Added first files for admin and login/signup in admin
256
paramecio2/libraries/db/corefields.py
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
from paramecio2.libraries.db.webmodel import PhangoField
|
||||
from paramecio2.libraries.db import coreforms
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
|
||||
class IntegerField(PhangoField):
|
||||
|
||||
"""Class that figure an integer sql type field.
|
||||
|
||||
Args:
|
||||
name (str): The name of new field
|
||||
size (int): The size of the new field in database. By default 11.
|
||||
required (bool): Boolean for define if
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name, size=11, required=False):
|
||||
super(IntegerField, self).__init__(name, size, required)
|
||||
self.default_value=0
|
||||
|
||||
def check(self, value):
|
||||
|
||||
"""Method for check if value is integer
|
||||
|
||||
Args:
|
||||
value (int): The value to check
|
||||
|
||||
"""
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
try:
|
||||
|
||||
value=str(int(value))
|
||||
|
||||
if value=="0" and self.required==True:
|
||||
self.txt_error="The value is zero"
|
||||
self.error=True
|
||||
except:
|
||||
|
||||
value="0"
|
||||
self.txt_error="The value is zero"
|
||||
self.error=True
|
||||
|
||||
return value
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'INT('+str(self.size)+') NOT NULL DEFAULT "0"'
|
||||
|
||||
class BigIntegerField(IntegerField):
|
||||
|
||||
"""Class that figure an big integer sql type field.
|
||||
|
||||
Only change the sql type with respect to IntegerField
|
||||
|
||||
"""
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'BIGINT('+str(self.size)+') NOT NULL DEFAULT "0"'
|
||||
|
||||
|
||||
class FloatField(PhangoField):
|
||||
|
||||
"""Class that figure an float sql type field.
|
||||
|
||||
Args:
|
||||
name (str): The name of new field
|
||||
size (int): The size of the new field in database. By default 11.
|
||||
required (bool): Boolean for define if
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name, size=11, required=False):
|
||||
super(FloatField, self).__init__(name, size, required)
|
||||
|
||||
self.error_default="The value is zero"
|
||||
self.default_value=0
|
||||
|
||||
def check(self, value):
|
||||
|
||||
"""Method for check if value is integer
|
||||
|
||||
Args:
|
||||
value (float): The value to check
|
||||
|
||||
"""
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
try:
|
||||
|
||||
value=str(value)
|
||||
|
||||
if value.find(',')!=-1:
|
||||
value=value.replace(',', '.')
|
||||
|
||||
value=str(float(value))
|
||||
|
||||
if value==0 and self.required==True:
|
||||
self.txt_error=self.error_default
|
||||
self.error=True
|
||||
except:
|
||||
|
||||
value="0"
|
||||
self.txt_error=self.error_default
|
||||
self.error=True
|
||||
|
||||
return value
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
return 'FLOAT NOT NULL DEFAULT "0"'
|
||||
|
||||
class DoubleField(FloatField):
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
return 'DOUBLE NOT NULL DEFAULT "0"'
|
||||
|
||||
class CharField(PhangoField):
|
||||
|
||||
pass
|
||||
|
||||
class TextField(PhangoField):
|
||||
|
||||
def __init__(self, name, required=False):
|
||||
super().__init__(name, 11, required)
|
||||
|
||||
self.set_default='NOT NULL'
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'TEXT '+self.set_default
|
||||
|
||||
class HTMLField(TextField):
|
||||
|
||||
def __init__(self, name, required=False):
|
||||
super().__init__(name, required)
|
||||
|
||||
def check(self, value):
|
||||
|
||||
return re.sub('<.*?script?>', '', value)
|
||||
|
||||
|
||||
class ForeignKeyField(IntegerField):
|
||||
|
||||
def __init__(self, name, related_table, size=11, required=False, identifier_field='id', named_field="id", select_fields=[]):
|
||||
|
||||
super(ForeignKeyField, self).__init__(name, size, required)
|
||||
|
||||
self.table_id=related_table.name_field_id
|
||||
|
||||
self.table_name=related_table.name
|
||||
|
||||
self.related_model=related_table
|
||||
|
||||
self.identifier_field=identifier_field
|
||||
|
||||
self.named_field=named_field
|
||||
|
||||
self.select_fields=select_fields
|
||||
|
||||
self.foreignkey=True
|
||||
|
||||
self.change_form(coreforms.SelectModelForm, [related_table, self.named_field, self.identifier_field])
|
||||
|
||||
self.default_value=None
|
||||
|
||||
def check(self, value):
|
||||
|
||||
value=super().check(value)
|
||||
|
||||
if value=='0' or value==0:
|
||||
value='NULL'
|
||||
|
||||
return value
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'INT NULL'
|
||||
|
||||
|
||||
class BooleanField(IntegerField):
|
||||
|
||||
def __init__(self, name, size=1):
|
||||
|
||||
required=False
|
||||
|
||||
self.yes_text=I18n.lang('common', 'yes', 'Yes')
|
||||
self.no_text=I18n.lang('common', 'no', 'No')
|
||||
|
||||
super(IntegerField, self).__init__(name, size, required)
|
||||
|
||||
self.default_error="Need 0 or 1 value"
|
||||
self.default_value=0
|
||||
|
||||
def check(self, value):
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
try:
|
||||
|
||||
value=int(value)
|
||||
|
||||
if value<0 or value>1:
|
||||
self.txt_error=self.default_error
|
||||
self.error=True
|
||||
|
||||
except:
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.default_error
|
||||
value=0
|
||||
|
||||
value=str(value)
|
||||
|
||||
return value
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'BOOLEAN NOT NULL DEFAULT "0"'
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
value=int(value)
|
||||
|
||||
if value==0:
|
||||
value=self.no_text
|
||||
else:
|
||||
value=self.yes_text
|
||||
|
||||
return str(value)
|
||||
193
paramecio2/libraries/db/coreforms.py
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from collections import OrderedDict
|
||||
from html import escape
|
||||
|
||||
#Forms para python3
|
||||
|
||||
class BaseForm:
|
||||
|
||||
def __init__(self, name, value):
|
||||
|
||||
self.label=name
|
||||
self.name=name
|
||||
self.default_value=value
|
||||
self.css=''
|
||||
self.type='text'
|
||||
self.field=None
|
||||
self.required=False
|
||||
self.txt_error=''
|
||||
self.name_field_id=self.name+'_form'
|
||||
self.help=''
|
||||
|
||||
def form(self):
|
||||
|
||||
return '<input type="'+self.type+'" class="'+self.css+'" name="'+self.name+'" id="'+self.name_field_id+'" value="'+self.setform(self.default_value)+'" />'
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return value
|
||||
|
||||
#Method for escape value for html input. DON'T CHANGE IF YOU DON'T KNOWN WHAT ARE YOU DOING
|
||||
|
||||
def setform(self, value):
|
||||
|
||||
value=str(value)
|
||||
|
||||
return value.replace('"', '"').replace("'", ''')
|
||||
|
||||
def change_name(self, new_name):
|
||||
|
||||
self.name=new_name
|
||||
|
||||
self.name_field_id=self.name+'_form'
|
||||
|
||||
return ""
|
||||
|
||||
class SimpleTextForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
|
||||
self.after_text=''
|
||||
|
||||
def form(self):
|
||||
|
||||
return super().form()+' '+self.after_text
|
||||
|
||||
class TextForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(TextForm, self).__init__(name, value)
|
||||
|
||||
def form(self):
|
||||
|
||||
return '<textarea class="'+self.css+'" name="'+self.name+'" id="'+self.name+'_form">'+self.setform(self.default_value)+'</textarea>'
|
||||
|
||||
class PasswordForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(PasswordForm, self).__init__(name, value)
|
||||
self.type='password'
|
||||
|
||||
def setform(self, value):
|
||||
return ""
|
||||
|
||||
class HiddenForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(HiddenForm, self).__init__(name, value)
|
||||
self.type='hidden'
|
||||
|
||||
|
||||
class SelectForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value, elements=OrderedDict()):
|
||||
super(SelectForm, self).__init__(name, value)
|
||||
self.arr_select=elements
|
||||
|
||||
def form(self):
|
||||
|
||||
the_form='<select name="'+self.name+'" id="'+self.name_field_id+'">\n'
|
||||
|
||||
arr_selected={self.default_value: 'selected'}
|
||||
|
||||
for k,v in self.arr_select.items():
|
||||
arr_selected[k]=arr_selected.get(k, '')
|
||||
|
||||
the_form+="<option value=\""+self.setform(str(k))+"\" "+arr_selected[k]+">"+self.setform(str(v))+"</option>"
|
||||
|
||||
the_form+='</select>\n'
|
||||
|
||||
return the_form
|
||||
|
||||
class SelectModelForm(SelectForm):
|
||||
|
||||
def __init__(self, name, value, model, field_name, field_value, field_parent=None):
|
||||
super(SelectModelForm, self).__init__(name, value)
|
||||
|
||||
try:
|
||||
self.default_value=int(self.default_value)
|
||||
except:
|
||||
self.default_value=0
|
||||
|
||||
self.arr_select=OrderedDict()
|
||||
self.model=model
|
||||
self.field_name=field_name
|
||||
self.field_value=field_value
|
||||
self.field_parent=field_parent
|
||||
|
||||
self.form=self.normal_form
|
||||
|
||||
if self.field_parent!=None:
|
||||
self.form=self.parent_form
|
||||
|
||||
|
||||
def normal_form(self):
|
||||
|
||||
self.arr_select['']=''
|
||||
|
||||
with self.model.select([self.field_name, self.field_value], True) as cur:
|
||||
for arr_value in cur:
|
||||
|
||||
self.arr_select[arr_value[self.field_value]]=self.model.fields[self.field_name].show_formatted(arr_value[self.field_name])
|
||||
|
||||
try:
|
||||
|
||||
self.default_value=int(self.default_value)
|
||||
|
||||
except:
|
||||
self.default_value=0
|
||||
|
||||
return super().form()
|
||||
|
||||
def parent_form(self):
|
||||
|
||||
self.arr_select['']=''
|
||||
|
||||
arr_son={}
|
||||
|
||||
old_conditions=self.model.conditions
|
||||
old_limit=self.model.limit
|
||||
|
||||
self.model.limit=''
|
||||
|
||||
self.model.set_conditions('WHERE 1=1', [])
|
||||
|
||||
|
||||
with self.model.select([self.field_name, self.field_value, self.field_parent], True) as cur:
|
||||
|
||||
for arr_value in cur:
|
||||
|
||||
if not arr_value[self.field_parent] in arr_son:
|
||||
|
||||
arr_son[arr_value[self.field_parent]]=[]
|
||||
|
||||
arr_son[arr_value[self.field_parent]].append([arr_value[self.field_value], arr_value[self.field_name]])
|
||||
|
||||
self.create_son(0, arr_son)
|
||||
|
||||
self.model.conditions=old_conditions
|
||||
self.model.limit=old_limit
|
||||
|
||||
try:
|
||||
|
||||
self.default_value=int(self.default_value)
|
||||
|
||||
except:
|
||||
self.default_value=0
|
||||
|
||||
return super().form()
|
||||
|
||||
|
||||
def create_son(self, parent_id, arr_son, separator=''):
|
||||
|
||||
if parent_id in arr_son:
|
||||
for son in arr_son[parent_id]:
|
||||
self.arr_select[son[0]]=separator+son[1]
|
||||
|
||||
son_separator=separator
|
||||
|
||||
if son[0] in arr_son:
|
||||
son_separator+='--'
|
||||
self.create_son(son[0],arr_son, son_separator)
|
||||
386
paramecio2/libraries/db/dbadmin.py
Normal file
|
|
@ -0,0 +1,386 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os,traceback
|
||||
import sys, inspect
|
||||
import shutil
|
||||
import re
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
from colorama import init, Fore, Back, Style
|
||||
from importlib import import_module, reload
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from settings import config
|
||||
|
||||
#from models import books
|
||||
|
||||
def start():
|
||||
|
||||
connection=WebModel.connection()
|
||||
|
||||
#connection.connect_to_db(WebModel.connections['default'])
|
||||
|
||||
parser = argparse.ArgumentParser(description='A tool for create tables in databases using models from Cromosoma')
|
||||
|
||||
parser.add_argument('--model', help='Model python path', required=True)
|
||||
|
||||
parser.add_argument('--config', help='The config file', required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
init()
|
||||
|
||||
#Import config
|
||||
|
||||
config_file='config'
|
||||
|
||||
if args.config!=None:
|
||||
config_file=args.config
|
||||
|
||||
try:
|
||||
|
||||
config=import_module('settings.'+config_file)
|
||||
|
||||
except:
|
||||
e = sys.exc_info()[0]
|
||||
v = sys.exc_info()[1]
|
||||
|
||||
print(Fore.WHITE+Back.RED+Style.BRIGHT+"Config file not found: %s %s" % (e, v))
|
||||
|
||||
exit(1)
|
||||
|
||||
#print(WebModel.connections)
|
||||
|
||||
if '/' in args.model:
|
||||
|
||||
args.model=args.model.replace('/', '.')[:-3] #.replace('.py', '')
|
||||
|
||||
try:
|
||||
|
||||
model=import_module(args.model)
|
||||
|
||||
for name, obj in inspect.getmembers(sys.modules[model.__name__]):
|
||||
if inspect.isclass(obj):
|
||||
if obj.__module__==args.model and hasattr(obj, 'webmodel'):
|
||||
|
||||
WebModel.model[name.lower()]=obj(connection)
|
||||
|
||||
|
||||
#WebModel.modelobj
|
||||
|
||||
except:
|
||||
"""
|
||||
e = sys.exc_info()[0]
|
||||
v = sys.exc_info()[1]
|
||||
|
||||
print(Fore.WHITE+Back.RED+Style.BRIGHT +"Error, file with model not found: %s %s" % (e, v))
|
||||
"""
|
||||
print("Exception in user code:")
|
||||
print("-"*60)
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
print("-"*60)
|
||||
|
||||
exit(1)
|
||||
|
||||
#load the table of databases
|
||||
|
||||
cursor=connection.query("show tables")
|
||||
|
||||
table_exists=[]
|
||||
|
||||
for row in cursor:
|
||||
table=list(row.values())[0]
|
||||
|
||||
if table in WebModel.model:
|
||||
table_exists.append(table)
|
||||
|
||||
#If don't want order
|
||||
#set([1,2,3,4]) - set([2,5])
|
||||
|
||||
tables=list(WebModel.model.keys())
|
||||
|
||||
#Array diff ordered
|
||||
|
||||
new_tables=[x for x in tables if x not in table_exists]
|
||||
|
||||
#If don't want order
|
||||
#new_tables=set(tables)-set(table_exists)
|
||||
|
||||
#Need order new_tables
|
||||
|
||||
changes=0
|
||||
|
||||
#Create new tables
|
||||
|
||||
if len(new_tables)>0:
|
||||
print(Style.BRIGHT+"Creating new tables...")
|
||||
|
||||
changes+=1
|
||||
|
||||
for table in new_tables:
|
||||
print(Style.NORMAL+"--Creating table "+table+"...")
|
||||
connection.query(WebModel.model[table].create_table())
|
||||
|
||||
for table in new_tables:
|
||||
|
||||
print("--Adding indexes and constraints for the new table "+table)
|
||||
|
||||
for k_field, index in WebModel.arr_sql_index[table].items():
|
||||
print("---Added index to "+k_field)
|
||||
connection.query(index)
|
||||
|
||||
for k_set, index_set in WebModel.arr_sql_set_index[table].items():
|
||||
|
||||
if index_set!="":
|
||||
connection.query(index_set)
|
||||
print("---Added constraint to "+k_set)
|
||||
|
||||
print("--Adding uniques elements for the new table")
|
||||
|
||||
#See if changes exists
|
||||
|
||||
#Check if created tables are modified.
|
||||
|
||||
try:
|
||||
|
||||
model_old=import_module('backups.'+args.model)
|
||||
|
||||
for name, obj in inspect.getmembers(sys.modules[model_old.__name__]):
|
||||
if inspect.isclass(obj):
|
||||
if obj.__module__=='backups.'+args.model and hasattr(obj, 'webmodel'):
|
||||
|
||||
WebModel.model['old_'+name.lower()]=obj(connection)
|
||||
|
||||
print(Style.BRIGHT+"Checking old versions of model for find changes...")
|
||||
|
||||
for table in tables:
|
||||
#connection.query("")
|
||||
#Check if new table
|
||||
|
||||
#fields_to_add, fields_to_modify, fields_to_add_index, fields_to_add_constraint, fields_to_add_unique, fields_to_delete_index, fields_to_delete_unique, fields_to_delete_constraint, fields_to_delete
|
||||
|
||||
fields_to_add=[]
|
||||
fields_to_modify=[]
|
||||
fields_to_add_index=[]
|
||||
fields_to_add_constraint=[]
|
||||
fields_to_add_unique=[]
|
||||
fields_to_delete_index=[]
|
||||
fields_to_delete_unique=[]
|
||||
fields_to_delete_constraint=[]
|
||||
fields_to_delete=[]
|
||||
|
||||
old_table='old_'+table
|
||||
|
||||
if not old_table in WebModel.model:
|
||||
WebModel.model[old_table]=WebModel.model[table]
|
||||
|
||||
for f, v in WebModel.model[table].fields.items():
|
||||
|
||||
if not f in WebModel.model[old_table].fields:
|
||||
|
||||
fields_to_add.append(f)
|
||||
|
||||
#Add index
|
||||
|
||||
if v.indexed==True:
|
||||
|
||||
fields_to_add_index.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
#Add unique
|
||||
|
||||
if v.unique==True:
|
||||
|
||||
fields_to_add_unique.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
#Add constraint
|
||||
|
||||
if v.foreignkey==True:
|
||||
|
||||
fields_to_add_constraint.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
changes+=1
|
||||
|
||||
#If exists field in old webmodel and new
|
||||
|
||||
else:
|
||||
|
||||
v_old=WebModel.model[old_table].fields[f]
|
||||
|
||||
if v.get_type_sql()!=v_old.get_type_sql():
|
||||
|
||||
fields_to_modify.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
#Add index
|
||||
|
||||
if v.indexed==True and v_old.indexed==False:
|
||||
|
||||
fields_to_add_index.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
if v.indexed==False and v_old.indexed==True:
|
||||
|
||||
fields_to_delete_index.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
#Add unique
|
||||
|
||||
if v.unique==True and v_old.unique==False:
|
||||
|
||||
fields_to_add_unique.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
if v.unique==False and v_old.unique==True:
|
||||
|
||||
fields_to_delete_unique.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
#Add constraint
|
||||
|
||||
if v.foreignkey==True and v_old.foreignkey==False:
|
||||
|
||||
fields_to_add_constraint.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
if v.foreignkey==False and v_old.foreignkey==True:
|
||||
|
||||
fields_to_delete_constraint.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
for f, v in WebModel.model[old_table].fields.items():
|
||||
|
||||
if not f in WebModel.model[table].fields:
|
||||
|
||||
#Add constraint
|
||||
|
||||
if v.foreignkey==True:
|
||||
|
||||
fields_to_delete_constraint.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
fields_to_delete.append(f)
|
||||
|
||||
changes+=1
|
||||
|
||||
WebModel.model[table].update_table(fields_to_add, fields_to_modify, fields_to_add_index, fields_to_add_constraint, fields_to_add_unique, fields_to_delete_index, fields_to_delete_unique, fields_to_delete_constraint, fields_to_delete)
|
||||
|
||||
#for field_update in arr_update:
|
||||
|
||||
|
||||
#Make a for in fields, if the field not exist in old model, create, if is not same type, recreate. If no have index now, delete index, if is a new index, create, same thing with uniques
|
||||
|
||||
#for field in WebModel.model
|
||||
|
||||
except ImportError:
|
||||
|
||||
pass
|
||||
|
||||
except:
|
||||
|
||||
print("Exception in user code:")
|
||||
print("-"*60)
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
print("-"*60)
|
||||
|
||||
exit(1)
|
||||
|
||||
original_file_path=args.model.replace('.', '/')+'.py'
|
||||
|
||||
backup_path='backups/'+original_file_path
|
||||
|
||||
if changes>0:
|
||||
print(Style.BRIGHT+"Creating backup of the model. WARNING: DON'T DELETE BACKUPS DIRECTORY IF YOU WANT MAKE CHANGES IN THE FUTURE WITHOUT MODIFY DIRECTLY THE DATABASE")
|
||||
|
||||
create_backup(original_file_path, backup_path)
|
||||
|
||||
else:
|
||||
if not os.path.isfile(backup_path):
|
||||
create_backup(original_file_path, backup_path)
|
||||
|
||||
# Execute script
|
||||
|
||||
arr_script_model=args.model.split('.')
|
||||
|
||||
arr_script_model.pop()
|
||||
|
||||
script_model='.'.join(arr_script_model)+'.scripts.install'
|
||||
|
||||
script_py=script_model.replace('.', '/')+'.py'
|
||||
|
||||
if os.path.isfile(script_py):
|
||||
|
||||
locked_file='/'.join(arr_script_model)+'/scripts/locked'
|
||||
|
||||
if not os.path.isfile(locked_file):
|
||||
|
||||
script_install=import_module(script_model)
|
||||
|
||||
script_install.run()
|
||||
|
||||
f=open(locked_file, 'w')
|
||||
|
||||
f.write('OK')
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
connection.close()
|
||||
|
||||
#script_model=args.model+''
|
||||
|
||||
print(Style.BRIGHT+"All tasks finished")
|
||||
|
||||
def create_backup(original_file_path, file_path):
|
||||
|
||||
#Create copy
|
||||
|
||||
path=os.path.dirname(file_path)
|
||||
|
||||
p=Path(path)
|
||||
|
||||
if not p.is_dir():
|
||||
p.mkdir(0o755, True)
|
||||
with open(path+'/__init__.py', 'w') as f:
|
||||
f.write("#!/usr/bin/env python3\n")
|
||||
|
||||
#Create path
|
||||
|
||||
if os.path.isfile(file_path):
|
||||
today = date.today()
|
||||
shutil.copy(file_path, file_path+'.'+today.strftime("%Y%M%d%H%M%S"))
|
||||
|
||||
new_file=""
|
||||
|
||||
f=open(original_file_path)
|
||||
|
||||
for line in f:
|
||||
"""
|
||||
new_line=line.replace("model[\"", "model[\"old_")
|
||||
new_line=new_line.replace("model['", "model['old_")
|
||||
|
||||
new_line=new_line.replace("WebModel(\"", "WebModel(\"old_")
|
||||
new_line=new_line.replace("WebModel('", "WebModel('old_")
|
||||
"""
|
||||
new_file+=line
|
||||
|
||||
f.close()
|
||||
|
||||
f=open(file_path, 'w')
|
||||
|
||||
f.write(new_file)
|
||||
|
||||
f.close()
|
||||
0
paramecio2/libraries/db/extrafields/__init__.py
Normal file
59
paramecio2/libraries/db/extrafields/arrayfield.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
from paramecio2.libraries.db.webmodel import PhangoField,WebModel
|
||||
import json
|
||||
|
||||
class ArrayField(PhangoField):
|
||||
|
||||
def __init__(self, name, field_type, required=False):
|
||||
|
||||
super().__init__(name, required)
|
||||
|
||||
self.field_type=field_type
|
||||
|
||||
self.error_default='Sorry, the json array is invalid'
|
||||
|
||||
self.set_default='NOT NULL'
|
||||
|
||||
def check(self, value):
|
||||
|
||||
if type(value).__name__=='str':
|
||||
try:
|
||||
value=json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
|
||||
value=[]
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
|
||||
elif type(value).__name__!='list':
|
||||
|
||||
value=[]
|
||||
self.error=True
|
||||
self.txt_error='Sorry, the json array is invalid'
|
||||
|
||||
if type(self.field_type).__name__!='ArrayField':
|
||||
for k,v in enumerate(value):
|
||||
|
||||
value[k]=self.field_type.check(v)
|
||||
|
||||
final_value=json.dumps(value)
|
||||
|
||||
final_value=WebModel.escape_sql(final_value)
|
||||
|
||||
return final_value
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
return 'TEXT '+self.set_default
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return ", ".join(value)
|
||||
|
||||
def loads(self, value):
|
||||
|
||||
try:
|
||||
|
||||
return json.loads(value)
|
||||
except:
|
||||
|
||||
return False
|
||||
47
paramecio2/libraries/db/extrafields/colorfield.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
from paramecio2.libraries.db.corefields import IntegerField
|
||||
from paramecio2.libraries.db.extraforms.colorform import ColorForm
|
||||
|
||||
class ColorField(IntegerField):
|
||||
|
||||
def __init__(self, name, size=11, required=False):
|
||||
super().__init__(name, size, required)
|
||||
|
||||
self.name_form=ColorForm
|
||||
|
||||
def check(self, value):
|
||||
|
||||
value=str(value).replace('#', '0x')
|
||||
|
||||
value=int(value, 16)
|
||||
|
||||
if value<0 or value>0xffffff:
|
||||
value=0
|
||||
|
||||
return value
|
||||
def get_hex_color(self, value):
|
||||
|
||||
value=str(hex(int(value))).replace('0x', '')
|
||||
|
||||
c=len(value)
|
||||
|
||||
if(c<6):
|
||||
repeat=6-c
|
||||
value=('0'*repeat)+value
|
||||
|
||||
value='#'+value
|
||||
|
||||
return value
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
value=str(hex(int(value))).replace('0x', '')
|
||||
|
||||
c=len(value)
|
||||
|
||||
if(c<6):
|
||||
repeat=6-c
|
||||
value=('0'*repeat)+value
|
||||
|
||||
value='#'+value
|
||||
|
||||
return '<div style="width:50px;height:50px;background-color:%s;"></div>' % value;
|
||||
39
paramecio2/libraries/db/extrafields/datefield.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from paramecio2.libraries.db.corefields import PhangoField
|
||||
from paramecio.citoplasma import datetime
|
||||
from paramecio2.libraries.db.extraforms.dateform import DateForm
|
||||
|
||||
class DateField(PhangoField):
|
||||
|
||||
def __init__(self, name, size=255, required=False):
|
||||
|
||||
super().__init__(name, size, required)
|
||||
|
||||
self.name_form=DateForm
|
||||
|
||||
self.utc=True
|
||||
|
||||
self.error_default='Error: Date format invalid'
|
||||
|
||||
def check(self, value):
|
||||
|
||||
if self.utc:
|
||||
|
||||
value=datetime.local_to_gmt(value)
|
||||
|
||||
elif not datetime.obtain_timestamp(value, False):
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
return ''
|
||||
|
||||
if value==False:
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
return ''
|
||||
|
||||
return value
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return datetime.format_date(value)
|
||||
60
paramecio2/libraries/db/extrafields/datetimefield.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
from paramecio2.libraries.db.corefields import PhangoField
|
||||
from paramecio.citoplasma import datetime
|
||||
from paramecio2.libraries.db.extraforms.dateform import DateForm
|
||||
|
||||
class DateTimeField(PhangoField):
|
||||
|
||||
def __init__(self, name, size=255, required=False):
|
||||
|
||||
super().__init__(name, size, required)
|
||||
|
||||
self.name_form=DateForm
|
||||
|
||||
self.utc=False
|
||||
|
||||
self.error_default='Error: Date format invalid'
|
||||
|
||||
def check(self, value):
|
||||
|
||||
if self.utc:
|
||||
|
||||
value=datetime.local_to_gmt(value)
|
||||
|
||||
elif not datetime.obtain_timestamp(value, False):
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
return ''
|
||||
|
||||
if value==False:
|
||||
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
return ''
|
||||
else:
|
||||
|
||||
"""
|
||||
format_date_txt="YYYY/MM/DD"
|
||||
|
||||
format_time_txt="HH:mm:ss"
|
||||
"""
|
||||
|
||||
value=datetime.format_local_strtime('YYYY-MM-DD HH:mm:ss', value)
|
||||
|
||||
return value
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
# Convert to paramecio value
|
||||
value=str(value)
|
||||
value=value.replace('-', '').replace(':', '').replace(' ', '')
|
||||
|
||||
return datetime.format_date(value)
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
"""Method for return the sql code for this type
|
||||
|
||||
"""
|
||||
|
||||
return 'DATETIME NOT NULL'
|
||||
50
paramecio2/libraries/db/extrafields/dictfield.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
from paramecio2.libraries.db.webmodel import WebModel, PhangoField
|
||||
import json
|
||||
|
||||
class DictField(PhangoField):
|
||||
|
||||
def __init__(self, name, field_type, required=False):
|
||||
|
||||
super().__init__(name, required)
|
||||
|
||||
self.field_type=field_type
|
||||
|
||||
self.error_default='Sorry, the json dict is invalid'
|
||||
|
||||
self.set_default='NOT NULL'
|
||||
|
||||
def check(self, value):
|
||||
|
||||
if type(value).__name__=='str':
|
||||
try:
|
||||
value=json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
|
||||
value={}
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
|
||||
elif type(value).__name__!='dict':
|
||||
|
||||
value={}
|
||||
self.error=True
|
||||
self.txt_error=self.error_default
|
||||
|
||||
for k,v in value.items():
|
||||
|
||||
value[k]=self.field_type.check(v)
|
||||
|
||||
final_value=json.dumps(value)
|
||||
|
||||
#final_value=WebModel.escape_sql(final_value)
|
||||
|
||||
return final_value
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
return 'TEXT '+self.set_default
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return ", ".join(value)
|
||||
|
||||
27
paramecio2/libraries/db/extrafields/emailfield.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
from paramecio2.libraries.db.corefields import CharField
|
||||
import re
|
||||
|
||||
mail_pattern=re.compile("\w[\w\.-]*@\w[\w\.-]+\.\w+")
|
||||
|
||||
class EmailField(CharField):
|
||||
|
||||
def __init__(self, name, size=1024, required=False):
|
||||
|
||||
super().__init__(name, size, required)
|
||||
|
||||
self.error_default='Error: No valid format'
|
||||
|
||||
def check(self, value):
|
||||
|
||||
value=super().check(value)
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
if not mail_pattern.match(value):
|
||||
|
||||
self.error=True
|
||||
value=""
|
||||
self.txt_error=self.error_default
|
||||
|
||||
return value
|
||||
176
paramecio2/libraries/db/extrafields/filefield.py
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from paramecio2.libraries.db.corefields import CharField
|
||||
from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
from paramecio.citoplasma import httputils
|
||||
from paramecio.citoplasma.keyutils import create_key
|
||||
import traceback
|
||||
|
||||
from bottle import request
|
||||
|
||||
|
||||
from uuid import uuid4
|
||||
#from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
|
||||
class FileField(CharField):
|
||||
|
||||
def __init__(self, name, save_folder='media/upload/files', sizes=None, module=None, size=255, required=False):
|
||||
|
||||
super().__init__(name, size, required)
|
||||
|
||||
self.yes_prefix=True
|
||||
|
||||
self.suffix=''
|
||||
|
||||
# Is relative to media folder of paramecio
|
||||
|
||||
#if module!=None:
|
||||
|
||||
self.save_folder=save_folder
|
||||
|
||||
self.file_related=True
|
||||
|
||||
self.sizes=sizes
|
||||
|
||||
self.name_form=FileForm
|
||||
self.extra_parameters=[self.save_folder]
|
||||
|
||||
|
||||
def change_folder(self, folder):
|
||||
|
||||
pass
|
||||
|
||||
def check(self, value):
|
||||
|
||||
files_uploaded=request.files
|
||||
|
||||
field_file=self.name+'_file'
|
||||
|
||||
#if not change
|
||||
|
||||
if not field_file in files_uploaded:
|
||||
|
||||
if value=='':
|
||||
|
||||
if self.model:
|
||||
|
||||
if self.model.updated:
|
||||
|
||||
old_reset=self.model.yes_reset_conditions
|
||||
|
||||
self.model.yes_reset_conditions=False
|
||||
|
||||
with self.model.select([self.name]) as cur:
|
||||
|
||||
for arr_image in cur:
|
||||
|
||||
if arr_image[self.name]!='':
|
||||
try:
|
||||
os.remove(arr_image[self.name])
|
||||
except:
|
||||
pass
|
||||
|
||||
#if arr_image[self.name]!=save_file and arr_image[self.name]!='':
|
||||
|
||||
#value=arr_image[self.name]
|
||||
|
||||
self.model.yes_reset_conditions=old_reset
|
||||
self.txt_error='Field is empty'
|
||||
self.error=True
|
||||
|
||||
return ''
|
||||
|
||||
else:
|
||||
|
||||
value=os.path.basename(value)
|
||||
|
||||
return self.save_folder+'/'+value
|
||||
|
||||
|
||||
# Load image file
|
||||
|
||||
file_bytecode=files_uploaded[field_file].file
|
||||
|
||||
filename=files_uploaded[field_file].filename
|
||||
|
||||
realfilename, ext = os.path.splitext(filename)
|
||||
|
||||
prefix=''
|
||||
|
||||
if self.yes_prefix==True:
|
||||
#prefix=uuid4().hex+'_'
|
||||
prefix=create_key(5).replace('/', '-').replace('#', '-')+self.suffix+'_'
|
||||
|
||||
filename=prefix+filename
|
||||
|
||||
save_file=self.save_folder+'/'+filename
|
||||
|
||||
# Save file
|
||||
|
||||
try:
|
||||
|
||||
#Check if directory exists
|
||||
|
||||
if not os.path.isdir(self.save_folder):
|
||||
|
||||
# Try create if not
|
||||
|
||||
try:
|
||||
|
||||
p=Path(self.save_folder)
|
||||
|
||||
p.mkdir(mode=0o755, parents=True)
|
||||
|
||||
except:
|
||||
self.error=True
|
||||
|
||||
self.txt_error='Error: cannot create the directory where save the image.Check permissions,'
|
||||
return ""
|
||||
|
||||
#files_uploaded[field_file].save(self.save_folder, overwrite=True)
|
||||
|
||||
if os.path.isfile(save_file):
|
||||
|
||||
os.remove(save_file)
|
||||
|
||||
# Delete old files
|
||||
|
||||
if self.model!=None:
|
||||
|
||||
if self.model.updated:
|
||||
|
||||
#old_conditions=self.model.conditions
|
||||
|
||||
old_reset=self.model.yes_reset_conditions
|
||||
|
||||
self.model.yes_reset_conditions=False
|
||||
|
||||
with self.model.select([self.name]) as cur:
|
||||
|
||||
for arr_file in cur:
|
||||
|
||||
if arr_file[self.name]!=save_file and arr_file[self.name]!='':
|
||||
|
||||
if os.path.isfile(arr_file[self.name]):
|
||||
|
||||
os.remove(arr_file[self.name])
|
||||
|
||||
self.model.yes_reset_conditions=old_reset
|
||||
|
||||
|
||||
#self.model.conditions=old_conditions
|
||||
|
||||
return save_file
|
||||
|
||||
except:
|
||||
|
||||
self.error=True
|
||||
self.txt_error='Error: cannot save the image file, Exists directory for save the file? '+traceback.format_exc()
|
||||
print(traceback.format_exc())
|
||||
return ""
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return os.path.basename(value)
|
||||
|
||||
157
paramecio2/libraries/db/extrafields/i18nfield.py
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
from paramecio2.libraries.db.webmodel import PhangoField
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.db.extraforms.i18nform import I18nForm
|
||||
from paramecio.citoplasma.i18n import I18n
|
||||
from paramecio.citoplasma.httputils import GetPostFiles
|
||||
import json
|
||||
import re
|
||||
|
||||
class I18nField(PhangoField):
|
||||
|
||||
def __init__(self, name, form=None):
|
||||
|
||||
super().__init__(name)
|
||||
|
||||
if form==None:
|
||||
form=BaseForm(name, '')
|
||||
|
||||
self.name_form=I18nForm
|
||||
self.extra_parameters=[form]
|
||||
self.show_formatted_value=True
|
||||
self.show_blank=False
|
||||
|
||||
arr_i18n={i:'' for i in I18n.dict_i18n}
|
||||
self.default_value=json.dumps(arr_i18n)
|
||||
|
||||
def change_form(self, form):
|
||||
self.extra_parameters=[form]
|
||||
|
||||
def check_value(self, value):
|
||||
|
||||
return super().check(value)
|
||||
|
||||
def check(self, value):
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
arr_values={}
|
||||
|
||||
try:
|
||||
arr_values=json.loads(value)
|
||||
|
||||
if not arr_values:
|
||||
arr_values={}
|
||||
|
||||
except:
|
||||
arr_values={}
|
||||
|
||||
arr_real_values={}
|
||||
|
||||
error_values=0
|
||||
|
||||
for lang in I18n.dict_i18n:
|
||||
arr_real_values[lang]=arr_values.get(lang, '')
|
||||
arr_real_values[lang]=self.check_value(arr_real_values[lang])
|
||||
|
||||
|
||||
if not arr_real_values[lang] or arr_real_values[lang]=='None':
|
||||
arr_real_values[lang]=''
|
||||
error_values+=1
|
||||
|
||||
self.error=False
|
||||
|
||||
arr_values=arr_real_values
|
||||
|
||||
if error_values:
|
||||
if error_values==len(arr_values):
|
||||
self.error=True
|
||||
self.txt_error='Sorry, You field language is empty'
|
||||
return json.dumps(arr_values)
|
||||
|
||||
|
||||
"""
|
||||
if arr_values[I18n.default_lang]=='':
|
||||
self.error=True
|
||||
self.txt_error='Sorry, You need default language '+I18n.default_lang
|
||||
return json.dumps(arr_values)
|
||||
"""
|
||||
|
||||
return json.dumps(arr_values)
|
||||
|
||||
def get_type_sql(self):
|
||||
|
||||
return 'TEXT NOT NULL'
|
||||
|
||||
def obtain_lang_value(self, lang, value):
|
||||
|
||||
return value.get(self.name+'_'+lang, '')
|
||||
|
||||
def obtain_lang_from_post(self, lang, value):
|
||||
|
||||
#getpost=GetPostFiles()
|
||||
|
||||
#getpost.obtain_post()
|
||||
|
||||
return "" #GetPostFiles.post.get(self.name+'_'+lang, '')
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
if value=='':
|
||||
value='{"en-US": "", "es-ES": ""}'
|
||||
|
||||
value=json.loads(value)
|
||||
|
||||
lang=I18n.get_default_lang()
|
||||
|
||||
if value[lang]!='' or self.show_blank:
|
||||
|
||||
return value[lang]
|
||||
|
||||
lang_value=value[I18n.default_lang]
|
||||
|
||||
if value[I18n.default_lang]=='':
|
||||
for l in value:
|
||||
|
||||
if value[l]!='':
|
||||
lang_value=value[l]
|
||||
break
|
||||
|
||||
return lang_value
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_value(value):
|
||||
|
||||
value=json.loads(value)
|
||||
|
||||
lang=I18n.get_default_lang()
|
||||
|
||||
if value[lang]!='':
|
||||
|
||||
return value[lang]
|
||||
|
||||
return value[I18n.default_lang]
|
||||
|
||||
class I18nHTMLField(I18nField):
|
||||
|
||||
def check_value(self, value):
|
||||
|
||||
return re.sub('<.*?script?>', '', value)
|
||||
|
||||
class I18nPhangoField(I18nField):
|
||||
|
||||
def __init__(self, name, field_class, form=None):
|
||||
|
||||
super().__init__(name, form)
|
||||
|
||||
self.field_class=field_class
|
||||
|
||||
def check_value(self, value):
|
||||
|
||||
f=self.field_class
|
||||
|
||||
return f.check(value)
|
||||
276
paramecio2/libraries/db/extrafields/imagefield.py
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from paramecio2.libraries.db.corefields import CharField
|
||||
from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
from paramecio.citoplasma import httputils
|
||||
from paramecio.citoplasma.keyutils import create_key
|
||||
import traceback
|
||||
|
||||
from bottle import request
|
||||
try:
|
||||
from PIL import Image
|
||||
except:
|
||||
print("Unexpected error:", sys.exc_info()[0])
|
||||
raise
|
||||
|
||||
|
||||
from uuid import uuid4
|
||||
#from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
|
||||
class ImageField(CharField):
|
||||
|
||||
def __init__(self, name, save_folder='media/upload/images', sizes=None, module=None, size=255, required=False):
|
||||
|
||||
super().__init__(name, size, required)
|
||||
|
||||
self.yes_prefix=True
|
||||
|
||||
#self.name_form=FileForm
|
||||
|
||||
self.thumbnail={'mini_': 150}
|
||||
|
||||
self.yes_thumbnail=False
|
||||
|
||||
self.default_quality_thumb=95
|
||||
|
||||
self.suffix=''
|
||||
|
||||
# Is relative to media folder of paramecio
|
||||
|
||||
#if module!=None:
|
||||
|
||||
self.save_folder=save_folder
|
||||
|
||||
self.file_related=True
|
||||
|
||||
self.sizes=sizes
|
||||
|
||||
self.name_form=FileForm
|
||||
self.extra_parameters=[self.save_folder]
|
||||
|
||||
|
||||
def change_folder(self, folder):
|
||||
|
||||
pass
|
||||
|
||||
def check(self, value):
|
||||
|
||||
files_uploaded=request.files
|
||||
|
||||
field_file=self.name+'_file'
|
||||
|
||||
#if not change
|
||||
|
||||
if not field_file in files_uploaded:
|
||||
|
||||
if value=='':
|
||||
|
||||
if self.model:
|
||||
|
||||
if self.model.updated:
|
||||
|
||||
old_reset=self.model.yes_reset_conditions
|
||||
|
||||
self.model.yes_reset_conditions=False
|
||||
|
||||
with self.model.select([self.name]) as cur:
|
||||
|
||||
for arr_image in cur:
|
||||
|
||||
if arr_image[self.name]!='':
|
||||
try:
|
||||
os.remove(arr_image[self.name])
|
||||
except:
|
||||
pass
|
||||
|
||||
#if arr_image[self.name]!=save_file and arr_image[self.name]!='':
|
||||
|
||||
#value=arr_image[self.name]
|
||||
|
||||
self.model.yes_reset_conditions=old_reset
|
||||
self.txt_error='Field is empty'
|
||||
self.error=True
|
||||
|
||||
return ''
|
||||
|
||||
else:
|
||||
|
||||
value=os.path.basename(value)
|
||||
|
||||
return self.save_folder+'/'+value
|
||||
|
||||
|
||||
# Load image file
|
||||
|
||||
file_bytecode=files_uploaded[field_file].file
|
||||
|
||||
filename=files_uploaded[field_file].filename
|
||||
|
||||
try:
|
||||
|
||||
im=Image.open(file_bytecode)
|
||||
|
||||
except IOError:
|
||||
|
||||
self.error=True
|
||||
|
||||
self.txt_error='Error, file not have a valid format'
|
||||
return ""
|
||||
|
||||
real_width=im.size[0]
|
||||
real_height=im.size[1]
|
||||
|
||||
if self.sizes:
|
||||
|
||||
if 'maximum' in self.sizes:
|
||||
if self.sizes['maximum'][0]<real_width or self.sizes['maximum'][1]<real_height:
|
||||
self.error=True
|
||||
self.txt_error='Wrong size. Maximum size is '+str(self.sizes['maximum'][0])+'x'+str(self.sizes['maximum'][1])
|
||||
im.close()
|
||||
return ""
|
||||
|
||||
if 'minimum' in self.sizes:
|
||||
if self.sizes['minimum'][0]>real_width or self.sizes['minimum'][1]>real_height:
|
||||
|
||||
self.error=True
|
||||
self.txt_error='Wrong size. Minimum size is '+str(self.sizes['minimum'][0])+'x'+str(self.sizes['minimum'][1])
|
||||
im.close()
|
||||
return ""
|
||||
|
||||
if 'resize' in self.sizes:
|
||||
|
||||
height_t=0
|
||||
width_t=0
|
||||
|
||||
if real_height<=self.sizes['resize'][1]:
|
||||
height_t=self.sizes['resize'][1]
|
||||
|
||||
if real_width>self.sizes['resize'][0]:
|
||||
|
||||
width_t=self.sizes['resize'][0]
|
||||
|
||||
if height_t==0:
|
||||
ratio=(real_width/width_t)
|
||||
height_t=round(real_height/ratio)
|
||||
|
||||
size=(width_t, height_t)
|
||||
|
||||
if width_t>0 and height_t>0:
|
||||
im.thumbnail(size, 3)
|
||||
|
||||
format_image=im.format
|
||||
|
||||
if format_image!='JPEG' and format_image!='GIF' and format_image!='PNG':
|
||||
|
||||
self.error=True
|
||||
self.txt_error='Format is wrong. Requires JPEG or PNG formats'
|
||||
im.close()
|
||||
return ""
|
||||
|
||||
# Create thumbnails and move file
|
||||
|
||||
realfilename, ext = os.path.splitext(filename)
|
||||
|
||||
prefix=''
|
||||
|
||||
if self.yes_prefix==True:
|
||||
#prefix=uuid4().hex+'_'
|
||||
prefix=create_key(5).replace('/', '-').replace('#', '-')+self.suffix+'_'
|
||||
|
||||
filename=prefix+filename
|
||||
|
||||
save_file=self.save_folder+'/'+filename
|
||||
|
||||
if self.yes_thumbnail:
|
||||
|
||||
for name, width_t in self.thumbnail.items():
|
||||
|
||||
im_thumb=im.copy()
|
||||
|
||||
ratio=(real_width/width_t)
|
||||
height_t=round(real_height/ratio)
|
||||
|
||||
size=(width_t, height_t)
|
||||
|
||||
save_file_thumb=self.save_folder+'/'+name+filename
|
||||
|
||||
im_thumb.thumbnail(size, Image.ANTIALIAS)
|
||||
im_thumb.save(save_file_thumb, "JPEG", quality=self.default_quality_thumb)
|
||||
|
||||
im_thumb.close()
|
||||
|
||||
# Save file
|
||||
|
||||
try:
|
||||
|
||||
#Check if directory exists
|
||||
|
||||
if not os.path.isdir(self.save_folder):
|
||||
|
||||
# Try create if not
|
||||
|
||||
try:
|
||||
|
||||
p=Path(self.save_folder)
|
||||
|
||||
p.mkdir(mode=0o755, parents=True)
|
||||
|
||||
except:
|
||||
im.close()
|
||||
self.error=True
|
||||
|
||||
self.txt_error='Error: cannot create the directory where save the image.Check permissions,'
|
||||
return ""
|
||||
|
||||
#files_uploaded[field_file].save(self.save_folder, overwrite=True)
|
||||
|
||||
if os.path.isfile(save_file):
|
||||
|
||||
os.remove(save_file)
|
||||
|
||||
im.save(save_file)
|
||||
|
||||
# Delete old files
|
||||
|
||||
if self.model!=None:
|
||||
|
||||
if self.model.updated:
|
||||
|
||||
#old_conditions=self.model.conditions
|
||||
|
||||
old_reset=self.model.yes_reset_conditions
|
||||
|
||||
self.model.yes_reset_conditions=False
|
||||
|
||||
with self.model.select([self.name]) as cur:
|
||||
|
||||
for arr_image in cur:
|
||||
|
||||
if arr_image[self.name]!=save_file and arr_image[self.name]!='':
|
||||
|
||||
if os.path.isfile(arr_image[self.name]):
|
||||
|
||||
os.remove(arr_image[self.name])
|
||||
|
||||
self.model.yes_reset_conditions=old_reset
|
||||
|
||||
|
||||
#self.model.conditions=old_conditions
|
||||
|
||||
im.close()
|
||||
|
||||
return save_file
|
||||
|
||||
except:
|
||||
|
||||
im.close()
|
||||
self.error=True
|
||||
self.txt_error='Error: cannot save the image file, Exists directory for save the file? '+traceback.format_exc()
|
||||
print(traceback.format_exc())
|
||||
return ""
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return os.path.basename(value)
|
||||
|
||||
19
paramecio2/libraries/db/extrafields/ipfield.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from paramecio2.libraries.db.corefields import CharField
|
||||
import ipaddress
|
||||
|
||||
class IpField(CharField):
|
||||
|
||||
def check(self, value):
|
||||
|
||||
try:
|
||||
|
||||
value=str(ipaddress.ip_address(value))
|
||||
|
||||
except:
|
||||
|
||||
self.error=True
|
||||
self.txt_error='No Valid IP'
|
||||
value=""
|
||||
|
||||
|
||||
return value
|
||||
27
paramecio2/libraries/db/extrafields/langfield.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.corefields import CharField
|
||||
from paramecio2.libraries.db import coreforms
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
|
||||
class LangField(CharField):
|
||||
|
||||
def __init__(self, name, size=255, required=False):
|
||||
|
||||
super(CharField, self).__init__(name, size, required)
|
||||
|
||||
select_lang={}
|
||||
|
||||
for lang in I18n.dict_i18n:
|
||||
select_lang[lang]=lang
|
||||
|
||||
self.change_form(coreforms.SelectForm, [select_lang])
|
||||
self.default_value=I18n.default_lang
|
||||
|
||||
def check(self, value):
|
||||
|
||||
if value not in I18n.dict_i18n:
|
||||
|
||||
value=I18n.default_lang
|
||||
|
||||
return value
|
||||
26
paramecio2/libraries/db/extrafields/moneyfield.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
from paramecio2.libraries.db.corefields import FloatField
|
||||
from decimal import Decimal, getcontext
|
||||
from locale import format_string
|
||||
|
||||
getcontext().prec=2
|
||||
|
||||
class MoneyField(FloatField):
|
||||
|
||||
def __init__(self, name, required=False):
|
||||
|
||||
super().__init__(name, 11, required)
|
||||
|
||||
def check(self, value):
|
||||
|
||||
value=Decimal(value)
|
||||
|
||||
return value
|
||||
|
||||
def show_formatted(self, value):
|
||||
|
||||
return format_string('%.2f', Decimal(value), grouping=True)
|
||||
|
||||
@staticmethod
|
||||
def format_money(value):
|
||||
return format_string('%.2f', Decimal(value), grouping=True)
|
||||
|
||||
42
paramecio2/libraries/db/extrafields/parentfield.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
#from paramecio2.libraries.db.webmodel import PhangoField
|
||||
from paramecio2.libraries.db.corefields import IntegerField
|
||||
from paramecio2.libraries.db.coreforms import SelectModelForm
|
||||
from paramecio.citoplasma.httputils import GetPostFiles
|
||||
|
||||
class ParentField(IntegerField):
|
||||
|
||||
def __init__(self, name, size=11, required=False, field_name='name'):
|
||||
|
||||
super().__init__(name, size, required)
|
||||
|
||||
#self.foreignkey=True
|
||||
self.indexed=True
|
||||
self.field_name=field_name
|
||||
|
||||
def post_register(self):
|
||||
|
||||
if self.model!=None:
|
||||
self.change_form(SelectModelForm, [self.model, self.field_name, self.model.name_field_id, self.name])
|
||||
|
||||
def check(self, value):
|
||||
|
||||
value=super().check(value)
|
||||
|
||||
if self.model!=None:
|
||||
if self.model.updated==True:
|
||||
if self.model.name_field_id in self.model.post:
|
||||
GetPostFiles.obtain_get()
|
||||
|
||||
model_id=GetPostFiles.get.get(self.model.name_field_id, '0')
|
||||
|
||||
if model_id==value:
|
||||
self.error=True
|
||||
self.txt_error='A field cannot be its own father'
|
||||
self.required=True
|
||||
value=0
|
||||
return value
|
||||
|
||||
|
||||
return value
|
||||
119
paramecio2/libraries/db/extrafields/passwordfield.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
from paramecio2.libraries.db.corefields import PhangoField
|
||||
from paramecio2.libraries.db.coreforms import PasswordForm
|
||||
from hmac import compare_digest as compare_hash
|
||||
import crypt
|
||||
|
||||
class PasswordField(PhangoField):
|
||||
|
||||
def __init__(self, name, size=1024, required=False):
|
||||
|
||||
super(PasswordField, self).__init__(name, size, required)
|
||||
self.protected=True
|
||||
self.name_form=PasswordForm
|
||||
self.default_value=''
|
||||
self.encrypt_password=True
|
||||
|
||||
def check(self, value):
|
||||
|
||||
self.txt_error=''
|
||||
self.error=False
|
||||
|
||||
value.strip()
|
||||
|
||||
if value=='':
|
||||
|
||||
if self.model!=None:
|
||||
|
||||
if self.model.updated==True:
|
||||
self.required=False
|
||||
self.check_blank=True
|
||||
return ""
|
||||
else:
|
||||
|
||||
self.txt_error=self.error_default
|
||||
self.error=True
|
||||
|
||||
else:
|
||||
self.txt_error=self.error_default
|
||||
self.error=True
|
||||
|
||||
else:
|
||||
|
||||
#if crypt.METHOD_SHA512 in crypt.methods:
|
||||
|
||||
#salt=crypt.mksalt(crypt.METHOD_SHA512)
|
||||
if self.encrypt_password:
|
||||
value=crypt.crypt(value)
|
||||
|
||||
"""
|
||||
else:
|
||||
|
||||
self.txt_error="You need the SHA512 method"
|
||||
self.error=True
|
||||
return ""
|
||||
"""
|
||||
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def verify( password, h):
|
||||
#return bcrypt_sha256.verify(password, h)
|
||||
return compare_hash(h, crypt.crypt(password, h))
|
||||
|
||||
# Old function bcrypt
|
||||
|
||||
"""
|
||||
try:
|
||||
|
||||
from passlib.hash import bcrypt
|
||||
from passlib.hash import bcrypt_sha256
|
||||
|
||||
class PasswordField(PhangoField):
|
||||
|
||||
def __init__(self, name, size=1024, required=False):
|
||||
|
||||
super(PasswordField, self).__init__(name, size, required)
|
||||
self.protected=True
|
||||
self.name_form=PasswordForm
|
||||
self.default_value=''
|
||||
|
||||
def check(self, value):
|
||||
|
||||
self.txt_error=''
|
||||
self.error=False
|
||||
|
||||
value.strip()
|
||||
|
||||
if value=='':
|
||||
|
||||
if self.model!=None:
|
||||
|
||||
if self.model.updated==True:
|
||||
self.required=False
|
||||
self.check_blank=True
|
||||
return ""
|
||||
else:
|
||||
|
||||
self.txt_error="The field is empty"
|
||||
self.error=True
|
||||
|
||||
else:
|
||||
self.txt_error="The field is empty"
|
||||
self.error=True
|
||||
|
||||
else:
|
||||
|
||||
#if crypt.METHOD_SHA512 in crypt.methods:
|
||||
|
||||
#value = bcrypt_sha256.encrypt(value)
|
||||
value = bcrypt_sha256.hash(value)
|
||||
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def verify( password, h):
|
||||
|
||||
return bcrypt_sha256.verify(password, h)
|
||||
|
||||
except:
|
||||
"""
|
||||
22
paramecio2/libraries/db/extrafields/percentfield.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
from paramecio2.libraries.db.corefields import IntegerField
|
||||
|
||||
class PercentField(IntegerField):
|
||||
|
||||
def __init__(self, name, required=False):
|
||||
|
||||
super().__init__(name, 2, required)
|
||||
|
||||
def check(self, value):
|
||||
|
||||
try:
|
||||
value=int(value)
|
||||
|
||||
if value<0:
|
||||
value=0
|
||||
if value>100:
|
||||
value=100
|
||||
|
||||
except:
|
||||
value=0
|
||||
|
||||
return value
|
||||
37
paramecio2/libraries/db/extrafields/slugifyfield.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.corefields import CharField
|
||||
from paramecio.citoplasma.slugify import slugify
|
||||
from paramecio2.libraries.db.coreforms import HiddenForm
|
||||
|
||||
class SlugifyField(CharField):
|
||||
|
||||
def __init__(self, name, size=255, field_related=None, required=False):
|
||||
|
||||
super(SlugifyField, self).__init__(name, size, required)
|
||||
|
||||
self.name_form=HiddenForm
|
||||
|
||||
self.field_related=field_related
|
||||
|
||||
def check(self, value):
|
||||
|
||||
value=slugify(value)
|
||||
|
||||
if value=='':
|
||||
|
||||
if self.model!=None and self.field_related!=None:
|
||||
|
||||
self.model.post[self.field_related]=self.model.post.get(self.field_related, '')
|
||||
|
||||
value=slugify(self.model.post[self.field_related])
|
||||
|
||||
if value=='':
|
||||
|
||||
self.error=True
|
||||
self.error_txt='Value is empty'
|
||||
|
||||
return ''
|
||||
return value
|
||||
|
||||
|
||||
42
paramecio2/libraries/db/extrafields/urlfield.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
from paramecio2.libraries.db.corefields import CharField
|
||||
import re
|
||||
|
||||
check_url = re.compile(
|
||||
r'^(?:http|ftp)s?://' # http:// or https://
|
||||
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
|
||||
r'localhost|' #localhost...
|
||||
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
|
||||
r'(?::\d+)?' # optional port
|
||||
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
|
||||
|
||||
class UrlField(CharField):
|
||||
|
||||
def check(self, value):
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
if not check_url.match(value):
|
||||
|
||||
self.error=True
|
||||
value=""
|
||||
self.txt_error='No valid URL format'
|
||||
|
||||
return value
|
||||
|
||||
check_domain=re.compile('^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$')
|
||||
|
||||
class DomainField(CharField):
|
||||
|
||||
def check(self, value):
|
||||
|
||||
self.error=False
|
||||
self.txt_error=''
|
||||
|
||||
if not check_domain.match(value):
|
||||
|
||||
self.error=True
|
||||
value=""
|
||||
self.txt_error='No valid domain format'
|
||||
|
||||
return value
|
||||
16
paramecio2/libraries/db/extrafields/usernamefield.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from paramecio2.libraries.db.corefields import PhangoField
|
||||
from paramecio2.libraries.db.coreforms import PasswordForm
|
||||
from hmac import compare_digest as compare_hash
|
||||
import crypt
|
||||
import re
|
||||
|
||||
class UserNameField(PhangoField):
|
||||
|
||||
def check(self, value):
|
||||
|
||||
if not re.match("^[A-Za-z0-9_-]+$", value):
|
||||
self.txt_error='Error: use only letters, numbers, underscores and dashes for this field'
|
||||
self.error=1
|
||||
value=''
|
||||
|
||||
return value
|
||||
0
paramecio2/libraries/db/extraforms/__init__.py
Normal file
20
paramecio2/libraries/db/extraforms/checkform.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
|
||||
class CheckForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value, real_value=1):
|
||||
super(CheckForm, self).__init__(name, value)
|
||||
|
||||
self.real_value=real_value
|
||||
|
||||
def form(self):
|
||||
|
||||
arr_value={}
|
||||
|
||||
arr_value[self.setform(self.default_value)]=''
|
||||
|
||||
arr_value[self.setform(self.real_value)]='checked'
|
||||
|
||||
return '<input type="checkbox" class="'+self.css+'" name="'+self.name+'" id="'+self.name_field_id+'" value="'+str(self.real_value)+'" '+arr_value[self.setform(self.default_value)]+'>'
|
||||
17
paramecio2/libraries/db/extraforms/colorform.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.mtemplates import standard_t
|
||||
|
||||
class ColorForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value):
|
||||
|
||||
super().__init__(name, value)
|
||||
|
||||
self.t=standard_t
|
||||
|
||||
def form(self):
|
||||
|
||||
|
||||
return self.t.load_template('forms/colorform.phtml', name_form=self.name_field_id, default_value=self.default_value, form=self)
|
||||
39
paramecio2/libraries/db/extraforms/dateform.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.mtemplates import standard_t
|
||||
from paramecio2.libraries.datetime import format_timedata
|
||||
|
||||
class DateForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value):
|
||||
|
||||
super().__init__(name, value)
|
||||
|
||||
self.yes_time=False
|
||||
self.t=standard_t
|
||||
|
||||
def form(self):
|
||||
|
||||
y=''
|
||||
m=''
|
||||
d=''
|
||||
h=''
|
||||
min=''
|
||||
s=''
|
||||
min_time=''
|
||||
|
||||
time=format_timedata(self.default_value)
|
||||
|
||||
if time[0]:
|
||||
y=int(time[0])
|
||||
m=int(time[1])
|
||||
d=int(time[2])
|
||||
h=int(time[3])
|
||||
min_time=int(time[4])
|
||||
s=int(time[5])
|
||||
|
||||
return self.t.load_template('forms/dateform.phtml', yes_time=self.yes_time, form=self.name, y=y, m=m, d=d, h=h, min=min_time, s=s)
|
||||
|
||||
#def
|
||||
|
||||
21
paramecio2/libraries/db/extraforms/fileform.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.mtemplates import env_theme, PTemplate
|
||||
|
||||
env=env_theme(__file__)
|
||||
|
||||
t=PTemplate(env)
|
||||
|
||||
class FileForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value, path):
|
||||
|
||||
super().__init__(name, value)
|
||||
|
||||
self.t=t
|
||||
self.enctype=True
|
||||
|
||||
def form(self):
|
||||
|
||||
return self.t.load_template('forms/fileform.phtml', form=self)
|
||||
32
paramecio2/libraries/db/extraforms/i18nform.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.libraries.mtemplates import standard_t
|
||||
import json
|
||||
|
||||
class I18nForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value, form):
|
||||
|
||||
super().__init__(name, value)
|
||||
|
||||
self.form_child=form
|
||||
self.t=standard_t
|
||||
|
||||
def form(self):
|
||||
|
||||
lang_selected=I18n.get_default_lang()
|
||||
|
||||
try:
|
||||
self.default_value=json.loads(self.default_value)
|
||||
except:
|
||||
self.default_value={}
|
||||
|
||||
if type(self.default_value).__name__!='dict':
|
||||
self.default_value={}
|
||||
|
||||
for lang in I18n.dict_i18n:
|
||||
self.default_value[lang]=self.default_value.get(lang, '')
|
||||
|
||||
return standard_t.load_template('forms/i18nform.phtml', name_form=self.name_field_id, real_name_form=self.name, form=self.form_child, arr_i18n=I18n.dict_i18n, lang_selected=lang_selected, default_value=self.default_value)
|
||||
22
paramecio2/libraries/db/extraforms/texthtmlform.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.mtemplates import env_theme, PTemplate
|
||||
|
||||
env=env_theme(__file__)
|
||||
|
||||
t=PTemplate(env)
|
||||
|
||||
class TextHTMLForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value, t_add=None):
|
||||
|
||||
super().__init__(name, value)
|
||||
|
||||
self.t=t_add
|
||||
|
||||
if t_add==None:
|
||||
self.t=t
|
||||
|
||||
def form(self):
|
||||
|
||||
return self.t.load_template('forms/texthtmlform.phtml', form=self)
|
||||
22
paramecio2/libraries/db/extraforms/usernameform.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
from paramecio2.libraries.db.coreforms import BaseForm
|
||||
from paramecio2.libraries.mtemplates import env_theme, PTemplate
|
||||
|
||||
env=env_theme(__file__)
|
||||
|
||||
t=PTemplate(env)
|
||||
|
||||
class TextHTMLForm(BaseForm):
|
||||
|
||||
def __init__(self, name, value, t_add=None):
|
||||
|
||||
super().__init__(name, value)
|
||||
|
||||
self.t=t_add
|
||||
|
||||
if t_add==None:
|
||||
self.t=t
|
||||
|
||||
def form(self):
|
||||
|
||||
return self.t.load_template('forms/texthtmlform.phtml', form=self)
|
||||
210
paramecio2/libraries/db/sqlalchemy.py
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
#import pymysql.cursors
|
||||
#pymysql.install_as_MySQLdb
|
||||
#import sqlalchemy.pool as pool
|
||||
from sqlalchemy import create_engine
|
||||
import traceback
|
||||
|
||||
#mypool=None
|
||||
#engine = create_engine('sqlite:///:memory:', echo=True)
|
||||
engine=None
|
||||
|
||||
class SqlClass:
|
||||
|
||||
cursors_connect=None
|
||||
disable_pool=False
|
||||
pymysql_install=False
|
||||
pool_size=15
|
||||
|
||||
def __init__(self, connection):
|
||||
|
||||
self.max_overflow=-1
|
||||
self.error_connection=""
|
||||
# Data of connection
|
||||
self.connection=connection
|
||||
# Sql connection
|
||||
self.conn=None
|
||||
self.connected=False
|
||||
self.pool_recycle=3600
|
||||
self.connect()
|
||||
|
||||
|
||||
def connect(self):
|
||||
|
||||
global engine
|
||||
|
||||
if not SqlClass.disable_pool:
|
||||
|
||||
if not engine:
|
||||
|
||||
try:
|
||||
|
||||
if self.connection['db_type']=='pymysql':
|
||||
|
||||
import pymysql.cursors
|
||||
|
||||
SqlClass.cursors_connect=pymysql.cursors.DictCursor
|
||||
else:
|
||||
import MySQLdb.cursors
|
||||
SqlClass.cursors_connect=MySQLdb.cursors.DictCursor
|
||||
|
||||
engine=create_engine("mysql+%s://%s:%s@%s/%s?charset=utf8mb4" % (self.connection['db_type'], self.connection['user'], self.connection['password'], self.connection['host'], self.connection['db']), pool_recycle=self.pool_recycle, echo_pool=True, pool_size=self.pool_size, pool_pre_ping=True)
|
||||
|
||||
except:
|
||||
e = sys.exc_info()[0]
|
||||
v = sys.exc_info()[1]
|
||||
|
||||
self.error_connection="Error in connection: %s %s" % (e, v)
|
||||
|
||||
#self.conn.close()
|
||||
|
||||
raise NameError(self.error_connection)
|
||||
|
||||
self.conn=engine.raw_connection()
|
||||
|
||||
#self.conn.ping(True)
|
||||
|
||||
else:
|
||||
|
||||
if self.connection['db_type']=='pymysql':
|
||||
|
||||
import pymysql.cursors
|
||||
|
||||
if not SqlClass.pymysql_install:
|
||||
pymysql.install_as_MySQLdb
|
||||
SqlClass.pymysql_install=True
|
||||
|
||||
self.conn=pymysql.connect(self.connection['host'],
|
||||
user=self.connection['user'],
|
||||
passwd=self.connection['password'],
|
||||
db=self.connection['db'],
|
||||
charset='utf8mb4',
|
||||
cursorclass=pymysql.cursors.DictCursor)
|
||||
|
||||
else:
|
||||
|
||||
import MySQLdb.cursors
|
||||
|
||||
self.conn=MySQLdb.connect(self.connection['host'],
|
||||
user=self.connection['user'],
|
||||
passwd=self.connection['password'],
|
||||
db=self.connection['db'],
|
||||
charset='utf8mb4',
|
||||
cursorclass=MySQLdb.cursors.DictCursor)
|
||||
|
||||
pass
|
||||
|
||||
"""
|
||||
if self.conn==None:
|
||||
try:
|
||||
def getconn():
|
||||
return pymysql.connect(self.connection['host'],
|
||||
user=self.connection['user'],
|
||||
passwd=self.connection['password'],
|
||||
db=self.connection['db'],
|
||||
charset='utf8mb4',
|
||||
cursorclass=pymysql.cursors.DictCursor)
|
||||
|
||||
if mypool==None:
|
||||
|
||||
mypool=pool.QueuePool(getconn, max_overflow=self.max_overflow, pool_size=self.pool_size, recycle=self.pool_recycle, use_threadlocal=True)
|
||||
|
||||
self.conn=mypool.connect()
|
||||
|
||||
self.conn.ping(True)
|
||||
|
||||
self.connected=True
|
||||
|
||||
except:
|
||||
e = sys.exc_info()[0]
|
||||
v = sys.exc_info()[1]
|
||||
|
||||
self.error_connection="Error in connection: %s %s" % (e, v)
|
||||
|
||||
self.conn.close()
|
||||
|
||||
raise NameError(self.error_connection)
|
||||
"""
|
||||
|
||||
#Make def query more simple if not debugging.
|
||||
|
||||
def query(self, sql_query, arguments=[], name_connection="default"):
|
||||
|
||||
|
||||
cursor=self.conn.cursor(SqlClass.cursors_connect)
|
||||
|
||||
try:
|
||||
|
||||
cursor.execute(sql_query, arguments)
|
||||
self.conn.commit()
|
||||
return cursor
|
||||
|
||||
except:
|
||||
e = sys.exc_info()[0]
|
||||
v = sys.exc_info()[1]
|
||||
|
||||
if hasattr(cursor, '_last_executed'):
|
||||
sql_query=cursor._last_executed
|
||||
|
||||
self.error_connection="Error in query ||%s||Values: %s" % (sql_query, str(arguments))
|
||||
|
||||
self.conn.close()
|
||||
|
||||
#return False
|
||||
raise NameError(self.error_connection)
|
||||
|
||||
|
||||
#self.connect()
|
||||
|
||||
#if fetch_type=="ASSOC":
|
||||
#fetch_type=MySQLdb.cursors.DictCursor
|
||||
|
||||
#with self.conn.cursor(MySQLdb.cursors.DictCursor) as cursor:
|
||||
"""
|
||||
cursor=self.conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
try:
|
||||
|
||||
cursor.execute(sql_query, arguments)
|
||||
self.conn.commit()
|
||||
|
||||
return cursor
|
||||
|
||||
|
||||
except:
|
||||
e = sys.exc_info()[0]
|
||||
v = sys.exc_info()[1]
|
||||
|
||||
if hasattr(cursor, '_last_executed'):
|
||||
sql_query=cursor._last_executed
|
||||
#, traceback.format_exc()
|
||||
self.error_connection="Error in query ||%s||Values: %s" % (sql_query, str(arguments))
|
||||
|
||||
#return False
|
||||
raise NameError(self.error_connection)
|
||||
"""
|
||||
|
||||
#Fetcho row return dictionary if is defined in query.
|
||||
|
||||
#def fetch(self, cursor):
|
||||
|
||||
#return cursor.fetchone()
|
||||
|
||||
def __del__(self):
|
||||
|
||||
if self.conn:
|
||||
|
||||
self.conn.close()
|
||||
|
||||
def close(self, name_connection="default"):
|
||||
|
||||
if self.conn:
|
||||
|
||||
self.conn.close()
|
||||
self.conn=None
|
||||
|
||||
pass
|
||||
|
||||
|
||||
156
paramecio2/libraries/db/usermodel.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.libraries.db.coreforms import PasswordForm
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from flask import request
|
||||
|
||||
class UserModel(WebModel):
|
||||
|
||||
def __init__(self, name_field_id="id"):
|
||||
|
||||
super().__init__(name_field_id)
|
||||
|
||||
self.password_field='password'
|
||||
self.email_field='email'
|
||||
self.username_field='username'
|
||||
self.yes_repeat_password=True
|
||||
self.check_user=True
|
||||
self.check_email=True
|
||||
|
||||
def create_forms(self, arr_fields=[]):
|
||||
|
||||
# Add password_repeat to forms from the model
|
||||
|
||||
arr_fields=super().create_forms(arr_fields)
|
||||
|
||||
if self.password_field in arr_fields and self.yes_repeat_password:
|
||||
|
||||
repeat_password=PasswordForm('repeat_password', '')
|
||||
|
||||
repeat_password.required=1
|
||||
|
||||
repeat_password.label=I18n.lang('common', 'repeat_password', 'Repeat Password')
|
||||
|
||||
repeat_password.field=self.fields['password']
|
||||
|
||||
self.create_form_after(self.password_field, repeat_password)
|
||||
|
||||
return arr_fields
|
||||
|
||||
"""
|
||||
def insert(self, dict_values, external_agent=True):
|
||||
|
||||
if 'password' in dict_values:
|
||||
|
||||
dict_values['repeat_password']=dict_values.get('repeat_password', '')
|
||||
|
||||
if dict_values['repeat_password']!=dict_values[self.password_field]:
|
||||
self.fields[self.password_field].error=True
|
||||
self.fields['password'].txt_error=I18n.lang('common', 'error_passwords_no_match', 'Error: passwords doesn\'t match')
|
||||
|
||||
return super().insert(dict_values, external_agent)
|
||||
"""
|
||||
|
||||
def check_all_fields(self, dict_values, external_agent, yes_update=False, errors_set="insert"):
|
||||
|
||||
error=0
|
||||
|
||||
try:
|
||||
|
||||
fields, values, update_values=super().check_all_fields(dict_values, external_agent, yes_update, errors_set)
|
||||
except:
|
||||
|
||||
error+=1
|
||||
|
||||
if self.check_user==True:
|
||||
|
||||
# Check if passwords matches
|
||||
|
||||
if self.password_field in dict_values:
|
||||
|
||||
dict_values['repeat_password']=dict_values.get('repeat_password', '')
|
||||
|
||||
if dict_values[self.password_field].strip()!="":
|
||||
|
||||
if dict_values['repeat_password']!=dict_values[self.password_field]:
|
||||
|
||||
self.fields[self.password_field].error=True
|
||||
self.fields[self.password_field].txt_error=I18n.lang('common', 'error_passwords_no_match', 'Error: passwords doesn\'t match')
|
||||
|
||||
error+=1
|
||||
|
||||
# Check if exists user with same email or password
|
||||
|
||||
get_id=0
|
||||
|
||||
if self.updated:
|
||||
# Need the id
|
||||
#GetPostFiles.obtain_get()
|
||||
#GetPostFiles.obtain_post()
|
||||
"""
|
||||
getpostfiles=GetPostFiles()
|
||||
|
||||
getpostfiles.obtain_get()
|
||||
"""
|
||||
|
||||
#get_id=getpostfiles.get.get(self.name_field_id, '0')
|
||||
get_id=requests.args.get(self.name_field_id, '0')
|
||||
|
||||
#post_id=getpostfiles.post.get(self.name_field_id, '0')
|
||||
post_id=requests.form.get(self.name_field_id, '0')
|
||||
|
||||
if get_id!='0':
|
||||
get_id=int(get_id)
|
||||
|
||||
if post_id!='0':
|
||||
get_id=int(post_id)
|
||||
|
||||
pass
|
||||
|
||||
get_id=int(get_id)
|
||||
|
||||
sql_id=''
|
||||
|
||||
original_conditions=self.conditions
|
||||
|
||||
self.reset_conditions()
|
||||
|
||||
if self.username_field in dict_values:
|
||||
|
||||
self.conditions=['WHERE username=%s AND '+self.name_field_id+'!=%s', [dict_values[self.username_field], get_id]]
|
||||
|
||||
if self.select_count()>0:
|
||||
|
||||
self.fields[self.username_field].error=True
|
||||
self.fields[self.username_field].txt_error=I18n.lang('common', 'error_username_exists', 'Error: username already exists')
|
||||
self.fields_errors[self.username_field].append(self.fields[self.username_field].txt_error)
|
||||
error+=1
|
||||
|
||||
|
||||
if self.check_email:
|
||||
|
||||
if self.email_field in dict_values:
|
||||
|
||||
self.conditions=['WHERE email=%s AND '+self.name_field_id+'!=%s', [dict_values[self.email_field], get_id]]
|
||||
|
||||
if self.select_count()>0:
|
||||
|
||||
self.fields[self.email_field].error=True
|
||||
self.fields[self.email_field].txt_error=I18n.lang('common', 'error_email_exists', 'Error: this email is already being used')
|
||||
self.fields_errors[self.email_field].append(self.fields[self.email_field].txt_error)
|
||||
|
||||
error+=1
|
||||
|
||||
self.conditions=original_conditions
|
||||
|
||||
if error>0:
|
||||
self.query_error+='Error:if is not expected, please, check that you disabled the special checkings of this model'
|
||||
return False
|
||||
|
||||
return fields, values, update_values
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1369
paramecio2/libraries/db/webmodel.py
Normal file
136
paramecio2/libraries/formsutils.py
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from paramecio2.libraries.db import corefields
|
||||
from paramecio2.libraries.db.coreforms import PasswordForm
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from flask import session
|
||||
from paramecio2.libraries.keyutils import create_key_encrypt
|
||||
|
||||
# Need unittest
|
||||
|
||||
def pass_values_to_form(post, arr_form, yes_error=True, pass_values=True):
|
||||
|
||||
if pass_values:
|
||||
def get_value(key):
|
||||
return post[key]
|
||||
|
||||
else:
|
||||
def get_value(key):
|
||||
return arr_form[key].default_value
|
||||
|
||||
for key, value in arr_form.items():
|
||||
|
||||
post[key]=post.get(key, '')
|
||||
|
||||
#if arr_form[key].default_value=='':
|
||||
arr_form[key].default_value=get_value(key)
|
||||
|
||||
if arr_form[key].field==None:
|
||||
arr_form[key].field=corefields.CharField(key, 255, required=False)
|
||||
|
||||
# Recheck value if no set error field
|
||||
if arr_form[key].field.error == None:
|
||||
arr_form[key].field.check(post[key])
|
||||
|
||||
#arr_form[key].txt_error=""
|
||||
|
||||
if arr_form[key].required==True and arr_form[key].field.error==True and yes_error==True:
|
||||
arr_form[key].txt_error=arr_form[key].field.txt_error
|
||||
|
||||
# Reset error on field.
|
||||
|
||||
arr_form[key].field.error=None
|
||||
|
||||
return arr_form
|
||||
|
||||
class CheckForm():
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.error=0
|
||||
|
||||
def check(self, post, arr_form):
|
||||
|
||||
for k in arr_form.keys():
|
||||
|
||||
post[k]=post.get(k, '')
|
||||
|
||||
if arr_form[k].field==None:
|
||||
arr_form[k].field=corefields.CharField(k, 255, required=False)
|
||||
|
||||
post[k]=arr_form[k].field.check(post[k])
|
||||
arr_form[k].txt_error=arr_form[k].field.txt_error
|
||||
|
||||
if arr_form[k].field.error==True and arr_form[k].required==True:
|
||||
self.error+=1
|
||||
|
||||
return post, arr_form
|
||||
|
||||
def check_form(post, arr_form, sufix_form='_error'):
|
||||
|
||||
error=0
|
||||
error_form={}
|
||||
|
||||
for k in arr_form.keys():
|
||||
|
||||
post[k]=post.get(k, '')
|
||||
|
||||
if arr_form[k].field==None:
|
||||
arr_form[k].field=corefields.CharField(k, 255, required=False)
|
||||
|
||||
post[k]=arr_form[k].field.check(post[k])
|
||||
arr_form[k].txt_error=arr_form[k].field.txt_error
|
||||
|
||||
if arr_form[k].field.error==True and arr_form[k].required==True:
|
||||
error_form['#'+k+sufix_form]=arr_form[k].txt_error
|
||||
error+=1
|
||||
|
||||
return error, error_form, post, arr_form
|
||||
|
||||
def show_form(post, arr_form, t, yes_error=True, pass_values=True, modelform_tpl='forms/modelform.phtml'):
|
||||
|
||||
# Create csrf_token in session
|
||||
|
||||
generate_csrf()
|
||||
|
||||
if pass_values==True:
|
||||
pass_values_to_form(post, arr_form, yes_error, pass_values)
|
||||
|
||||
return t.load_template(modelform_tpl, forms=arr_form)
|
||||
|
||||
#Simple Function for add repeat_password form to user model
|
||||
|
||||
def set_extra_forms_user(user_admin):
|
||||
|
||||
user_admin.fields['password'].required=True
|
||||
user_admin.fields['email'].required=True
|
||||
|
||||
user_admin.create_forms(['username', 'email', 'password'])
|
||||
|
||||
user_admin.forms['repeat_password']=PasswordForm('repeat_password', '')
|
||||
|
||||
user_admin.forms['repeat_password'].required=True
|
||||
|
||||
user_admin.forms['repeat_password'].label=I18n.lang('common', 'repeat_password', 'Repeat Password')
|
||||
|
||||
#Function for initial values for necessary fields.
|
||||
|
||||
def ini_fields(fields):
|
||||
pass
|
||||
|
||||
def csrf_token(token_id='csrf_token'):
|
||||
|
||||
#s=get_session()
|
||||
|
||||
if not 'csrf_token' in session:
|
||||
session['csrf_token']=create_key_encrypt()
|
||||
|
||||
return '<input type="hidden" name="csrf_token" class="csrf_token" id="'+token_id+'" value="'+session['csrf_token']+'" />'
|
||||
|
||||
def generate_csrf():
|
||||
|
||||
if not 'csrf_token' in session:
|
||||
session['csrf_token']=create_key_encrypt()
|
||||
|
||||
return session['csrf_token']
|
||||
|
||||
|
|
@ -44,10 +44,8 @@ class I18n:
|
|||
def get_default_lang():
|
||||
|
||||
lang=I18n.default_lang
|
||||
|
||||
s=session
|
||||
|
||||
lang=s.get('lang', lang)
|
||||
#lang=session.get('lang', lang)
|
||||
|
||||
return lang
|
||||
|
||||
|
|
|
|||
19
paramecio2/libraries/keyutils.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from hashlib import sha512, sha256
|
||||
from base64 import b64encode
|
||||
from os import urandom
|
||||
|
||||
# Functions for create random strings usando urandom
|
||||
|
||||
def create_key_encrypt(n=10):
|
||||
|
||||
return sha512(urandom(n)).hexdigest()
|
||||
|
||||
def create_key_encrypt_256(n=10):
|
||||
|
||||
return sha256(urandom(n)).hexdigest()
|
||||
|
||||
def create_key(n=10):
|
||||
|
||||
rand_bytes=urandom(n)
|
||||
|
||||
return b64encode(rand_bytes).decode('utf-8')[0:-2]
|
||||
|
|
@ -9,6 +9,7 @@ import gettext
|
|||
import sys
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.libraries.urls import make_url, make_media_url
|
||||
from paramecio2.libraries.formsutils import csrf_token
|
||||
|
||||
def env_theme(module, cache_enabled=True, cache_impl='', cache_args={}, module_directory="./tmp/modules"):
|
||||
|
||||
|
|
@ -49,12 +50,14 @@ class PTemplate:
|
|||
|
||||
self.add_filter(I18n.lang)
|
||||
|
||||
self.add_filter(make_url)
|
||||
#self.add_filter(make_url)
|
||||
|
||||
self.add_filter(make_media_url)
|
||||
|
||||
self.add_filter(url_for)
|
||||
|
||||
self.add_filter(csrf_token)
|
||||
|
||||
"""
|
||||
def gettext(self, text):
|
||||
return gettext.dgettext(self.domain_gettext, text)
|
||||
|
|
@ -102,3 +105,7 @@ class PTemplate:
|
|||
|
||||
self.filters[filter_name.__name__]=filter_name
|
||||
|
||||
env=env_theme(__file__)
|
||||
|
||||
standard_t=PTemplate(env)
|
||||
|
||||
|
|
|
|||
33
paramecio2/libraries/templates/forms/colorform.phtml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
${add_js_home_local('jquery.min.js', 'admin')}
|
||||
${add_js_home_local('spectrum.js', 'admin')}
|
||||
${add_css_home_local('spectrum.css', 'admin')}
|
||||
<%
|
||||
|
||||
|
||||
form.default_value=str(hex(int(form.default_value))).replace('0x', '')
|
||||
|
||||
c=len(form.default_value)
|
||||
|
||||
if(c<6):
|
||||
repeat=6-c
|
||||
form.default_value=('0'*repeat)+form.default_value
|
||||
|
||||
form.default_value='#'+form.default_value
|
||||
|
||||
%>
|
||||
|
||||
<input type='text' id="${form.name_field_id}_field_form" name="${form.name}" value="${form.default_value}" />
|
||||
<script>
|
||||
$("#${form.name_field_id}_field_form").spectrum({
|
||||
allowEmpty: true
|
||||
});
|
||||
|
||||
$("#${form.name_field_id}_field_form").closest('form').submit( function () {
|
||||
|
||||
var t=$("#${form.name_field_id}_field_form").spectrum("get");
|
||||
|
||||
$('#${form.name_field_id}_field_form').val(t.toHexString());
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
71
paramecio2/libraries/templates/forms/dateform.phtml
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
${add_js_home_local('jquery.min.js', 'admin')}
|
||||
|
||||
<input type="number" min="1" max="31" name="${form}_day" id="time_${form}_day" class="form_day" value="${d}" size="2" maxlength="2"/>
|
||||
<input type="number" min="1" max="12" name="${form}_month" id="time_${form}_month" class="form_month" value="${m}" size="2" maxlength="2"/>
|
||||
<input type="number" name="${form}_year" id="time_${form}_year" class="form_year" value="${y}" size="4" maxlength="4"/>
|
||||
% if yes_time==True:
|
||||
<input type="text" min="0" max="23" name="${form}_hour" id="time_${form}_hour" class="form_hour" value="${h}" size="2" maxlength="2"/>
|
||||
<input type="text" min="0" max="60" name="${form}_minute" id="time_${form}_minute" class="form_minute" value="${min}" size="2" maxlength="2"/>
|
||||
<input type="text" min="0" max="60" name="${form}_second" id="time_${form}_second" class="form_second" value="${s}" size="2" maxlength="2"/>
|
||||
% endif
|
||||
<input type="hidden" name="${form}" id="time_${form}" value="" />
|
||||
|
||||
<script language="javascript">
|
||||
$(document).submit(function () {
|
||||
|
||||
year=$("#time_${form}_year").val().toString();
|
||||
month=$("#time_${form}_month").val().toString();
|
||||
day=$("#time_${form}_day").val().toString();
|
||||
|
||||
year=add_extra_length(year, 4);
|
||||
month=add_extra_length(month, 2);
|
||||
day=add_extra_length(day, 2);
|
||||
|
||||
final_time=year+month+day
|
||||
|
||||
% if yes_time==True:
|
||||
hour=$("#time_${form}_hour").val().toString();
|
||||
minute=$("#time_${form}_minute").val().toString();
|
||||
second=$("#time_${form}_second").val().toString();
|
||||
|
||||
hour=add_extra_length(hour, 2);
|
||||
minute=add_extra_length(minute, 2);
|
||||
second=add_extra_length(second, 2);
|
||||
|
||||
final_time+=final_time;
|
||||
|
||||
% else:
|
||||
|
||||
final_time+='000000';
|
||||
|
||||
% endif
|
||||
|
||||
|
||||
$("#time_${form}").val(final_time);
|
||||
|
||||
});
|
||||
|
||||
function add_extra_length(str_number, total_length)
|
||||
{
|
||||
|
||||
if(str_number.length<total_length)
|
||||
{
|
||||
c=total_length-str_number.length;
|
||||
|
||||
extra_number='';
|
||||
|
||||
for(x=0;x<c;x++)
|
||||
{
|
||||
|
||||
extra_number+='0';
|
||||
|
||||
}
|
||||
|
||||
str_number=extra_number+str_number;
|
||||
}
|
||||
|
||||
return str_number;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
12
paramecio2/libraries/templates/forms/fileform.phtml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<%
|
||||
|
||||
import os
|
||||
|
||||
name_file=os.path.basename(form.default_value)
|
||||
|
||||
%>
|
||||
<input type="file" name="${form.name}_file" id="${form.name}_file_field_form" />
|
||||
% if name_file:
|
||||
${name_file}
|
||||
% endif
|
||||
<input type="hidden" name="${form.name}" id="${form.name}_field_form" value="${form.default_value}"/>
|
||||
61
paramecio2/libraries/templates/forms/i18nform.phtml
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
${add_js_home_local('tools.js', 'admin')}
|
||||
<%
|
||||
|
||||
choose=''
|
||||
|
||||
%>
|
||||
<div id="languages_form">
|
||||
<%def name="select_lang(i18n, lang_selected)">
|
||||
% if i18n==lang_selected:
|
||||
<%
|
||||
return "choose_flag"
|
||||
%>
|
||||
% else:
|
||||
<%
|
||||
return "no_choose_flag"
|
||||
%>
|
||||
% endif
|
||||
</%def>
|
||||
<%def name="hide_lang(i18n, lang_selected)">
|
||||
% if i18n!=lang_selected:
|
||||
style="display:none;"
|
||||
% endif
|
||||
</%def>
|
||||
<input type="hidden" name="${real_name_form}" id="${name_form}_i18n_value" value="" />
|
||||
% if lang_selected!=None:
|
||||
% for i18n in arr_i18n:
|
||||
|
||||
${form.change_name(name_form+'_'+i18n)}
|
||||
<%
|
||||
form.default_value=default_value[i18n]
|
||||
%>
|
||||
<span id="${name_form}_${i18n}_switch" class="${name_form}_i18n_form">${form.form()|n}</span> <a class="choose_flag ${name_form}_i18n_flag lang_form" id="${name_form}_${i18n}_element" href="#"><img src="${make_media_url_module('images/languages/'+i18n+'.png', 'admin')}" alt="${name_form}_${i18n}"/></a>
|
||||
% endfor
|
||||
% endif
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
//In submit convert in json
|
||||
|
||||
$(".${name_form}_i18n_flag").closest('form').submit( function () {
|
||||
|
||||
arr_i18n={}
|
||||
|
||||
$(".${name_form}_i18n_form").each(function () {
|
||||
|
||||
var lang=$(this).attr('id').replace('${name_form}_','').replace('_switch', '');
|
||||
|
||||
var child_input=$('#${name_form}_'+lang+'_form');
|
||||
|
||||
arr_i18n[lang]=child_input.val();
|
||||
|
||||
});
|
||||
|
||||
document.getElementById("${name_form}_i18n_value").value=JSON.stringify(arr_i18n);
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
5
paramecio2/libraries/templates/forms/modelform.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<div class="form">
|
||||
{% for form in forms.values() %}
|
||||
<p><label>{{form.label|safe}}</label>{{form.form()}}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
21
paramecio2/libraries/templates/forms/modelform.phtml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<%def name="check_required(required)">
|
||||
% if required:
|
||||
${'*'} \
|
||||
% endif
|
||||
</%def>
|
||||
<%def name="help(help, name)">
|
||||
% if help:
|
||||
<i class="fa fa-question-circle tooltip" data-tooltip-content="#tooltip_${name}_content" style="cursor:pointer;"></i> \
|
||||
<div class="tooltip_templates" style="display:none;"><div id="tooltip_${name}_content">${help|n}</div></div>
|
||||
% endif
|
||||
</%def>
|
||||
<div class="form">
|
||||
% for form in forms.values():
|
||||
% if form.type!='hidden':
|
||||
<p><label>${form.label} ${check_required(form.required)} ${help(form.help, form.name)}</label>${form.form()|n} <span class="error" id="${form.name}_error">${form.txt_error}</span></p>
|
||||
% else:
|
||||
${form.form()|n}
|
||||
% endif
|
||||
% endfor
|
||||
${csrf_token()|n}
|
||||
</div>
|
||||
22
paramecio2/libraries/templates/forms/texthtmlform.phtml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<p>
|
||||
<textarea name="${form.name}" id="${form.name_field_id}">
|
||||
${form.default_value}
|
||||
</textarea>
|
||||
</p>
|
||||
<script>
|
||||
tinymce.init({
|
||||
selector: '#${form.name_field_id}',
|
||||
height: 500,
|
||||
menubar: true,
|
||||
plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists textcolor wordcount imagetools contextmenu colorpicker textpattern',
|
||||
toolbar: 'formatselect | fontsizeselect bold italic underline strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat',
|
||||
fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt 48pt 64pt 100pt 120pt",
|
||||
content_css: '//www.tinymce.com/css/codepen.min.css',
|
||||
setup: function (editor) {
|
||||
editor.on('change', function () {
|
||||
tinymce.triggerSave();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
${add_js_home_local('tinymce/tinymce.min.js', 'admin')}
|
||||
12
paramecio2/libraries/templates/utils/accept.phtml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
${question_text}: <input type="button" value="Yes" id="accept"/>
|
||||
<script language="javascript">
|
||||
|
||||
$('#accept').click( function () {
|
||||
|
||||
location.href='${url_redirect|n}'
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<%block name="form">
|
||||
</%block>
|
||||
4
paramecio2/libraries/templates/utils/admin.phtml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
${show_flash_message()|n}
|
||||
<!--<h1>${admin.title}</h1>-->
|
||||
<p><a href="${add_get_parameters(admin.url, op_admin='1')}">${lang('common', 'add_item', 'Add new item')}</a></p>
|
||||
${admin.list.show()|n}
|
||||
21
paramecio2/libraries/templates/utils/insertform.phtml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<p><a href="${admin.url_redirect}">${admin.text_home|n}</a> >> \
|
||||
% if id!='0':
|
||||
${title_edit} \
|
||||
%else:
|
||||
${title_edit} \
|
||||
%endif
|
||||
<%
|
||||
|
||||
enctype_txt=''
|
||||
|
||||
if enctype:
|
||||
enctype_txt='enctype="multipart/form-data"'
|
||||
|
||||
%>
|
||||
</p>
|
||||
<form method="post" action="${url_action}" ${enctype_txt|n}>
|
||||
<h2>${title_edit}</h2>
|
||||
<span class="error">${model.query_error}</span>
|
||||
${ form|n }
|
||||
<p><input type="submit" value="${lang('common', 'send', 'Send') }"></p>
|
||||
</form>
|
||||
135
paramecio2/libraries/templates/utils/list.phtml
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<%def name="select_field(field)">
|
||||
% if simplelist.search_field==field:
|
||||
selected \
|
||||
% endif
|
||||
</%def>
|
||||
<%def name="set_css_arrow(simplelist, field)">
|
||||
% if simplelist.order_field==field:
|
||||
<i class="fa fa-arrow-${simplelist.order_class[simplelist.order]}" aria-hidden="true"></i>
|
||||
% endif
|
||||
</%def>
|
||||
% if simplelist.yes_search:
|
||||
<div class="form">
|
||||
<form method="get" action="${simplelist.url}">
|
||||
${lang('common','search', 'Search')}: <input type="text" name="search_text" value="${simplelist.search_text|n}">
|
||||
<select name="search_field">
|
||||
% for field in simplelist.search_fields:
|
||||
<option value="${simplelist.model.fields[field].name}" ${select_field(field)}>${simplelist.model.fields[field].label}</option>
|
||||
% endfor
|
||||
</select>
|
||||
<input type="submit" value="${lang('common', 'search', 'Search')}" />
|
||||
</form>
|
||||
</div>
|
||||
% endif
|
||||
% if not simplelist.table_div:
|
||||
|
||||
<table class="table_list" id="${simplelist.model.name}_table">
|
||||
<tr class="title_list">
|
||||
% for field in simplelist.fields_showed:
|
||||
<td class="${simplelist.model.fields[field].name}_td"><a href="${add_get_parameters(simplelist.url, order_field=field, begin_page=simplelist.begin_page, order=simplelist.change_order[field], search_text=simplelist.search_text, search_field=simplelist.search_field)}" class="">${set_css_arrow(simplelist, field)}${simplelist.model.fields[field].label}</a></td>
|
||||
% endfor
|
||||
% for extra_field in simplelist.arr_extra_fields:
|
||||
<td class="options_td">${ extra_field }</td>
|
||||
% endfor
|
||||
</tr>
|
||||
<%
|
||||
pos=0
|
||||
%>
|
||||
% for row in list:
|
||||
<%
|
||||
if not 'pos' in row:
|
||||
row['pos']=pos
|
||||
%>
|
||||
<tr class="row_list">
|
||||
% for field in simplelist.fields_showed:
|
||||
% if simplelist.model.fields[field].escape==True:
|
||||
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
|
||||
<td class="${simplelist.model.fields[field].name}_td">${simplelist.model.fields[field].show_formatted(row[field])}</td>
|
||||
% else:
|
||||
<td class="${simplelist.model.fields[field].name}_td">${simplelist.model.fields[field].show_formatted(row[field])}${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))}</td>
|
||||
% endif
|
||||
% else:
|
||||
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
|
||||
<td class="${simplelist.model.fields[field].name}_td">${str(simplelist.model.fields[field].show_formatted(row[field]))|n}</td>
|
||||
% else:
|
||||
<td class="${simplelist.model.fields[field].name}_td">${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))|n}</td>
|
||||
% endif
|
||||
% endif
|
||||
% endfor
|
||||
|
||||
% for extra_field_func in simplelist.arr_extra_options:
|
||||
<td class="options_td">${ simplelist.set_options(extra_field_func, row)|n }</td>
|
||||
% endfor
|
||||
</tr>
|
||||
<%
|
||||
pos+=1
|
||||
%>
|
||||
% endfor
|
||||
</table>
|
||||
|
||||
% else:
|
||||
|
||||
<%
|
||||
|
||||
size_td=round(100/(len(simplelist.fields_showed)+len(simplelist.arr_extra_options)))
|
||||
|
||||
%>
|
||||
|
||||
<div class="table_list" id="${simplelist.model.name}_table">
|
||||
<div class="${simplelist.model.name}_tr tr_list_div">
|
||||
% for field in simplelist.fields_showed:
|
||||
<div class="${simplelist.model.fields[field].name}_td fields_span_title" style="width: ${size_td}%;"><a href="${add_get_parameters(simplelist.url, order_field=field, begin_page=simplelist.begin_page, order=simplelist.change_order[field], search_text=simplelist.search_text, search_field=simplelist.search_field)}" class="">${set_css_arrow(simplelist, field)}${simplelist.model.fields[field].label}</a></div>
|
||||
% endfor
|
||||
% for extra_field in simplelist.arr_extra_fields:
|
||||
<div class="fields_span_title options_td" style="width: ${size_td}%;">${ extra_field }</div>
|
||||
% endfor
|
||||
</div>
|
||||
<div class="table_rows ${simplelist.model.name}_table_rows" id="${simplelist.model.name}_table_rows">
|
||||
<%
|
||||
pos=0
|
||||
%>
|
||||
% for row in list:
|
||||
<div id="${simplelist.model.name}_table_${row['id']}" class="${simplelist.model.name}_table_row" style="clear: both;overflow: hidden;">
|
||||
<%
|
||||
if not 'pos' in row:
|
||||
row['pos']=pos
|
||||
%>
|
||||
|
||||
% for field in simplelist.fields_showed:
|
||||
% if simplelist.model.fields[field].escape==True:
|
||||
<div class="${simplelist.model.fields[field].name}_td fields_span_table_data" style="width: ${size_td}%;">
|
||||
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
|
||||
${simplelist.model.fields[field].show_formatted(row[field])}
|
||||
% else:
|
||||
${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))}
|
||||
% endif
|
||||
</div>
|
||||
% else:
|
||||
<div class="${simplelist.model.fields[field].name}_td fields_span_table_data" style="width: ${size_td}%;">
|
||||
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
|
||||
${str(simplelist.model.fields[field].show_formatted(row[field]))|n}
|
||||
% else:
|
||||
${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))|n}
|
||||
% endif
|
||||
</div>
|
||||
% endif
|
||||
% endfor
|
||||
|
||||
% for extra_field_func in simplelist.arr_extra_options:
|
||||
<div class="options_td fields_span_table_data" style="width: ${size_td}%;">${ simplelist.set_options(extra_field_func, row)|n }</div>
|
||||
% endfor
|
||||
<%
|
||||
pos+=1
|
||||
%>
|
||||
</div>
|
||||
% endfor
|
||||
</div>
|
||||
<br clear="all" />
|
||||
</div>
|
||||
|
||||
% endif
|
||||
<p>
|
||||
% if pages!='':
|
||||
${lang('common', 'pages', 'Pages')}: ${pages|n}
|
||||
% endif
|
||||
</p>
|
||||
85
paramecio2/libraries/templates/utils/translations.phtml
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<div id="container_translation">
|
||||
<div class="flash" style="display:none;">${lang('admin', 'translation_saved_sucessfully', 'Translation saved sucessfully')}</div>
|
||||
<br />
|
||||
<form method="get" action="">
|
||||
${lang('admin', 'modules', 'Modules')}
|
||||
${form_module.form()|n}
|
||||
<input type="submit" value="${lang('admin', 'change_module_to_translate', 'Change module to translate')}" />
|
||||
</form>
|
||||
<div id="saving" style="display:none;"><i class="fa fa-circle-o-notch fa-2x fa-spin fa-fw"></i> ${lang('admin', 'saving_translation', 'Saving translation')}</div>
|
||||
<form method="post" action="#" id="send_text">
|
||||
% if len(arr_i18n_form):
|
||||
|
||||
<p><input type="submit" value="${lang('admin', 'send', 'Send')}" /></p>
|
||||
|
||||
% for i18n_form in arr_i18n_form:
|
||||
|
||||
<p>${i18n_form.form()|n}</p>
|
||||
|
||||
% endfor
|
||||
|
||||
<p><input type="submit" value="${lang('admin', 'send', 'Send')}" /></p>
|
||||
|
||||
% endif
|
||||
${csrf_token("csrf_token")|n}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
$('#send_text').submit( function () {
|
||||
|
||||
$('#send_text').hide();
|
||||
$('#saving').show();
|
||||
|
||||
url="${make_admin_url('lang/translations',{'module_admin': selected_module, 'op': '1'})}";
|
||||
|
||||
/*data=$(this).serializeArray().reduce(function(obj, item) {
|
||||
obj[item.name] = item.value;
|
||||
return obj;
|
||||
}, {});*/
|
||||
|
||||
data=$(this).serialize()
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: data,
|
||||
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
|
||||
success: function (data) {
|
||||
|
||||
$('#saving').hide();
|
||||
|
||||
if(!data.error) {
|
||||
|
||||
$('#send_text').show();
|
||||
$('.flash').show();
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
$(".flash").fadeOut(1000)
|
||||
|
||||
}, 3000);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
alert('Error: cannot update the translations');
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
error: function (data) {
|
||||
|
||||
alert(JSON.stringify(data));
|
||||
$('#send_text').show();
|
||||
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
</script>
|
||||
8
paramecio2/libraries/templates/utils/verify_delete.phtml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<form method="post" action="${add_get_parameters(url, id=item_id, op_admin=op_admin, verified=verified)}">
|
||||
<div class="form">
|
||||
<!-- <input type="hidden" name="id" value="${item_id}">
|
||||
<input type="hidden" name="op_admin" value="${op_admin}">
|
||||
<input type="hidden" name="verified" value="${verified}">-->
|
||||
<input type="submit" value="${lang('common', 'delete_item_you_sure', 'Are you sure for delete this item?')}" />
|
||||
</div>
|
||||
</form>
|
||||
177
paramecio2/modules/admin/app.py
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
from flask import Blueprint, redirect, session, url_for, request, g, make_response
|
||||
from settings import config
|
||||
from paramecio2.libraries.mtemplates import PTemplate, env_theme
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.libraries.formsutils import show_form, generate_csrf, set_extra_forms_user, pass_values_to_form
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.modules.admin.models.admin import UserAdmin
|
||||
from paramecio2.libraries.keyutils import create_key_encrypt
|
||||
|
||||
env=env_theme(__file__)
|
||||
|
||||
t=PTemplate(env)
|
||||
|
||||
yes_recovery_login=False
|
||||
email_address='localhost'
|
||||
|
||||
if hasattr(config, 'yes_recovery_login'):
|
||||
yes_recovery_login=config.yes_recovery_login
|
||||
|
||||
if hasattr(config, 'email_address'):
|
||||
email_address=config.email_address
|
||||
|
||||
|
||||
admin_app=Blueprint('admin_app', __name__, static_folder='static')
|
||||
|
||||
@admin_app.before_request
|
||||
def admin_prepare():
|
||||
|
||||
g.connection=WebModel.connection()
|
||||
|
||||
if request.endpoint!='admin_app.login' and request.endpoint!='admin_app.signup':
|
||||
if 'login_admin' not in session:
|
||||
return redirect(url_for('admin_app.login'))
|
||||
|
||||
@admin_app.after_request
|
||||
def admin_finished(response):
|
||||
|
||||
#print('pepe')
|
||||
|
||||
g.connection.close()
|
||||
|
||||
return response
|
||||
|
||||
# Load
|
||||
|
||||
@admin_app.route('/admin')
|
||||
@admin_app.route('/admin/<module>')
|
||||
def admin(module=''):
|
||||
|
||||
"""
|
||||
if 'login_admin' not in session:
|
||||
return redirect(url_for('admin_app.login'))
|
||||
"""
|
||||
|
||||
return t.load_template('home.phtml', title=I18n.lang('admin', 'paramecio_admin', 'Paramecio admin'))
|
||||
|
||||
@admin_app.route('/admin/logout')
|
||||
def logout():
|
||||
|
||||
return redirect(url_for('admin_app.login'))
|
||||
|
||||
@admin_app.route('/admin/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
|
||||
#connection=WebModel.connection()
|
||||
|
||||
user_admin=UserAdmin(g.connection)
|
||||
|
||||
user_admin.yes_repeat_password=False
|
||||
|
||||
user_admin.fields['password'].required=True
|
||||
|
||||
user_admin.create_forms(['username', 'password'])
|
||||
|
||||
c=user_admin.select_count()
|
||||
|
||||
if c==0:
|
||||
return redirect(url_for('admin_app.signup'))
|
||||
|
||||
post={}
|
||||
|
||||
if request.method=='POST':
|
||||
|
||||
username=request.form['username']
|
||||
|
||||
password=request.form['password']
|
||||
|
||||
arr_user=user_admin.set_conditions('WHERE username=%s', [username]).select_a_row_where()
|
||||
|
||||
if arr_user:
|
||||
|
||||
if user_admin.fields['password'].verify(password, arr_user['password']):
|
||||
|
||||
session['login_admin']=True
|
||||
|
||||
return {'error': 0}
|
||||
|
||||
else:
|
||||
|
||||
return {'error': 1, 'csrf_token': generate_csrf()}
|
||||
else:
|
||||
|
||||
return {'error': 1, 'csrf_token': generate_csrf()}
|
||||
|
||||
#if
|
||||
|
||||
else:
|
||||
|
||||
forms=show_form(post, user_admin.forms, t, yes_error=False)
|
||||
|
||||
return t.load_template('login.phtml', forms=forms, yes_recovery_login=yes_recovery_login)
|
||||
|
||||
@admin_app.route('/admin/signup', methods=['GET', 'POST'])
|
||||
def signup():
|
||||
|
||||
user_admin=UserAdmin(g.connection)
|
||||
|
||||
c=user_admin.select_count()
|
||||
|
||||
if c==0:
|
||||
|
||||
if request.method=='POST':
|
||||
|
||||
user_admin.conditions=['WHERE privileges=%s', [2]]
|
||||
|
||||
forms=dict(request.form)
|
||||
|
||||
forms['privileges']=2
|
||||
|
||||
user_admin.valid_fields=['username', 'email', 'password', 'privileges']
|
||||
|
||||
user_admin.create_forms()
|
||||
|
||||
if user_admin.insert(forms, False):
|
||||
|
||||
|
||||
|
||||
error= {'error': 0}
|
||||
|
||||
return error
|
||||
|
||||
else:
|
||||
|
||||
user_admin.check_all_fields(forms, False)
|
||||
|
||||
pass_values_to_form(forms, user_admin.forms, yes_error=True)
|
||||
|
||||
session['csrf_token']=create_key_encrypt()
|
||||
|
||||
error={'error': 1, 'csrf_token': session['csrf_token']}
|
||||
|
||||
for field in user_admin.valid_fields:
|
||||
|
||||
error[field]=user_admin.forms[field].txt_error
|
||||
|
||||
error['repeat_password']=user_admin.forms['repeat_password'].txt_error
|
||||
|
||||
return error
|
||||
|
||||
else:
|
||||
|
||||
post={}
|
||||
|
||||
set_extra_forms_user(user_admin)
|
||||
|
||||
forms=show_form(post, user_admin.forms, t, yes_error=False)
|
||||
|
||||
return t.load_template('register.phtml', forms=forms)
|
||||
|
||||
else:
|
||||
|
||||
return redirect(url_for('.login'))
|
||||
|
||||
@admin_app.route('/admin/recovery_password')
|
||||
def recovery_password():
|
||||
|
||||
return ""
|
||||
899
paramecio2/modules/admin/media/css/admin.css
Normal file
|
|
@ -0,0 +1,899 @@
|
|||
|
||||
body
|
||||
{
|
||||
|
||||
margin:0px;
|
||||
background-color:#f7f6f1;
|
||||
font-family: "Roboto", sans, sans-serif, serif;
|
||||
font-size: 16px;
|
||||
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
|
||||
color: #1c6280;
|
||||
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
|
||||
color: #d54e21;
|
||||
|
||||
}
|
||||
|
||||
#header
|
||||
{
|
||||
|
||||
width:100%;
|
||||
height:52px;
|
||||
color:#000;
|
||||
font-size:22px;
|
||||
font-family:"Roboto", sans, serif;
|
||||
/*background-image:url('../images/background.png');
|
||||
background-position:top;
|
||||
background-repeat:repeat-x;*/
|
||||
background-color:#e1ebed;
|
||||
line-height: 47px;
|
||||
|
||||
}
|
||||
|
||||
#title_phango
|
||||
{
|
||||
font-size:28px;
|
||||
padding-left:15px;
|
||||
color: #555555;
|
||||
font-family:"Roboto", sans, serif;
|
||||
/*font-style:italic;*/
|
||||
/*text-shadow:#000000 1px 1px 1px;
|
||||
filter: progid:DXImageTransform.Microsoft.Shadow(color='#000000', Direction=130, Strength=4);*/
|
||||
|
||||
}
|
||||
|
||||
#title_framework
|
||||
{
|
||||
|
||||
font-size:28px;
|
||||
padding-right:15px;
|
||||
color:#ff9b2f;
|
||||
/*text-shadow:#000000 1px 1px 1px;
|
||||
filter: progid:DXImageTransform.Microsoft.Shadow(color='#000000', Direction=130, Strength=4);*/
|
||||
|
||||
}
|
||||
|
||||
h1, h2
|
||||
{
|
||||
|
||||
font-family:"Roboto", sans, serif;
|
||||
border: solid #cbcbcb;
|
||||
border-width: 0px 0px 1px 1px;
|
||||
font-size:26px;
|
||||
color:#333333;
|
||||
margin:0px 0px 20px 0px;
|
||||
padding:5px 10px;
|
||||
font-weight:normal;
|
||||
background: #e6e6e6;
|
||||
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
||||
font-size:20px;
|
||||
background: transparent;
|
||||
color: #000;
|
||||
padding: 0px;
|
||||
border-width:0px;
|
||||
margin: 4px 0px;
|
||||
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
||||
-webkit-box-shadow: 1px 1px 5px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 1px 1px 5px 0px rgba(0,0,0,0.75);
|
||||
box-shadow: 1px 1px 5px 0px rgba(0,0,0,0.75);
|
||||
font-size:20px;
|
||||
padding:3px 10px;
|
||||
font-weight: 600;
|
||||
|
||||
}
|
||||
|
||||
p {
|
||||
|
||||
border: solid #cbcbcb;
|
||||
margin-top:4px;
|
||||
border-width:0px;
|
||||
|
||||
}
|
||||
|
||||
#logo_header
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#center_body {
|
||||
|
||||
background-position:left;
|
||||
background-repeat:repeat-y;
|
||||
height: auto !important;
|
||||
width:100%;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
overflow:auto;
|
||||
height: auto !important;
|
||||
min-height:300px;
|
||||
position:relative;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#menu
|
||||
{
|
||||
|
||||
float:left;
|
||||
width:20%;
|
||||
margin-right:0px;
|
||||
position:relative;
|
||||
/* border:solid #cccccc;
|
||||
border-width:0px 1px 1px 0px;*/
|
||||
box-sizing: border-box;
|
||||
/* padding-bottom: 100px;*/
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
#menu a
|
||||
{
|
||||
|
||||
font-size:16px;
|
||||
/*font-family:arial, sans;*/
|
||||
text-decoration:none;
|
||||
color:#ededed;
|
||||
display:block;
|
||||
border:solid #cccccc;
|
||||
/*border-width:0px 1px 1px 1px;*/
|
||||
border-width:0px;
|
||||
padding:5px;
|
||||
padding-top:10px;
|
||||
padding-bottom:10px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#menu a:hover
|
||||
{
|
||||
|
||||
text-decoration:underline;
|
||||
color:#fbfbfb;
|
||||
background: #0fb1dd;
|
||||
text-decoration:none;
|
||||
|
||||
}
|
||||
|
||||
#menu a.sub_module
|
||||
{
|
||||
|
||||
color:#6183b1;
|
||||
background-color: #fbfbfb;
|
||||
text-decoration:none;
|
||||
|
||||
}
|
||||
|
||||
.menu_title
|
||||
{
|
||||
|
||||
padding:5px;
|
||||
font-size:18px;
|
||||
font-family:"Roboto", sans, serif;
|
||||
font-weight:bold;
|
||||
/*background-image:url('../images/background_title.png');
|
||||
background-position:top;
|
||||
background-repeat: repeat-x;*/
|
||||
background-color: #003c95;
|
||||
/*border:solid #cccccc;
|
||||
border-width:0px 1px 1px 1px;*/
|
||||
color: #fbfbfb;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.father_admin {
|
||||
|
||||
font-family:"Roboto", sans, serif;
|
||||
padding:5px;
|
||||
font-size:18px;
|
||||
display: block;
|
||||
color: #fbfbfb;
|
||||
font-weight:bold;
|
||||
background: #000;
|
||||
/*
|
||||
background: rgba(76,76,76,1);
|
||||
background: -moz-linear-gradient(top, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%);
|
||||
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(76,76,76,1)), color-stop(12%, rgba(89,89,89,1)), color-stop(25%, rgba(102,102,102,1)), color-stop(39%, rgba(71,71,71,1)), color-stop(50%, rgba(44,44,44,1)), color-stop(51%, rgba(0,0,0,1)), color-stop(60%, rgba(17,17,17,1)), color-stop(76%, rgba(43,43,43,1)), color-stop(91%, rgba(28,28,28,1)), color-stop(100%, rgba(19,19,19,1)));
|
||||
background: -webkit-linear-gradient(top, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%);
|
||||
background: -o-linear-gradient(top, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%);
|
||||
background: -ms-linear-gradient(top, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%);
|
||||
background: linear-gradient(to bottom, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313', GradientType=0 );*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
#menu ul {
|
||||
|
||||
margin:0px;
|
||||
/*border: solid #000 1px;*/
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
#menu li {
|
||||
|
||||
border-width: 0px;
|
||||
|
||||
}
|
||||
|
||||
.content_admin
|
||||
{
|
||||
|
||||
margin:auto;
|
||||
background: rgba(18,47,59,1);
|
||||
background: -moz-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: -webkit-gradient(left top, right top, color-stop(0%, rgba(18,47,59,1)), color-stop(51%, rgba(18,47,59,1)), color-stop(74%, rgba(18,47,59,1)), color-stop(100%, rgba(8,59,77,1)));
|
||||
background: -webkit-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: -o-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: -ms-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: linear-gradient(to right, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background-size: 20% 100%;
|
||||
background-repeat:no-repeat;
|
||||
padding:0px;
|
||||
border:solid #bcbcbc;
|
||||
border-width: 0px;
|
||||
font-size:16px;
|
||||
position:relative;
|
||||
overflow:auto;
|
||||
border: solid #cbcbcb;
|
||||
border-width: 0px 0px 1px 0px;
|
||||
min-height: 90vh;
|
||||
}
|
||||
|
||||
.content_admin i {
|
||||
|
||||
margin-right: 10px;
|
||||
|
||||
}
|
||||
|
||||
.contents
|
||||
{
|
||||
float:right;
|
||||
width:80%;
|
||||
padding:0px 0px 0px 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.content
|
||||
{
|
||||
padding:0px 10px 5px 10px;
|
||||
/*border: solid #000 1px;*/
|
||||
|
||||
}
|
||||
|
||||
.title
|
||||
{
|
||||
|
||||
font-size:18px;
|
||||
font-weight:bold;
|
||||
font-family:helvetica, sans;
|
||||
text-decoration:none;
|
||||
color:#fbfbfb;
|
||||
padding:5px;
|
||||
/*background-image:url('../images/background_title.png');
|
||||
background-position:top;
|
||||
background-repeat: repeat-x;*/
|
||||
background-color: #337ab7;
|
||||
border-radius: 8px 8px 0px 0px;
|
||||
border:solid #337ab7;
|
||||
border-width:1px 0px 1px 0px;
|
||||
margin-top:8px;
|
||||
}
|
||||
|
||||
#inform {
|
||||
|
||||
margin:auto;
|
||||
|
||||
}
|
||||
|
||||
/*Styles for common templates...*/
|
||||
|
||||
.form {
|
||||
|
||||
border: solid #cbcbcb 1px;
|
||||
padding:10px;
|
||||
margin:10px 0px 10px 0px;
|
||||
border-radius:5px;
|
||||
|
||||
}
|
||||
|
||||
.form textarea {
|
||||
|
||||
width:100%;
|
||||
height:200px;
|
||||
|
||||
}
|
||||
|
||||
.form label {
|
||||
display: block;
|
||||
/*width: 150px;*/
|
||||
float: left;
|
||||
margin-bottom: 20px;
|
||||
text-align: left;
|
||||
width: 350px;
|
||||
padding-right: 20px;
|
||||
/*border: #000000 solid;
|
||||
border-width:1px;*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.form p {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
display:block;
|
||||
|
||||
}
|
||||
|
||||
.panel {
|
||||
|
||||
display:block;
|
||||
float:left;
|
||||
/*clear:left;*/
|
||||
text-align:center;
|
||||
border: #000000 solid;
|
||||
border-width:0px;
|
||||
min-width:200px;
|
||||
width:200px !important;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
min-height:100px;
|
||||
height:100px !important;
|
||||
position:relative;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.panel p {
|
||||
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
/*padding-bottom:0px;*/
|
||||
text-align:center;
|
||||
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
|
||||
}
|
||||
|
||||
.panel img {
|
||||
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
|
||||
}
|
||||
|
||||
.table_list {
|
||||
|
||||
width:100%;
|
||||
border:solid #cccccc;
|
||||
border-width:1px;
|
||||
margin:0px;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
|
||||
.title_list td, .fields_span_title {
|
||||
|
||||
margin:0px;
|
||||
padding:4px;
|
||||
/*background-image:url('../images/background_title.png');
|
||||
background-position:top;
|
||||
background-repeat: repeat-x;*/
|
||||
background: #ccc;
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
box-sizing: border-box;
|
||||
/*border: solid #000 1px;*/
|
||||
|
||||
}
|
||||
|
||||
.fields_span_title, div.options_td , div.fields_span_table_data {
|
||||
|
||||
box-sizing: border-box;
|
||||
display:inline-block;
|
||||
float:left;
|
||||
/*margin-top:4px;*/
|
||||
/*border: solid #000 1px;*/
|
||||
}
|
||||
|
||||
.tr_list_div , div.fields_span_table_data {
|
||||
|
||||
margin-top:4px;
|
||||
margin-left: 4px;
|
||||
margin-right: 2px;
|
||||
|
||||
}
|
||||
|
||||
.row_list td, div.fields_span_table_data {
|
||||
|
||||
/*border:solid #cccccc;
|
||||
border-width:1px;*/
|
||||
padding:4px;
|
||||
|
||||
}
|
||||
|
||||
div.fields_span_table_data {
|
||||
|
||||
box-sizing: border-box;
|
||||
margin: 0px;
|
||||
|
||||
}
|
||||
|
||||
.cont_text, .cont
|
||||
{
|
||||
|
||||
margin:auto;
|
||||
background-color:#ffffff;
|
||||
padding:10px 10px 10px 10px;
|
||||
border:solid #cbcbcb;
|
||||
border-width: 0px 1px 1px 1px;
|
||||
font-size:14px;
|
||||
position:relative;
|
||||
overflow:auto;
|
||||
margin-bottom:10px;
|
||||
border-radius: 0px 0px 5px 5px;
|
||||
|
||||
}
|
||||
|
||||
.cont_top {
|
||||
|
||||
border-width: 1px 1px 1px 1px;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
.search {
|
||||
|
||||
border-width: 1px;
|
||||
border-radius:5px;
|
||||
margin-top:5px;
|
||||
|
||||
}
|
||||
|
||||
.right_cont
|
||||
{
|
||||
|
||||
width:78%;
|
||||
|
||||
}
|
||||
|
||||
.none_cont
|
||||
{
|
||||
|
||||
/*width:100%;*/
|
||||
|
||||
}
|
||||
|
||||
.contview
|
||||
{
|
||||
|
||||
border:solid #cccccc;
|
||||
border-width:1px 1px 1px 1px;
|
||||
padding:15px;
|
||||
margin: 0px 0px 5px 0px;
|
||||
|
||||
}
|
||||
|
||||
.error
|
||||
{
|
||||
|
||||
color: #ff0000;
|
||||
font-weight:bold;
|
||||
|
||||
}
|
||||
|
||||
.hidden_form
|
||||
{
|
||||
|
||||
display: none;
|
||||
/*clear:left;*/
|
||||
|
||||
}
|
||||
|
||||
.no_hidden_form
|
||||
{
|
||||
|
||||
display: inline;
|
||||
/*float:left;
|
||||
clear:left right;*/
|
||||
|
||||
}
|
||||
|
||||
a.no_choose_flag
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=50);
|
||||
-moz-opacity: .5;
|
||||
opacity: .5;
|
||||
display:inline-block;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
a.choose_flag
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=100);
|
||||
-moz-opacity: 100;
|
||||
opacity: 1;
|
||||
display:inline-block;
|
||||
margin: 0px;
|
||||
|
||||
}
|
||||
|
||||
a:hover.no_choose_flag
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=100);
|
||||
-moz-opacity: 100;
|
||||
opacity: 1;
|
||||
|
||||
}
|
||||
|
||||
#languages
|
||||
{
|
||||
width:100%;
|
||||
clear:left;
|
||||
|
||||
}
|
||||
|
||||
/** input **/
|
||||
|
||||
#center_body input {
|
||||
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
background: #eeeeee;
|
||||
|
||||
}
|
||||
|
||||
#center_body input:hover {
|
||||
|
||||
background: #fafafa;
|
||||
|
||||
}
|
||||
|
||||
#center_body input[type="submit"], #center_body input[type="button"]
|
||||
{
|
||||
|
||||
font-family: helvetica, arial,sans;
|
||||
font-size:16px;
|
||||
border-radius:5px;
|
||||
border: solid #205081 1px;
|
||||
background: #205081;
|
||||
padding: 5px 10px 5px 10px;
|
||||
font-weight:bold;
|
||||
color: #fbfbfb;
|
||||
|
||||
}
|
||||
|
||||
#center_body input[type="button"]
|
||||
{
|
||||
|
||||
background: #f0ad4e;
|
||||
border: solid #f0ad4e 1px;
|
||||
|
||||
}
|
||||
|
||||
#center_body input:hover[type="submit"]
|
||||
{
|
||||
|
||||
background: #104070;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
#center_body input:hover[type="button"]
|
||||
{
|
||||
|
||||
background: #d09c3d;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
#center_body input[type="text"]
|
||||
{
|
||||
|
||||
width:500px;
|
||||
|
||||
}
|
||||
|
||||
#center_body textarea {
|
||||
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
|
||||
}
|
||||
|
||||
#center_body select {
|
||||
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
|
||||
}
|
||||
|
||||
#languages_general, #logout
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
margin: 0px 0px 0px 0px;
|
||||
top:54px;
|
||||
z-index:3;
|
||||
right:0px;
|
||||
width:50px;
|
||||
|
||||
}
|
||||
|
||||
#languages_general {
|
||||
|
||||
top:8px;
|
||||
right:5px;
|
||||
height:10px;
|
||||
|
||||
}
|
||||
|
||||
#logout
|
||||
{
|
||||
|
||||
top:8px;
|
||||
right:10px;
|
||||
width:55px;
|
||||
font-weight:bold;
|
||||
font-size:10px;
|
||||
text-decoration: none;
|
||||
/*border: solid #000 1px;*/
|
||||
}
|
||||
|
||||
#logout a {
|
||||
|
||||
text-decoration: none;
|
||||
|
||||
}
|
||||
|
||||
a.no_choose_flag_general
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=50);
|
||||
-moz-opacity: .5;
|
||||
opacity: .5;
|
||||
float:left;
|
||||
margin: 2px;
|
||||
|
||||
}
|
||||
|
||||
a.choose_flag_general
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=100);
|
||||
-moz-opacity: 100;
|
||||
opacity: 100;
|
||||
float:left;
|
||||
margin: 2px;
|
||||
|
||||
}
|
||||
|
||||
a:hover.no_choose_flag_general
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=100);
|
||||
-moz-opacity: 100;
|
||||
opacity: 100;
|
||||
float:left;
|
||||
margin: 2px;
|
||||
|
||||
}
|
||||
|
||||
a.form_button_tab, a.form_button_tab_selected
|
||||
{
|
||||
|
||||
border: solid #121212 1px;
|
||||
border-radius:10px;
|
||||
padding:10px;
|
||||
display:inline-block;
|
||||
text-decoration:none;
|
||||
color:#fbfbfb;
|
||||
background: #000;
|
||||
|
||||
}
|
||||
|
||||
a.form_button_tab_selected
|
||||
{
|
||||
|
||||
background:#fbfbfb;
|
||||
color: #000;
|
||||
|
||||
}
|
||||
|
||||
a.form_button_tab:hover
|
||||
{
|
||||
|
||||
|
||||
color:#000;
|
||||
background:#fbfbfb;
|
||||
|
||||
}
|
||||
|
||||
.flash
|
||||
{
|
||||
border-radius:15px;
|
||||
margin-top:15px;
|
||||
padding:25px;
|
||||
color:#fbfbfb;
|
||||
text-shadow:#000000 1px 1px 1px;
|
||||
filter: progid:DXImageTransform.Microsoft.Shadow(color='#000000', Direction=130, Strength=4);
|
||||
|
||||
background: #ff3019; /* Old browsers */
|
||||
background: -moz-linear-gradient(top, #ff3019 0%, #cf0404 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff3019), color-stop(100%,#cf0404)); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, #ff3019 0%,#cf0404 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, #ff3019 0%,#cf0404 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, #ff3019 0%,#cf0404 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, #ff3019 0%,#cf0404 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff3019', endColorstr='#cf0404',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
}
|
||||
|
||||
#toggle {
|
||||
|
||||
position:absolute;
|
||||
left:10px;
|
||||
top:0px;
|
||||
z-index:1;
|
||||
display:none;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#toggle span {
|
||||
|
||||
display:none;
|
||||
|
||||
}
|
||||
|
||||
.first_canvas {
|
||||
|
||||
width:48%;
|
||||
float:right;
|
||||
|
||||
}
|
||||
|
||||
.other_canvas {
|
||||
|
||||
width:48%;
|
||||
float:left;
|
||||
|
||||
}
|
||||
|
||||
.my_arrow_right {
|
||||
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
||||
.little_textarea {
|
||||
|
||||
height: 50px !important;
|
||||
|
||||
}
|
||||
|
||||
/* Media queries */
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
|
||||
.content_admin {
|
||||
|
||||
background: transparent;
|
||||
|
||||
}
|
||||
|
||||
#toggle {
|
||||
|
||||
display:block;
|
||||
|
||||
}
|
||||
|
||||
#toggle span {
|
||||
|
||||
display:none;
|
||||
|
||||
}
|
||||
|
||||
.contents {
|
||||
|
||||
width:100%;
|
||||
|
||||
}
|
||||
|
||||
#menu {
|
||||
|
||||
width:100%;
|
||||
|
||||
}
|
||||
|
||||
#menu a {
|
||||
|
||||
background: rgba(18,47,59,1);
|
||||
background: -moz-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: -webkit-gradient(left top, right top, color-stop(0%, rgba(18,47,59,1)), color-stop(51%, rgba(18,47,59,1)), color-stop(74%, rgba(18,47,59,1)), color-stop(100%, rgba(8,59,77,1)));
|
||||
background: -webkit-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: -o-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: -ms-linear-gradient(left, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
background: linear-gradient(to right, rgba(18,47,59,1) 0%, rgba(18,47,59,1) 51%, rgba(18,47,59,1) 74%, rgba(8,59,77,1) 100%);
|
||||
|
||||
}
|
||||
|
||||
#title_phango
|
||||
{
|
||||
font-size:18px;
|
||||
text-align:center;
|
||||
color: #555555;
|
||||
border: solid #000 0px;
|
||||
}
|
||||
|
||||
#title_framework
|
||||
{
|
||||
|
||||
display:none;
|
||||
|
||||
}
|
||||
|
||||
#header {
|
||||
|
||||
text-align:center;
|
||||
|
||||
}
|
||||
|
||||
.ip_td {
|
||||
|
||||
display:none;
|
||||
|
||||
}
|
||||
|
||||
.num_updates_td {
|
||||
|
||||
display:none;
|
||||
|
||||
}
|
||||
|
||||
.first_canvas {
|
||||
|
||||
width:100%;
|
||||
clear:both;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.other_canvas {
|
||||
|
||||
width:100%;
|
||||
clear:both;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
4
paramecio2/modules/admin/media/css/font-awesome.min.css
vendored
Normal file
142
paramecio2/modules/admin/media/css/login.css
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
body {
|
||||
|
||||
margin:0px;
|
||||
background: #fbfbfb;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
|
||||
}
|
||||
|
||||
#title {
|
||||
|
||||
padding:10px;
|
||||
color: #fbfbfb;
|
||||
background: #ff7153 url("../images/background_title_login.png") right no-repeat;
|
||||
font-size:1.5em;
|
||||
/*text-shadow: 1px 1px 0px rgba(0, 0, 0, 1);*/
|
||||
|
||||
}
|
||||
|
||||
.form {
|
||||
|
||||
margin:10px 15px 10px 10px;
|
||||
position:relative;
|
||||
|
||||
}
|
||||
|
||||
input[type="text"], input[type="password"] {
|
||||
|
||||
width:100%;
|
||||
border: solid #bcbcbc 1px;
|
||||
font-size:2em;
|
||||
border-radius:5px;
|
||||
padding:2px;
|
||||
|
||||
}
|
||||
|
||||
input:focus {
|
||||
|
||||
border-color: #FF7052;
|
||||
outline:1px;
|
||||
|
||||
}
|
||||
|
||||
.submit {
|
||||
|
||||
width:250px;
|
||||
display: block;
|
||||
margin: 0 auto 18px auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #FF7052;
|
||||
color: #FF7052;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 0px 0px 7px #fff;
|
||||
transition: 0.2s ease-out;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.submit:hover,
|
||||
.submit:focus {
|
||||
background: #FF7052;
|
||||
color: #fff;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.error {
|
||||
|
||||
font-weight:bold;
|
||||
color: #ff0000;
|
||||
|
||||
}
|
||||
|
||||
#submit_block {
|
||||
|
||||
position:relative;
|
||||
|
||||
}
|
||||
|
||||
#loading {
|
||||
|
||||
top:10px;
|
||||
right:40px;
|
||||
position:absolute;
|
||||
display:block;
|
||||
width:16px;
|
||||
height:16px;
|
||||
border: solid #000 0px;
|
||||
background: url('../images/ajax-loader.gif') center no-repeat;
|
||||
display:none;
|
||||
|
||||
}
|
||||
|
||||
/* Phones */
|
||||
@media (max-width: 767px) {
|
||||
|
||||
#login {
|
||||
|
||||
width:100%;
|
||||
border: solid #cbcbcb;
|
||||
border-width:0px 0px 1px 0px;
|
||||
margin-top:5px;
|
||||
margin:0px;
|
||||
overflow:hidden;
|
||||
background: #eaeaea;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Tablets */
|
||||
@media (min-width: 780px) and (max-width: 979px) {
|
||||
|
||||
#login {
|
||||
|
||||
position:relative;
|
||||
width:400px;
|
||||
border: solid #cbcbcb 1px;
|
||||
margin-top:5px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
overflow:hidden;
|
||||
background: #eaeaea;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktops */
|
||||
@media (min-width: 980px) {
|
||||
|
||||
#login {
|
||||
|
||||
position:relative;
|
||||
width:400px;
|
||||
border: solid #cbcbcb 1px;
|
||||
margin-top:5px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
overflow:hidden;
|
||||
background: #eaeaea;
|
||||
}
|
||||
|
||||
}
|
||||
49
paramecio2/modules/admin/media/css/responsive-nav.css
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*! responsive-nav.js 1.0.39 by @viljamis */
|
||||
|
||||
.nav-collapse ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
display: block;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nav-collapse li {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.js .nav-collapse {
|
||||
clip: rect(0 0 0 0);
|
||||
max-height: 0;
|
||||
position: absolute;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.nav-collapse.opened {
|
||||
max-height: 9999px;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 40em) {
|
||||
.js .nav-collapse {
|
||||
position: relative;
|
||||
}
|
||||
.js .nav-collapse.closed {
|
||||
max-height: none;
|
||||
}
|
||||
.nav-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
507
paramecio2/modules/admin/media/css/spectrum.css
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
/***
|
||||
Spectrum Colorpicker v1.8.0
|
||||
https://github.com/bgrins/spectrum
|
||||
Author: Brian Grinstead
|
||||
License: MIT
|
||||
***/
|
||||
|
||||
.sp-container {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
display:inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
/* https://github.com/bgrins/spectrum/issues/40 */
|
||||
z-index: 9999994;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sp-container.sp-flat {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Fix for * { box-sizing: border-box; } */
|
||||
.sp-container,
|
||||
.sp-container * {
|
||||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
|
||||
.sp-top {
|
||||
position:relative;
|
||||
width: 100%;
|
||||
display:inline-block;
|
||||
}
|
||||
.sp-top-inner {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
bottom:0;
|
||||
right:0;
|
||||
}
|
||||
.sp-color {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
bottom:0;
|
||||
right:20%;
|
||||
}
|
||||
.sp-hue {
|
||||
position: absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:84%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sp-clear-enabled .sp-hue {
|
||||
top:33px;
|
||||
height: 77.5%;
|
||||
}
|
||||
|
||||
.sp-fill {
|
||||
padding-top: 80%;
|
||||
}
|
||||
.sp-sat, .sp-val {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
}
|
||||
|
||||
.sp-alpha-enabled .sp-top {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.sp-alpha-enabled .sp-alpha {
|
||||
display: block;
|
||||
}
|
||||
.sp-alpha-handle {
|
||||
position:absolute;
|
||||
top:-4px;
|
||||
bottom: -4px;
|
||||
width: 6px;
|
||||
left: 50%;
|
||||
cursor: pointer;
|
||||
border: 1px solid black;
|
||||
background: white;
|
||||
opacity: .8;
|
||||
}
|
||||
.sp-alpha {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: -14px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 8px;
|
||||
}
|
||||
.sp-alpha-inner {
|
||||
border: solid 1px #333;
|
||||
}
|
||||
|
||||
.sp-clear {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sp-clear.sp-clear-display {
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.sp-clear-enabled .sp-clear {
|
||||
display: block;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:84%;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
/* Don't allow text selection */
|
||||
.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
|
||||
-webkit-user-select:none;
|
||||
-moz-user-select: -moz-none;
|
||||
-o-user-select:none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.sp-container.sp-input-disabled .sp-input-container {
|
||||
display: none;
|
||||
}
|
||||
.sp-container.sp-buttons-disabled .sp-button-container {
|
||||
display: none;
|
||||
}
|
||||
.sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
|
||||
display: none;
|
||||
}
|
||||
.sp-palette-only .sp-picker-container {
|
||||
display: none;
|
||||
}
|
||||
.sp-palette-disabled .sp-palette-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sp-initial-disabled .sp-initial {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
|
||||
.sp-sat {
|
||||
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
|
||||
background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
|
||||
background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
|
||||
background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
|
||||
background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
|
||||
background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
|
||||
filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
|
||||
}
|
||||
.sp-val {
|
||||
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
|
||||
background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
|
||||
background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
|
||||
background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
|
||||
background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
|
||||
background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
|
||||
filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
|
||||
}
|
||||
|
||||
.sp-hue {
|
||||
background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
||||
background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
||||
background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
|
||||
background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
||||
background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
||||
}
|
||||
|
||||
/* IE filters do not support multiple color stops.
|
||||
Generate 6 divs, line them up, and do two color gradients for each.
|
||||
Yes, really.
|
||||
*/
|
||||
.sp-1 {
|
||||
height:17%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
|
||||
}
|
||||
.sp-2 {
|
||||
height:16%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
|
||||
}
|
||||
.sp-3 {
|
||||
height:17%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
|
||||
}
|
||||
.sp-4 {
|
||||
height:17%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
|
||||
}
|
||||
.sp-5 {
|
||||
height:16%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
|
||||
}
|
||||
.sp-6 {
|
||||
height:17%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
|
||||
}
|
||||
|
||||
.sp-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Clearfix hack */
|
||||
.sp-cf:before, .sp-cf:after { content: ""; display: table; }
|
||||
.sp-cf:after { clear: both; }
|
||||
.sp-cf { *zoom: 1; }
|
||||
|
||||
/* Mobile devices, make hue slider bigger so it is easier to slide */
|
||||
@media (max-device-width: 480px) {
|
||||
.sp-color { right: 40%; }
|
||||
.sp-hue { left: 63%; }
|
||||
.sp-fill { padding-top: 60%; }
|
||||
}
|
||||
.sp-dragger {
|
||||
border-radius: 5px;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
border: 1px solid #fff;
|
||||
background: #000;
|
||||
cursor: pointer;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left: 0;
|
||||
}
|
||||
.sp-slider {
|
||||
position: absolute;
|
||||
top:0;
|
||||
cursor:pointer;
|
||||
height: 3px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
border: 1px solid #000;
|
||||
background: white;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
/*
|
||||
Theme authors:
|
||||
Here are the basic themeable display options (colors, fonts, global widths).
|
||||
See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
*/
|
||||
|
||||
.sp-container {
|
||||
border-radius: 0;
|
||||
background-color: #ECECEC;
|
||||
border: solid 1px #f0c49B;
|
||||
padding: 0;
|
||||
}
|
||||
.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
|
||||
font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.sp-top {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.sp-color, .sp-hue, .sp-clear {
|
||||
border: solid 1px #666;
|
||||
}
|
||||
|
||||
/* Input */
|
||||
.sp-input-container {
|
||||
float:right;
|
||||
width: 100px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.sp-initial-disabled .sp-input-container {
|
||||
width: 100%;
|
||||
}
|
||||
.sp-input {
|
||||
font-size: 12px !important;
|
||||
border: 1px inset;
|
||||
padding: 4px 5px;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
background:transparent;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
}
|
||||
.sp-input:focus {
|
||||
border: 1px solid orange;
|
||||
}
|
||||
.sp-input.sp-validation-error {
|
||||
border: 1px solid red;
|
||||
background: #fdd;
|
||||
}
|
||||
.sp-picker-container , .sp-palette-container {
|
||||
float:left;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
padding-bottom: 300px;
|
||||
margin-bottom: -290px;
|
||||
}
|
||||
.sp-picker-container {
|
||||
width: 172px;
|
||||
border-left: solid 1px #fff;
|
||||
}
|
||||
|
||||
/* Palettes */
|
||||
.sp-palette-container {
|
||||
border-right: solid 1px #ccc;
|
||||
}
|
||||
|
||||
.sp-palette-only .sp-palette-container {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.sp-palette .sp-thumb-el {
|
||||
display: block;
|
||||
position:relative;
|
||||
float:left;
|
||||
width: 24px;
|
||||
height: 15px;
|
||||
margin: 3px;
|
||||
cursor: pointer;
|
||||
border:solid 2px transparent;
|
||||
}
|
||||
.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
|
||||
border-color: orange;
|
||||
}
|
||||
.sp-thumb-el {
|
||||
position:relative;
|
||||
}
|
||||
|
||||
/* Initial */
|
||||
.sp-initial {
|
||||
float: left;
|
||||
border: solid 1px #333;
|
||||
}
|
||||
.sp-initial span {
|
||||
width: 30px;
|
||||
height: 25px;
|
||||
border:none;
|
||||
display:block;
|
||||
float:left;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.sp-initial .sp-clear-display {
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.sp-palette-button-container,
|
||||
.sp-button-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Replacer (the little preview div that shows up instead of the <input>) */
|
||||
.sp-replacer {
|
||||
margin:0;
|
||||
overflow:hidden;
|
||||
cursor:pointer;
|
||||
padding: 4px;
|
||||
display:inline-block;
|
||||
*zoom: 1;
|
||||
*display: inline;
|
||||
border: solid 1px #91765d;
|
||||
background: #eee;
|
||||
color: #333;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.sp-replacer:hover, .sp-replacer.sp-active {
|
||||
border-color: #F0C49B;
|
||||
color: #111;
|
||||
}
|
||||
.sp-replacer.sp-disabled {
|
||||
cursor:default;
|
||||
border-color: silver;
|
||||
color: silver;
|
||||
}
|
||||
.sp-dd {
|
||||
padding: 2px 0;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
float:left;
|
||||
font-size:10px;
|
||||
}
|
||||
.sp-preview {
|
||||
position:relative;
|
||||
width:25px;
|
||||
height: 20px;
|
||||
border: solid 1px #222;
|
||||
margin-right: 5px;
|
||||
float:left;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.sp-palette {
|
||||
*width: 220px;
|
||||
max-width: 220px;
|
||||
}
|
||||
.sp-palette .sp-thumb-el {
|
||||
width:16px;
|
||||
height: 16px;
|
||||
margin:2px 1px;
|
||||
border: solid 1px #d0d0d0;
|
||||
}
|
||||
|
||||
.sp-container {
|
||||
padding-bottom:0;
|
||||
}
|
||||
|
||||
|
||||
/* Buttons: http://hellohappy.org/css3-buttons/ */
|
||||
.sp-container button {
|
||||
background-color: #eeeeee;
|
||||
background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
|
||||
background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
|
||||
background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
|
||||
background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
|
||||
border: 1px solid #ccc;
|
||||
border-bottom: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
padding: 5px 4px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #eee;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.sp-container button:hover {
|
||||
background-color: #dddddd;
|
||||
background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
|
||||
background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
|
||||
background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
|
||||
background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
|
||||
background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
|
||||
border: 1px solid #bbb;
|
||||
border-bottom: 1px solid #999;
|
||||
cursor: pointer;
|
||||
text-shadow: 0 1px 0 #ddd;
|
||||
}
|
||||
.sp-container button:active {
|
||||
border: 1px solid #aaa;
|
||||
border-bottom: 1px solid #888;
|
||||
-webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
||||
-moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
||||
-ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
||||
-o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
||||
box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
||||
}
|
||||
.sp-cancel {
|
||||
font-size: 11px;
|
||||
color: #d93f3f !important;
|
||||
margin:0;
|
||||
padding:2px;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
text-decoration:none;
|
||||
|
||||
}
|
||||
.sp-cancel:hover {
|
||||
color: #d93f3f !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
.sp-palette span:hover, .sp-palette span.sp-thumb-active {
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.sp-preview, .sp-alpha, .sp-thumb-el {
|
||||
position:relative;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
||||
}
|
||||
.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
|
||||
display:block;
|
||||
position:absolute;
|
||||
top:0;left:0;bottom:0;right:0;
|
||||
}
|
||||
|
||||
.sp-palette .sp-thumb-inner {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
|
||||
}
|
||||
|
||||
.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
|
||||
}
|
||||
|
||||
.sp-clear-display {
|
||||
background-repeat:no-repeat;
|
||||
background-position: center;
|
||||
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
|
||||
}
|
||||
902
paramecio2/modules/admin/media/css/style.css
Normal file
|
|
@ -0,0 +1,902 @@
|
|||
/* General styles */
|
||||
|
||||
body
|
||||
{
|
||||
|
||||
margin:0px;
|
||||
background:url('../images/background.png') repeat-y center #e0e5e6;
|
||||
|
||||
}
|
||||
|
||||
iframe
|
||||
{
|
||||
|
||||
width:100%;
|
||||
border:solid #5b5b5b;
|
||||
border-width:1px;
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
|
||||
font-size:12px;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:none;
|
||||
color: #3434cc;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
|
||||
font-size:12px;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:underline;
|
||||
color: #4545dd;
|
||||
font-weight:bold;
|
||||
|
||||
}
|
||||
|
||||
strong
|
||||
{
|
||||
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
/*display:block;*/
|
||||
|
||||
}
|
||||
|
||||
/** center_body is the principal class **/
|
||||
|
||||
#center_body {
|
||||
|
||||
position:relative;
|
||||
height: auto !important;
|
||||
width:958px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
overflow:auto;
|
||||
height: auto !important;
|
||||
min-height:600px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** input **/
|
||||
|
||||
#center_body input {
|
||||
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
height:20px;
|
||||
border-radius:5px;
|
||||
background: #eeeeee;
|
||||
|
||||
}
|
||||
|
||||
#center_body input:hover {
|
||||
|
||||
background: #fafafa;
|
||||
|
||||
}
|
||||
|
||||
#center_body input[type="submit"]
|
||||
{
|
||||
|
||||
font-family: verdana,arial,sans;
|
||||
font-size:12px;
|
||||
height:25px;
|
||||
border-radius:25px;
|
||||
background: #eee;
|
||||
|
||||
}
|
||||
|
||||
#center_body input:hover[type="submit"]
|
||||
{
|
||||
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
|
||||
#center_body textarea {
|
||||
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
|
||||
}
|
||||
|
||||
#center_body select {
|
||||
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
|
||||
}
|
||||
|
||||
/* header elements classes */
|
||||
|
||||
#header
|
||||
{
|
||||
|
||||
width:952px;
|
||||
border:solid #000000;
|
||||
border-width:0px;
|
||||
border-right-width:0px;
|
||||
padding-left:5px;
|
||||
color: #676767;
|
||||
text-align:middle;
|
||||
height:120px;
|
||||
margin-bottom:4px;
|
||||
line-height: 35px;
|
||||
|
||||
}
|
||||
|
||||
#header a
|
||||
{
|
||||
|
||||
color: #555555;
|
||||
|
||||
}
|
||||
|
||||
#logo_img
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
top:20px;
|
||||
left:0px;
|
||||
|
||||
}
|
||||
|
||||
#your_account
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
top:25px;
|
||||
right:5px;
|
||||
background-image: url('../images/my-account.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position:left;
|
||||
padding-left:25px;
|
||||
|
||||
}
|
||||
|
||||
#cart
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
top:50px;
|
||||
right:5px;
|
||||
background-image: url('../images/cart.gif');
|
||||
background-repeat: no-repeat;
|
||||
background-position:left;
|
||||
padding-left:25px;
|
||||
font-size:12px;
|
||||
|
||||
}
|
||||
|
||||
#change_currency
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
top:70px;
|
||||
right:5px;
|
||||
background-image: url('../images/currency.gif');
|
||||
background-repeat: no-repeat;
|
||||
background-position:left;
|
||||
padding-left:25px;
|
||||
font-size:12px;
|
||||
|
||||
}
|
||||
|
||||
/* Languages styles in header. */
|
||||
|
||||
#languages
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
margin: 0px 0px 0px 0px;
|
||||
top:10px;
|
||||
right:5px;
|
||||
/*right:50px;*/
|
||||
|
||||
}
|
||||
|
||||
a.no_choose_flag
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=50);
|
||||
-moz-opacity: .5;
|
||||
opacity: .5;
|
||||
|
||||
}
|
||||
|
||||
a.choose_flag
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=100);
|
||||
-moz-opacity: 100;
|
||||
opacity: 100;
|
||||
|
||||
}
|
||||
|
||||
a:hover.no_choose_flag
|
||||
{
|
||||
|
||||
filter: Alpha(opacity=100);
|
||||
-moz-opacity: 100;
|
||||
opacity: 100;
|
||||
|
||||
}
|
||||
|
||||
#menu_barr
|
||||
{
|
||||
|
||||
height:40px;
|
||||
background-image:url('../images/background_barr.png');
|
||||
background-repeat: repeat-x;
|
||||
border:solid #cbcbcb;
|
||||
border-width:1px;
|
||||
border-radius:8px;
|
||||
text-align:center;
|
||||
font-size:16px;
|
||||
line-height:40px;
|
||||
margin-bottom:18px;
|
||||
|
||||
}
|
||||
|
||||
#menu_barr a
|
||||
{
|
||||
|
||||
font-size:16px;
|
||||
|
||||
}
|
||||
|
||||
/* Menus in left and right sides... */
|
||||
|
||||
#menu
|
||||
{
|
||||
|
||||
|
||||
width:175px;
|
||||
/*border:solid #ffffff;
|
||||
border-width:5px;*/
|
||||
margin:0px 0px 5px 0px;
|
||||
padding:0px;
|
||||
|
||||
}
|
||||
|
||||
#menu a
|
||||
{
|
||||
|
||||
font-size:14px;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:none;
|
||||
color: #3434cc;
|
||||
font-weight:bold;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
#menu a:hover
|
||||
{
|
||||
|
||||
font-size:14px;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:underline;
|
||||
color: #4545dd;
|
||||
padding:5px;
|
||||
|
||||
}
|
||||
|
||||
.title_block
|
||||
{
|
||||
|
||||
font-size:20px;
|
||||
font-weight:normal;
|
||||
font-family:verdana;
|
||||
text-decoration:none;
|
||||
color: #fff;
|
||||
background-image:url('../images/block_bg.png');
|
||||
background-repeat:repeat-x;
|
||||
background-position:bottom;
|
||||
background-color:#4e8df6;
|
||||
border:solid #256753;
|
||||
border-width:1px;
|
||||
padding:8px 4px 0px 8px;
|
||||
margin:0px;
|
||||
position:relative;
|
||||
height:40px;
|
||||
border-radius: 8px 8px 0px 0px;
|
||||
|
||||
}
|
||||
|
||||
.url_block
|
||||
{
|
||||
|
||||
font-size:12px;
|
||||
font-family:verdana;
|
||||
text-decoration:none;
|
||||
color: #676767;
|
||||
border:solid #cbcbcb;
|
||||
border-width:0px 1px 0px 1px;
|
||||
padding:8px 4px 8px 4px;
|
||||
margin:0px;
|
||||
position:relative;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.static_block
|
||||
{
|
||||
|
||||
font-size:12px;
|
||||
font-family:verdana;
|
||||
text-decoration:none;
|
||||
color: #676767;
|
||||
/*background-image:url('../images/block_bg_link.png');*/
|
||||
border:solid #cbcbcb;
|
||||
border-width:0px 1px 0px 1px;
|
||||
padding:4px;
|
||||
margin:0px;
|
||||
position:relative;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.block_end
|
||||
{
|
||||
|
||||
background-image:url('../images/block_end.png');
|
||||
height:15px;
|
||||
border:solid #cbcbcb;
|
||||
border-width:0px 1px 1px 1px;
|
||||
border-radius:0px 0px 5px 5px;
|
||||
margin-bottom:5px;
|
||||
|
||||
}
|
||||
|
||||
.link_menu a
|
||||
{
|
||||
|
||||
color:#ff0000;
|
||||
|
||||
}
|
||||
|
||||
.menu_left
|
||||
{
|
||||
|
||||
float:left;
|
||||
|
||||
}
|
||||
|
||||
.menu_right
|
||||
{
|
||||
|
||||
float:right;
|
||||
|
||||
}
|
||||
|
||||
/* styles in content */
|
||||
|
||||
#content
|
||||
{
|
||||
|
||||
display:block;
|
||||
padding:0px 5px 0px 5px;
|
||||
font-size:12px;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:none;
|
||||
color: #676767;
|
||||
margin-top:0px;
|
||||
overflow:auto;
|
||||
position:relative;
|
||||
font-weight:lighter;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.content
|
||||
{
|
||||
|
||||
overflow:auto;
|
||||
position:relative;
|
||||
|
||||
}
|
||||
|
||||
.content_all
|
||||
{
|
||||
|
||||
width:598px;
|
||||
float:left;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.content_right
|
||||
{
|
||||
|
||||
width:772px;
|
||||
float:left;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.title
|
||||
{
|
||||
|
||||
font-size:18px;
|
||||
font-weight:bold;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:none;
|
||||
color: #232323;
|
||||
border:solid #cbcbcb;
|
||||
border-width:1px;
|
||||
padding:10px;
|
||||
margin-bottom:5px;
|
||||
background-color:#1ca34f;
|
||||
background-image:url('../images/background_barr.png');
|
||||
background-repeat:repeat-x;
|
||||
border-radius:8px;
|
||||
text-shadow: 1px 1px 2px rgba(150, 150, 150, 1);
|
||||
|
||||
}
|
||||
|
||||
.cont {
|
||||
|
||||
border:solid #dbdbdb;
|
||||
border-width:1px 1px 1px 1px;
|
||||
padding:10px 20px 10px 20px;
|
||||
margin-bottom:5px;
|
||||
position:relative;
|
||||
/*text-align:justify;*/
|
||||
overflow:hidden;
|
||||
height:100%;
|
||||
|
||||
}
|
||||
|
||||
#inform {
|
||||
|
||||
margin:auto;
|
||||
|
||||
}
|
||||
|
||||
#options {
|
||||
|
||||
position:absolute;
|
||||
top:50px;
|
||||
left:600px;
|
||||
}
|
||||
|
||||
/*Styles for common templates...*/
|
||||
|
||||
.form label {
|
||||
display: block;
|
||||
width: 150px;
|
||||
float: left;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 300px;
|
||||
padding-right: 20px;
|
||||
|
||||
}
|
||||
|
||||
.form textarea {
|
||||
|
||||
width:100%;
|
||||
height:150px;
|
||||
clear:both;
|
||||
|
||||
}
|
||||
|
||||
.form p {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.panel {
|
||||
|
||||
|
||||
}
|
||||
|
||||
.panel p {
|
||||
|
||||
text-align:center;
|
||||
|
||||
}
|
||||
|
||||
.panel img {
|
||||
|
||||
display:block;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
|
||||
}
|
||||
|
||||
/* Table list config */
|
||||
|
||||
.table_list {
|
||||
|
||||
border:solid #cbcbcb;
|
||||
border-width:1px;
|
||||
width:100%;
|
||||
clear:left;
|
||||
border-radius:8px;
|
||||
|
||||
}
|
||||
|
||||
.head_list
|
||||
{
|
||||
|
||||
/*width:100%;*/
|
||||
margin:4px;
|
||||
display:block;
|
||||
position:relative;
|
||||
float:left;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px;*/
|
||||
width:60%;
|
||||
}
|
||||
|
||||
.head_list_right
|
||||
{
|
||||
|
||||
/*width:100%;*/
|
||||
margin:4px;
|
||||
display:block;
|
||||
position:relative;
|
||||
/*clear:left;*/
|
||||
float:right;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px;*/
|
||||
width:35%;
|
||||
bottom:0px;
|
||||
text-align:right;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.title_list
|
||||
{
|
||||
|
||||
|
||||
width:100%;
|
||||
position:relative;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px 1px 1px 1px;*/
|
||||
|
||||
}
|
||||
|
||||
.title_list td
|
||||
{
|
||||
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:none;
|
||||
color: #fff;
|
||||
border:solid #cbcbcb;
|
||||
border-width:1px 1px 1px 1px;
|
||||
padding:5px 5px 5px 5px;
|
||||
margin:4px;
|
||||
margin-bottom:5px;
|
||||
background-color:#d75a09;
|
||||
background-repeat:repeat-x;
|
||||
text-align:center;
|
||||
border-radius:8px;
|
||||
|
||||
}
|
||||
|
||||
.row_list
|
||||
{
|
||||
|
||||
|
||||
width:100%;
|
||||
position:relative;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px 1px 1px 1px;*/
|
||||
|
||||
}
|
||||
|
||||
.row_list td
|
||||
{
|
||||
|
||||
font-size:12px;
|
||||
font-weight:bold;
|
||||
font-family:verdana, verdana;
|
||||
text-decoration:none;
|
||||
color: #676767;
|
||||
border:solid #ffffff;
|
||||
border-width:1px 1px 1px 1px;
|
||||
padding:5px 5px 5px 5px;
|
||||
margin:4px;
|
||||
margin-bottom:5px;
|
||||
text-align:center;
|
||||
/*background-color:#d75a09;
|
||||
background-image:url('../images/fondo_titulo.png');
|
||||
background-repeat:repeat-x;*/
|
||||
/*float:left;*/
|
||||
|
||||
}
|
||||
|
||||
/* styles in private messages */
|
||||
|
||||
.new_message
|
||||
{
|
||||
|
||||
display:block;
|
||||
width:60px;
|
||||
height:30px;
|
||||
float:left;
|
||||
padding:0px;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px;*/
|
||||
background-image:url('../images/new_message.png');
|
||||
background-repeat:no-repeat;
|
||||
background-position:center;
|
||||
|
||||
}
|
||||
|
||||
.message
|
||||
{
|
||||
|
||||
display:block;
|
||||
width:60px;
|
||||
height:30px;
|
||||
float:left;
|
||||
padding:0px;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px;*/
|
||||
background-image:url('../images/message.png');
|
||||
background-repeat:no-repeat;
|
||||
background-position:center;
|
||||
|
||||
}
|
||||
|
||||
.error
|
||||
{
|
||||
|
||||
color: #ff0000;
|
||||
font-weight:bold;
|
||||
|
||||
}
|
||||
|
||||
#footer
|
||||
{
|
||||
|
||||
height:100px;
|
||||
border: solid #bcbcbc;
|
||||
border-width:1px;
|
||||
border-radius:8px;
|
||||
margin-bottom:15px;
|
||||
text-align:center;
|
||||
line-height:100px;
|
||||
position:relative;
|
||||
font-size:12px;
|
||||
font-family:verdana;
|
||||
color:#555555;
|
||||
background-image:url('../images/background_foot.png');
|
||||
background-repeat:repeat-x;
|
||||
background-position:bottom;
|
||||
background-color: #fff;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*Products style*/
|
||||
|
||||
.product
|
||||
{
|
||||
|
||||
display:block;
|
||||
position:relative;
|
||||
height:100%;
|
||||
margin-bottom:10px;
|
||||
|
||||
}
|
||||
|
||||
.title_product
|
||||
{
|
||||
|
||||
border:solid #ffffff;
|
||||
border-width:1px 0px 0px 0px;
|
||||
font-size:15px;
|
||||
font-weight:bold;
|
||||
display:block;
|
||||
/*clear:right;*/
|
||||
margin-bottom:4px;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px;*/
|
||||
|
||||
}
|
||||
|
||||
.image_list_prod
|
||||
{
|
||||
|
||||
border:solid #ffffff;
|
||||
border-width:1px;
|
||||
float:left;
|
||||
position:relative;
|
||||
padding:0px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.description_product
|
||||
{
|
||||
|
||||
float:left;
|
||||
padding:20px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.img_desc
|
||||
{
|
||||
|
||||
border:solid #ffffff;
|
||||
border-width:1px;
|
||||
margin-left:30px;
|
||||
margin-right:30px;
|
||||
|
||||
}
|
||||
|
||||
.desc_product
|
||||
{
|
||||
|
||||
border:solid #ffffff;
|
||||
border-width:0px 0px 1px 0px;
|
||||
overflow:auto;
|
||||
height:100%;
|
||||
padding-bottom:5px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
a.ship {
|
||||
|
||||
display: block;
|
||||
border: solid #cbcbcb;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
background-image:url('../images/background_barr.png');
|
||||
background-position:bottom center;
|
||||
background-repeat:repeat-x;
|
||||
text-align:center;
|
||||
min-width:100px;
|
||||
min-height: 28px;
|
||||
float:left;
|
||||
line-height:28px;
|
||||
padding:5px;
|
||||
color: #868686;
|
||||
|
||||
}
|
||||
|
||||
a.ship:hover {
|
||||
|
||||
/*background-position: -87px 0px;*/
|
||||
|
||||
}
|
||||
|
||||
a.see {
|
||||
|
||||
display: block;
|
||||
min-width: 126px;
|
||||
min-height: 28px;
|
||||
border: solid #cbcbcb;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
background-image:url('../images/background_barr.png');
|
||||
background-position:bottom center;
|
||||
background-repeat:repeat-x;
|
||||
line-height:28px;
|
||||
text-align:center;
|
||||
float:left;
|
||||
margin-right:2px;
|
||||
padding:5px;
|
||||
color: #868686;
|
||||
|
||||
}
|
||||
|
||||
.see_products {
|
||||
|
||||
display: block;
|
||||
min-width: 126px;
|
||||
min-height: 28px;
|
||||
border: solid #cbcbcb;
|
||||
border-width:1px;
|
||||
border-radius:5px;
|
||||
background-image:url('../images/background_barr.png');
|
||||
background-position:bottom center;
|
||||
background-repeat:repeat-x;
|
||||
line-height:28px;
|
||||
text-align:center;
|
||||
/*border:solid #ffffff;
|
||||
border-width:1px 1px 1px 1px;*/
|
||||
float:left;
|
||||
margin-right:2px;
|
||||
padding:5px;
|
||||
color: #868686;
|
||||
|
||||
}
|
||||
#show_process_buying
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
|
||||
}
|
||||
|
||||
/*view big image css*/
|
||||
|
||||
#show_big_images
|
||||
{
|
||||
|
||||
display:none;
|
||||
position:fixed;
|
||||
width:100%;
|
||||
height:100%;
|
||||
z-index:150;
|
||||
background-color: #000;
|
||||
|
||||
}
|
||||
|
||||
#center_frame_image
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:100%;
|
||||
z-index:151;
|
||||
|
||||
}
|
||||
|
||||
#frame_image
|
||||
{
|
||||
display:none;
|
||||
width:300px;
|
||||
height:300px;
|
||||
border: solid #ffffff;
|
||||
border-width:4px;
|
||||
border-radius:10px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
margin-top:20px;
|
||||
position:relative;
|
||||
z-index:151;
|
||||
background-image:url('../images/loading_image_black.gif');
|
||||
background-position:center;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #000;
|
||||
overflow:visible;
|
||||
|
||||
}
|
||||
|
||||
#icon_close_frame_image
|
||||
{
|
||||
|
||||
position:absolute;
|
||||
background-image:url('../images/close_black.png');
|
||||
background-position:center;
|
||||
background-repeat: no-repeat;
|
||||
width:30px;
|
||||
height:30px;
|
||||
display:block;
|
||||
z-index:152;
|
||||
color:#fff;
|
||||
right:0px;
|
||||
|
||||
}
|
||||
|
||||
.units
|
||||
{
|
||||
|
||||
width:40px;
|
||||
text-align:center;
|
||||
|
||||
}
|
||||
1
paramecio2/modules/admin/media/css/tooltipster.bundle.min.css
vendored
Normal file
BIN
paramecio2/modules/admin/media/fonts/FontAwesome.otf
Normal file
BIN
paramecio2/modules/admin/media/fonts/fontawesome-webfont.eot
Normal file
2671
paramecio2/modules/admin/media/fonts/fontawesome-webfont.svg
Normal file
|
After Width: | Height: | Size: 434 KiB |
BIN
paramecio2/modules/admin/media/fonts/fontawesome-webfont.ttf
Normal file
BIN
paramecio2/modules/admin/media/fonts/fontawesome-webfont.woff
Normal file
BIN
paramecio2/modules/admin/media/fonts/fontawesome-webfont.woff2
Normal file
BIN
paramecio2/modules/admin/media/images/ajax-loader.gif
Normal file
|
After Width: | Height: | Size: 500 B |
BIN
paramecio2/modules/admin/media/images/background.png
Normal file
|
After Width: | Height: | Size: 332 B |
BIN
paramecio2/modules/admin/media/images/background_title.png
Normal file
|
After Width: | Height: | Size: 476 B |
BIN
paramecio2/modules/admin/media/images/background_title_login.png
Normal file
|
After Width: | Height: | Size: 5 KiB |
BIN
paramecio2/modules/admin/media/images/languages/en-US.png
Normal file
|
After Width: | Height: | Size: 562 B |
BIN
paramecio2/modules/admin/media/images/languages/es-ES.png
Normal file
|
After Width: | Height: | Size: 539 B |
BIN
paramecio2/modules/admin/media/images/logo.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
5
paramecio2/modules/admin/media/js/jquery.min.js
vendored
Normal file
1
paramecio2/modules/admin/media/js/responsive-nav.min.js
vendored
Normal file
2323
paramecio2/modules/admin/media/js/spectrum.js
Normal file
504
paramecio2/modules/admin/media/js/tinymce/license.txt
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #a67f59;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 354 B |
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 331 B |
|
After Width: | Height: | Size: 342 B |
|
After Width: | Height: | Size: 340 B |
|
After Width: | Height: | Size: 336 B |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 343 B |
|
After Width: | Height: | Size: 321 B |
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 344 B |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 328 B |
|
After Width: | Height: | Size: 337 B |
|
After Width: | Height: | Size: 350 B |
|
After Width: | Height: | Size: 336 B |
|
|
@ -0,0 +1,135 @@
|
|||
.mce-visualblocks p {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks h1 {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks h2 {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks h3 {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks h4 {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks h5 {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks h6 {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks div:not([data-mce-bogus]) {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks section {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=);
|
||||
}
|
||||
|
||||
.mce-visualblocks article {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks blockquote {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks address {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=);
|
||||
}
|
||||
|
||||
.mce-visualblocks pre {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin-left: 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks figure {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks hgroup {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7);
|
||||
}
|
||||
|
||||
.mce-visualblocks aside {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=);
|
||||
}
|
||||
|
||||
.mce-visualblocks figcaption {
|
||||
border: 1px dashed #BBB;
|
||||
}
|
||||
|
||||
.mce-visualblocks ul {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==)
|
||||
}
|
||||
|
||||
.mce-visualblocks ol {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==);
|
||||
}
|
||||
|
||||
.mce-visualblocks dl {
|
||||
padding-top: 10px;
|
||||
border: 1px dashed #BBB;
|
||||
margin: 0 0 1em 3px;
|
||||
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==);
|
||||
}
|
||||
|
After Width: | Height: | Size: 104 B |
|
After Width: | Height: | Size: 99 B |
|
After Width: | Height: | Size: 86 B |
|
After Width: | Height: | Size: 120 B |
|
After Width: | Height: | Size: 72 B |
|
After Width: | Height: | Size: 64 B |
|
After Width: | Height: | Size: 93 B |