修改登录界面路径;

修改login.html路径问题;
添加静态文件
duizhaopin
apan 3 years ago
parent 27663b4a58
commit b521855947

@ -3,10 +3,12 @@
'''
@Date:2022/07/13 10:27:10
'''
# from Common.Utils import Utils
# from Common.utils import Utils
from DataEntity.HumitureRecordModels import EntityHumitureRecord
from Business.Repository import Repository
import datetime
# 功能模块
@ -27,13 +29,13 @@ class BllHumitureRecord(Repository):
# 获取温湿度列表
def getHumitureList(self, customerId, pageParam):
queryStr = 'select * from ((select * from rms_humiture_record where client_id=:clientId) '
queryStr += ' union all (select * from rms_humiture_record where client_id!=:clientId order by client_name ASC ) )t order by t.record_date DESC '
queryStr = 'select * from ((select * from rms_humiture_record where client_id=:client_id) '
queryStr += ' union all (select * from rms_humiture_record where client_id!=:client_id order by client_name ASC ) )t order by t.record_date DESC '
queryCountStr = 'select COUNT(*) from ((select * from rms_humiture_record where client_id=:clientId) '
queryCountStr += ' union all (select * from rms_humiture_record where client_id!=:clientId order by client_name ASC ) )t order by t.record_date DESC '
queryCountStr = 'select COUNT(*) from ((select * from rms_humiture_record where client_id=:client_id) '
queryCountStr += ' union all (select * from rms_humiture_record where client_id!=:client_id order by client_name ASC ) )t order by t.record_date DESC '
# queryParams = {"clientId": CurrentInfo.ClientInfo.client_id}
queryParams = {"clientId": customerId}
queryParams = {"client_id": customerId}
templateList = self.execute(queryStr + ' limit ' + str((pageParam.curPage-1)
* pageParam.pageRows)+','+str(pageParam.pageRows), queryParams).fetchall()
pageParam.totalRecords = self.execute(

@ -0,0 +1,141 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@Date:2022/07/14 08:39:04
'''
import threading
import datetime
from sqlalchemy import and_, or_
from Common.utils import Utils
from Business.Repository import Repository
from DataEntity.MedicamentModels import EntityMedicamentVariety
from DataEntity.UserModels import EntityUser
# 药剂品种业务逻辑类
class BllMedicamentVariety(Repository):
_instance_lock = threading.Lock()
# #实现单例模式
# def __new__(cls, *args, **kwargs):
# if not hasattr(BllMedicamentVariety, "_instance"):
# with BllMedicamentVariety._instance_lock:
# if not hasattr(BllMedicamentVariety, "_instance"):
# BllMedicamentVariety._instance = object.__new__(cls)
# return BllMedicamentVariety._instance
def __init__(self, entityType=EntityMedicamentVariety):
return super().__init__(entityType)
# 创建药剂品种
def createDrugVariety(
self, customerId, name, english, casNumber,
purity, total, net_weight_unit, net_weight, tp, entityUser=EntityUser()
):
entity = self.findEntity(
and_(
EntityMedicamentVariety.name == name,
EntityMedicamentVariety.purity == purity,
# EntityMedicamentVariety.Unit == unit,
# EntityMedicamentVariety.SpeciUnit == speciUnit,
# EntityMedicamentVariety.Speci == speci
EntityMedicamentVariety.total == total,
EntityMedicamentVariety.net_weight_unit == net_weight_unit,
EntityMedicamentVariety.net_weight == net_weight,
EntityMedicamentVariety.tp == tp,
)
)
if(entity is None):
print(entity, 9999999999999999999)
entity = EntityMedicamentVariety()
entity.variety_id = str(Utils.UUID())
entity.customer_id = customerId
entity.inventory_warning_value = 10
entity.shelf_life_warning_value = 10
entity.use_days_warning_value = 10
entity.name = name
entity.english_name = english
entity.cas_number = casNumber
entity.purity = purity
entity.total = total
entity.net_weight_unit = net_weight_unit
entity.net_weight = net_weight
entity.tp = tp
# 库存总数
entity.total_count = 1
# 在库数量
entity.normal_count = 1
# 领用数量
entity.use_count = 0
# 空瓶数量
entity.empty_count = 0
entity.is_supervise = 0
entity.create_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
entity.create_user_id = entityUser.user_id
entity.create_user_name = entityUser.real_name
self.insert(entity)
# else:
# # 库存总数 + 1
# entity.TotalCount += 1
# # 在库数量 + 1
# entity.NormalCount += 1
# self.update(entity)
entity = self.session.merge(entity)
return entity
# 模糊查询根据药剂名称或英文名称查询
def findEnglishOrChinseNameList(self, params):
return self.findList(or_(EntityMedicamentVariety.name.like('%' + params + '%'),
EntityMedicamentVariety.english_name.like('%' + params + '%')))
# #创建药剂品种
# def createDrugVariety(self, customerId, name, english, casNumber, purity, unit, speciUnit, speci, entityUser=EntityUser()):
# entity = self.findEntity(and_(EntityMedicamentVariety.Name == name, EntityMedicamentVariety.Purity == purity,
# EntityMedicamentVariety.Unit == unit, EntityMedicamentVariety.SpeciUnit == speciUnit, EntityMedicamentVariety.Speci == speci))
# if(entity is None):
# print(entity, 9999999999999999999)
# entity = EntityMedicamentVariety()
# entity.VarietyId = str(Utils.UUID())
# entity.CustomerId = customerId
# entity.InventoryWarningValue = 10
# entity.ShelfLifeWarningValue = 10
# entity.UseDaysWarningValue = 10
# entity.Name = name
# entity.EnglishName = english
# entity.CASNumber = casNumber
# entity.Purity = purity
# entity.Unit = unit
# entity.SpeciUnit = speciUnit
# # 库存总数
# entity.TotalCount = 1
# # 在库数量
# entity.NormalCount = 1
# # 领用数量
# entity.UseCount = 0
# # 空瓶数量
# entity.EmptyCount = 0
# entity.IsSupervise = 0
# entity.Speci = speci
# entity.CreateDate = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# entity.CreateUserId = entityUser.UserId
# entity.CreateUserName = entityUser.RealName
# self.insert(entity)
# # else:
# # # 库存总数 + 1
# # entity.TotalCount += 1
# # # 在库数量 + 1
# # entity.NormalCount += 1
# # self.update(entity)
# entity = self.session.merge(entity)
# return entity
# # 模糊查询根据药剂名称或英文名称查询
# def findEnglishOrChinseNameList(self, params):
# return self.findList(or_(EntityMedicamentVariety.Name.like('%' + params + '%'),
# EntityMedicamentVariety.EnglishName.like('%' + params + '%')))

@ -0,0 +1,228 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@Date:2022/07/14 08:36:50
'''
import threading
import time
from Business.Warning import BllWarning
from Business.MedicamentVariety import BllMedicamentVariety, Utils, datetime
from DataEntity.WarningModels import EntityWarning
class SupervisionWarning:
def __init__(self):
# 删除视频事件
self.deleteVideoDatetime = None
def supervision_start(self):
p = threading.Thread(target=self.supervision_start_thread)
p.start()
def insert_warning_default(self, customer_id, object_type, object_id, object_name, warning_content):
try:
warning_obj = EntityWarning(
warning_id=str(Utils.UUID()),
customer_id=customer_id,
object_type=object_type,
object_id=object_id,
object_name=object_name,
warning_content=warning_content,
warning_date=datetime.datetime.now(),
warning_user_name='系统',
is_solve=0,
is_add=1
)
bool_ = BllWarning().insert(warning_obj)
if bool_:
print('插入成功!')
except Exception as error:
print(error)
return
def warning_content_type(self, tp):
# 根据object_type俩进行消息区分
content_dict = {
"2": "药剂过期预警:过期药剂[%s](%s), 当前时间: %s; 超出设定过期时间%s; 位置:%s; 号柜%s",
"3": "药剂种类余量预警:药剂种类%s, 当前种类药剂余量%s瓶,小于设定余量%s瓶;",
"1": "药剂保质期预警:药剂 %s(%s) 超过保质期预警线, 当前时间:%s; 设定警戒线:%s天; 位置:%s号柜 %s",
"5": "%s 药柜滤芯保质期预警:药柜滤芯提前预警时间%s天,生产日期%s,当前时间:%s,保质期:%s天; 已达到提前预警时间;",
"6": "出库超期预警:用户[%s]已领用: %s(%s) %s天,超过预警线:%s"
}
return content_dict.get(tp, "")
def supervision_start_thread(self):
while True:
try:
BllWarning().executeNoParam("delete from rms_warning where object_type not in('7') ")
# 查询预警数量和某一类型当前在库数量
SQL = """
SELECT b.variety_id as variety_id, b.customer_id, b.Name, sum(case when a.status = 1 then 1 else 0 end) as normal_count, b.inventory_warning_value
from rms_medicament_variety as b LEFT JOIN rms_medicament as a on b.variety_id = a.variety_id GROUP by b.variety_id
"""
data_obj_list = BllMedicamentVariety().execute(SQL).fetchall()
for data_obj in data_obj_list:
if data_obj.inventory_warning_value:
if data_obj.inventory_warning_value > data_obj.normal_count:
# 封装conent统一化管理
# 封装创建warning方法统一化管理
# 药剂种类余量预警
object_type = 3
content_info = self.warning_content_type(
object_type)
self.insert_warning_default(
customer_id=data_obj.customer_id,
object_type=object_type,
object_id=data_obj.variety_id,
object_name=data_obj.name,
warning_content=content_info % (
data_obj.name,
str(data_obj.normal_count),
str(data_obj.inventory_warning_value)
)
)
time.sleep(1)
# SQL查询过期预警数量
SQL = """
select * from rms_medicament a where a.expiration_date < now();
"""
expire_obj_list = BllWarning().execute(SQL).fetchall()
if expire_obj_list:
for expire_obj in expire_obj_list:
if expire_obj.status != 3:
# 封装conent统一化管理
# 封装创建warning方法统一化管理
# 药剂过期预警
object_type = 2
conent = self.warning_content_type(object_type)
self.insert_warning_default(
customer_id=expire_obj.customer_id,
object_type=object_type,
object_id=expire_obj.medicament_id,
object_name=expire_obj.name,
warning_content=conent % (
expire_obj.name,
expire_obj.bar_code,
str(datetime.datetime.now().strftime(
'%Y-%m-%d %H:%M:%S')),
str(expire_obj.expiration_date or ''),
str(expire_obj.client_code or ''),
str(expire_obj.place or '')
),
)
time.sleep(1)
# SQL查询保质期预警数量
SQL = """
select * from rms_medicament a where a.expiration_date < DATE_ADD(now(), INTERVAL a.shelf_life_warning_value DAY);
"""
expireIdList = [x.medicament_id for x in expire_obj_list]
shelflife_obj_list = BllWarning().execute(SQL).fetchall()
if shelflife_obj_list:
for expire_obj in shelflife_obj_list:
if (expire_obj.status != 3 and expire_obj.medicament_id not in expireIdList):
# 封装conent统一化管理
# 封装创建warning方法统一化管理
# 药剂保质期预警
object_type = 1
conent = self.warning_content_type(object_type)
self.insert_warning_default(
customer_id=expire_obj.customer_id,
object_type=object_type,
object_id=expire_obj.medicament_id,
object_name=expire_obj.name,
warning_content=conent % (
expire_obj.name,
expire_obj.bar_code,
str(datetime.datetime.now().strftime(
'%Y-%m-%d %H:%M:%S')),
str(expire_obj.shelf_life_warning_value),
expire_obj.client_code,
(expire_obj.place if expire_obj.place else '')
)
)
time.sleep(1)
# SQL查询领用超期预警数量
todayDate = datetime.datetime.now().strftime("%Y-%m-%d")
SQL = """
SELECT DATEDIFF('"""+todayDate+"""',STR_TO_DATE(by_user_date,'%Y-%m-%d')) as user_days,
b.use_days_warning_value,a.by_user_name,a.`name`,a.bar_code,a.medicament_id,a.customer_id
FROM rms_medicament a LEFT JOIN rms_medicamentvariety b ON a.variety_id=b.variety_id
WHERE DATEDIFF('"""+todayDate+"""',STR_TO_DATE(by_user_date,'%Y-%m-%d'))>b.use_days_warning_value AND a.`status`=2;
"""
shelflife_obj_list = BllWarning().execute(SQL).fetchall()
if shelflife_obj_list:
for expire_obj in shelflife_obj_list:
# 封装conent统一化管理
# 封装创建warning方法统一化管理
# 出库超期预警
object_type = 6
conent = self.warning_content_type(object_type)
self.insert_warning_default(
customer_id=expire_obj.customer_id,
object_type=object_type,
object_id=expire_obj.medicament_id,
object_name=expire_obj.name,
warning_content=conent % (
expire_obj.by_user_name,
expire_obj.name,
expire_obj.bar_code,
str(expire_obj.user_days),
str(expire_obj.use_days_warning_value)
)
)
time.sleep(1)
# SQL查询药柜滤芯保质期预警
SQL = """
SELECT * FROM `rms_client`;
"""
filter_obj_list = BllWarning().execute(SQL).fetchall()
if filter_obj_list is not None:
for filter_obj in filter_obj_list:
if filter_obj.filter_production_date:
# 滤芯过期提前预警时间 生产日期 + 保质期 - 提前预警天数
filter_expire_date = filter_obj.filter_production_date + datetime.timedelta(days=(
filter_obj.filter_shelf_life - filter_obj.filter_shelf_life_warning_value))
if filter_expire_date <= datetime.datetime.now():
BllWarning_obj = BllWarning().findList(
EntityWarning.object_id == filter_obj.client_id).all()
if not BllWarning_obj:
# 封装conent统一化管理
# 封装创建warning方法统一化管理
# 药柜滤芯保质期预警
object_type = 5
conent = self.warning_content_type(
object_type)
self.insert_warning_default(
customer_id=filter_obj.customer_id,
object_type=object_type,
object_id=filter_obj.client_id,
object_name=filter_obj.client_name,
warning_content=conent % (
filter_obj.client_name,
str(filter_obj.filter_shelf_life_warning_value),
filter_obj.filter_production_date.strftime(
'%Y-%m-%d %H:%M:%S'),
str(datetime.datetime.now().strftime(
'%Y-%m-%d %H:%M:%S')),
str(filter_obj.filter_shelf_life),)
)
time.sleep(1)
except Exception as e:
print(str(e))
# logUtil().debug('预警监测:'+traceback.format_exc())
time.sleep(3600)

@ -3,37 +3,38 @@
'''
@Date:2022/07/13 09:37:21
'''
import os
import datetime
import functools
import hashlib
import platform
import uuid
import json
import datetime
import os
import platform
import random
import logging
import functools
import sys
import uuid
from logging import getLogger as get_logger
from logging.config import dictConfig as log_dict_config
import psutil
from django.core.cache import cache
from Business.Client import BllClient
from Business.HumitureRecord import BllHumitureRecord
from DataEntity.HumitureRecordModels import EntityHumitureRecord
from dateutil import parser, relativedelta
from django.conf import settings
from django.core.cache import cache
from sqlalchemy import and_
from dateutil import relativedelta, parser
from Common.AlchemyUtils import AlchemyEncoder
from Business.Client import BllClient
from Business.HumitureRecord import BllHumitureRecord
from DataEntity.HumitureRecordModels import EntityHumitureRecord
sys.path.append('.')
# 判断当前系统是linux还是windows
system_name = platform.system()
try:
# 加载settings里面的配置项
logging.config.dictConfig(settings.LOGGING)
logger = logging.getLogger('default')
except:
pass
# 加载settings里面的配置项
log_dict_config(settings.LOGGING)
logger = get_logger('default')
"""通用工具类"""
@ -331,3 +332,6 @@ class Utils(object):
if(len(udisklist) >= 3):
return '/media/yanyi/' + udisklist[2]
return ""
print(Utils.MD5("123456789"))

@ -1,3 +1,10 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@Date:2022/07/14 13:59:09
'''
import json
import time
import os

@ -3,7 +3,6 @@
'''
@Date:2022/07/13 15:16:50
'''
from model_name_utlis import model_name_loer
from sqlalchemy import Column, String, Integer, Text, Float
from sqlalchemy.ext.declarative import declarative_base

@ -9,12 +9,10 @@ https://docs.djangoproject.com/en/2.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""
import logging
import os
import time
import logging
from Common.searchDrug import GetDrugTypeData
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -29,7 +27,7 @@ SECRET_KEY = '%xoxlv+gx&4$^t8a2nyj56g93ayt-_xl_zl^dy3oru8o)3-r1k'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']
# Application definition
@ -42,16 +40,20 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
# 'corsheaders',
'account',
'user'
'user',
'corsheaders',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# 'corsheaders.middleware.CorsMiddleware', # 默认
'corsheaders.middleware.CorsMiddleware', # 默认
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -94,7 +96,7 @@ ROOT_URLCONF = 'YY_RMS_Multiple_Manage.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
@ -113,13 +115,14 @@ WSGI_APPLICATION = 'YY_RMS_Multiple_Manage.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
X_FRAME_OPTIONS = 'ALLOWALL url'
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
@ -153,14 +156,31 @@ USE_L10N = True
USE_TZ = True
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS = {
'host': 'localhost',
'port': 6379,
'db': 0,
'password': '123456',
'prefix': 'session',
'socket_timeout': 1
}
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
# 部署路径
STATIC_ROOT = '../YY_RMS_Multiple_Manage/static_files'
# 程序运行时加载 只加载一次
from Common.searchDrug import GetDrugTypeData
GetDrugTypeData.init()
flag_ = True
@ -236,3 +256,6 @@ LOGGING = {
},
}
}
from Common.SupervisionWarning import SupervisionWarning
SupervisionWarning().supervision_start()

@ -22,7 +22,12 @@ from django.conf import settings
from . import views
urlpatterns = [
# path('admin/', admin.site.urls),
re_path("^$", view=views.home, name="home"),
path("^$", view=views.home, name="home"),
# 登录相关接口
re_path('^account/', include("account.urls"))
re_path('^account/', include("account.urls")),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
handler404 = 'YY_RMS_Multiple_Manage.views.page_not_found'

@ -7,9 +7,11 @@ from django.views.decorators.http import require_http_methods
from django.shortcuts import HttpResponse, render, redirect
from Common.Utils import Utils, logger
from Business.User import BllUser
from Business.Warning import BllWarning
from Common.utils import Utils, logger
from Business.User import BllUser
@Utils.log_exception
@ -66,3 +68,9 @@ def home(request):
return render(request, 'home.html', locals())
finally:
BllWarning().session.close()
# 404页面处理方案
def page_not_found(request, exception):
logger.debug('页面没有找到')
return HttpResponse('地址错误')

@ -6,6 +6,9 @@
from django.urls import path, re_path
from django.conf.urls import include
from django.conf.urls.static import static
from django.conf import settings
from . import views

@ -5,12 +5,12 @@
'''
import datetime
import json
from django.shortcuts import render, HttpResponse, redirect
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
from Common.Utils import Utils, logger
from Common.utils import Utils, logger
from Business.User import BllUser
from Business.Log import BllLog

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,429 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*!
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
(function ($) {
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}
function splitAndTrim(value) {
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
function onErrors(event, validator) { // 'this' is the form element
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
function onSuccess(error) { // 'this' is the form element
var container = error.data("unobtrusiveContainer"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
if (container) {
container.addClass("field-validation-valid").removeClass("field-validation-error");
error.removeData("unobtrusiveContainer");
if (replace) {
container.empty();
}
}
}
function onReset(event) { // 'this' is the form element
var $form = $(this),
key = '__jquery_unobtrusive_validation_form_reset';
if ($form.data(key)) {
return;
}
// Set a flag that indicates we're currently resetting the form.
$form.data(key, true);
try {
$form.data("validator").resetForm();
} finally {
$form.removeData(key);
}
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form),
defaultOptions = $jQval.unobtrusive.options || {},
execInContext = function (name, args) {
var func = defaultOptions[name];
func && $.isFunction(func) && func.apply(form, args);
}
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: defaultOptions.errorClass || "input-validation-error",
errorElement: defaultOptions.errorElement || "span",
errorPlacement: function () {
onError.apply(form, arguments);
execInContext("errorPlacement", arguments);
},
invalidHandler: function () {
onErrors.apply(form, arguments);
execInContext("invalidHandler", arguments);
},
messages: {},
rules: {},
success: function () {
onSuccess.apply(form, arguments);
execInContext("success", arguments);
}
},
attachValidation: function () {
$form
.off("reset." + data_validation, onResetProxy)
.on("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
$jQval.unobtrusive = {
adapters: [],
parseElement: function (element, skipAttach) {
/// <summary>
/// Parses a single HTML element for unobtrusive validation attributes.
/// </summary>
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
/// validation to the form. If parsing just this single element, you should specify true.
/// If parsing several elements, you should specify false, and manually attach the validation
/// to the form when you are finished. The default is false.</param>
var $element = $(element),
form = $element.parents("form")[0],
valInfo, rules, messages;
if (!form) { // Cannot do client-side validation without a form
return;
}
valInfo = validationInfo(form);
valInfo.options.rules[element.name] = rules = {};
valInfo.options.messages[element.name] = messages = {};
$.each(this.adapters, function () {
var prefix = "data-val-" + this.name,
message = $element.attr(prefix),
paramValues = {};
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
prefix += "-";
$.each(this.params, function () {
paramValues[this] = $element.attr(prefix + this);
});
this.adapt({
element: element,
form: form,
message: message,
params: paramValues,
rules: rules,
messages: messages
});
}
});
$.extend(rules, { "__dummy__": true });
if (!skipAttach) {
valInfo.attachValidation();
}
},
parse: function (selector) {
/// <summary>
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
/// attribute values.
/// </summary>
/// <param name="selector" type="String">Any valid jQuery selector.</param>
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
// element with data-val=true
var $selector = $(selector),
$forms = $selector.parents()
.addBack()
.filter("form")
.add($selector.find("form"))
.has("[data-val=true]");
$selector.find("[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
};
adapters = $jQval.unobtrusive.adapters;
adapters.add = function (adapterName, params, fn) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
/// mmmm is the parameter name).</param>
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
/// attributes into jQuery Validate rules and/or messages.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
if (!fn) { // Called with no params, just a function
fn = params;
params = [];
}
this.push({ name: adapterName, params: params, adapt: fn });
return this;
};
adapters.addBool = function (adapterName, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has no parameter values.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, function (options) {
setValidationValues(options, ruleName || adapterName, true);
});
};
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a minimum value.</param>
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a maximum value.</param>
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
/// have both a minimum and maximum value.</param>
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the minimum value. The default is "min".</param>
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the maximum value. The default is "max".</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
var min = options.params.min,
max = options.params.max;
if (min && max) {
setValidationValues(options, minMaxRuleName, [min, max]);
}
else if (min) {
setValidationValues(options, minRuleName, min);
}
else if (max) {
setValidationValues(options, maxRuleName, max);
}
});
};
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has a single value.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
/// The default is "val".</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [attribute || "val"], function (options) {
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
});
};
$jQval.addMethod("__dummy__", function (value, element, params) {
return true;
});
$jQval.addMethod("regex", function (value, element, params) {
var match;
if (this.optional(element)) {
return true;
}
match = new RegExp(params).exec(value);
return (match && (match.index === 0) && (match[0].length === value.length));
});
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
var match;
if (nonalphamin) {
match = value.match(/\W/g);
match = match && match.length >= nonalphamin;
}
return match;
});
if ($jQval.methods.extension) {
adapters.addSingleVal("accept", "mimtype");
adapters.addSingleVal("extension", "extension");
} else {
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
// validating the extension, and ignore mime-type validations as they are not supported.
adapters.addSingleVal("extension", "extension", "accept");
}
adapters.addSingleVal("regex", "pattern");
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
setValidationValues(options, "equalTo", element);
});
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
// For checkboxes and radio buttons, only pick up values from checked fields.
if (field.is(":checkbox")) {
return field.filter(":checked").val() || field.filter(":hidden").val() || '';
}
else if (field.is(":radio")) {
return field.filter(":checked").val() || '';
}
return field.val();
};
});
setValidationValues(options, "remote", value);
});
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
if (options.params.min) {
setValidationValues(options, "minlength", options.params.min);
}
if (options.params.nonalphamin) {
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
}
if (options.params.regex) {
setValidationValues(options, "regex", options.params.regex);
}
});
$(function () {
$jQval.unobtrusive.parse(document);
});
}(jQuery));

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,340 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
window.matchMedia = window.matchMedia || (function(doc, undefined){
var bool,
docElem = doc.documentElement,
refNode = docElem.firstElementChild || docElem.firstChild,
// fakeBody required for <FF4 when executed in <head>
fakeBody = doc.createElement('body'),
div = doc.createElement('div');
div.id = 'mq-test-1';
div.style.cssText = "position:absolute;top:-100em";
fakeBody.style.background = "none";
fakeBody.appendChild(div);
return function(q){
div.innerHTML = '&shy;<style media="'+q+'"> #mq-test-1 { width: 42px; }</style>';
docElem.insertBefore(fakeBody, refNode);
bool = div.offsetWidth == 42;
docElem.removeChild(fakeBody);
return { matches: bool, media: q };
};
})(document);
/*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
(function( win ){
//exposed namespace
win.respond = {};
//define update even in native-mq-supporting browsers, to avoid errors
respond.update = function(){};
//expose media query support flag for external use
respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches;
//if media queries are supported, exit here
if( respond.mediaQueriesSupported ){ return; }
//define vars
var doc = win.document,
docElem = doc.documentElement,
mediastyles = [],
rules = [],
appendedEls = [],
parsedSheets = {},
resizeThrottle = 30,
head = doc.getElementsByTagName( "head" )[0] || docElem,
base = doc.getElementsByTagName( "base" )[0],
links = head.getElementsByTagName( "link" ),
requestQueue = [],
//loop stylesheets, send text content to translate
ripCSS = function(){
var sheets = links,
sl = sheets.length,
i = 0,
//vars for loop:
sheet, href, media, isCSS;
for( ; i < sl; i++ ){
sheet = sheets[ i ],
href = sheet.href,
media = sheet.media,
isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
//only links plz and prevent re-parsing
if( !!href && isCSS && !parsedSheets[ href ] ){
// selectivizr exposes css through the rawCssText expando
if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
translate( sheet.styleSheet.rawCssText, href, media );
parsedSheets[ href ] = true;
} else {
if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base)
|| href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
requestQueue.push( {
href: href,
media: media
} );
}
}
}
}
makeRequests();
},
//recurse through request queue, get css text
makeRequests = function(){
if( requestQueue.length ){
var thisRequest = requestQueue.shift();
ajax( thisRequest.href, function( styles ){
translate( styles, thisRequest.href, thisRequest.media );
parsedSheets[ thisRequest.href ] = true;
makeRequests();
} );
}
},
//find media blocks in css text, convert to style blocks
translate = function( styles, href, media ){
var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),
ql = qs && qs.length || 0,
//try to get CSS path
href = href.substring( 0, href.lastIndexOf( "/" )),
repUrls = function( css ){
return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
},
useMedia = !ql && media,
//vars used in loop
i = 0,
j, fullq, thisq, eachq, eql;
//if path exists, tack on trailing slash
if( href.length ){ href += "/"; }
//if no internal queries exist, but media attr does, use that
//note: this currently lacks support for situations where a media attr is specified on a link AND
//its associated stylesheet has internal CSS media queries.
//In those cases, the media attribute will currently be ignored.
if( useMedia ){
ql = 1;
}
for( ; i < ql; i++ ){
j = 0;
//media attr
if( useMedia ){
fullq = media;
rules.push( repUrls( styles ) );
}
//parse for styles
else{
fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
}
eachq = fullq.split( "," );
eql = eachq.length;
for( ; j < eql; j++ ){
thisq = eachq[ j ];
mediastyles.push( {
media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",
rules : rules.length - 1,
hasquery: thisq.indexOf("(") > -1,
minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
} );
}
}
applyMedia();
},
lastCall,
resizeDefer,
// returns the value of 1em in pixels
getEmValue = function() {
var ret,
div = doc.createElement('div'),
body = doc.body,
fakeUsed = false;
div.style.cssText = "position:absolute;font-size:1em;width:1em";
if( !body ){
body = fakeUsed = doc.createElement( "body" );
body.style.background = "none";
}
body.appendChild( div );
docElem.insertBefore( body, docElem.firstChild );
ret = div.offsetWidth;
if( fakeUsed ){
docElem.removeChild( body );
}
else {
body.removeChild( div );
}
//also update eminpx before returning
ret = eminpx = parseFloat(ret);
return ret;
},
//cached container for 1em value, populated the first time it's needed
eminpx,
//enable/disable styles
applyMedia = function( fromResize ){
var name = "clientWidth",
docElemProp = docElem[ name ],
currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
styleBlocks = {},
lastLink = links[ links.length-1 ],
now = (new Date()).getTime();
//throttle resize calls
if( fromResize && lastCall && now - lastCall < resizeThrottle ){
clearTimeout( resizeDefer );
resizeDefer = setTimeout( applyMedia, resizeThrottle );
return;
}
else {
lastCall = now;
}
for( var i in mediastyles ){
var thisstyle = mediastyles[ i ],
min = thisstyle.minw,
max = thisstyle.maxw,
minnull = min === null,
maxnull = max === null,
em = "em";
if( !!min ){
min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
}
if( !!max ){
max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
}
// if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
if( !styleBlocks[ thisstyle.media ] ){
styleBlocks[ thisstyle.media ] = [];
}
styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
}
}
//remove any existing respond style element(s)
for( var i in appendedEls ){
if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){
head.removeChild( appendedEls[ i ] );
}
}
//inject active styles, grouped by media type
for( var i in styleBlocks ){
var ss = doc.createElement( "style" ),
css = styleBlocks[ i ].join( "\n" );
ss.type = "text/css";
ss.media = i;
//originally, ss was appended to a documentFragment and sheets were appended in bulk.
//this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
head.insertBefore( ss, lastLink.nextSibling );
if ( ss.styleSheet ){
ss.styleSheet.cssText = css;
}
else {
ss.appendChild( doc.createTextNode( css ) );
}
//push to appendedEls to track for later removal
appendedEls.push( ss );
}
},
//tweaked Ajax functions from Quirksmode
ajax = function( url, callback ) {
var req = xmlHttp();
if (!req){
return;
}
req.open( "GET", url, true );
req.onreadystatechange = function () {
if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){
return;
}
callback( req.responseText );
}
if ( req.readyState == 4 ){
return;
}
req.send( null );
},
//define ajax obj
xmlHttp = (function() {
var xmlhttpmethod = false;
try {
xmlhttpmethod = new XMLHttpRequest();
}
catch( e ){
xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" );
}
return function(){
return xmlhttpmethod;
};
})();
//translate CSS
ripCSS();
//expose update for re-running respond later on
respond.update = ripCSS;
//adjust on resize
function callMedia(){
applyMedia( true );
}
if( win.addEventListener ){
win.addEventListener( "resize", callMedia, false );
}
else if( win.attachEvent ){
win.attachEvent( "onresize", callMedia );
}
})(this);

@ -0,0 +1,20 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='&shy;<style media="'+h+'"> #mq-test-1 { width: 42px; }</style>';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document);
/*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
(function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B<y;B++){A=D[B],z=A.href,C=A.media,x=A.rel&&A.rel.toLowerCase()==="stylesheet";if(!!z&&x&&!o[z]){if(A.styleSheet&&A.styleSheet.rawCssText){m(A.styleSheet.rawCssText,z,C);o[z]=true}else{if((!/^([a-zA-Z:]*\/\/)/.test(z)&&!g)||z.replace(RegExp.$1,"").split("/")[0]===e.location.host){d.push({href:z,media:C})}}}}u()},u=function(){if(d.length){var x=d.shift();n(x.href,function(y){m(y,x.href,x.media);o[x.href]=true;u()})}},m=function(I,x,z){var G=I.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),J=G&&G.length||0,x=x.substring(0,x.lastIndexOf("/")),y=function(K){return K.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+x+"$2$3")},A=!J&&z,D=0,C,E,F,B,H;if(x.length){x+="/"}if(A){J=1}for(;D<J;D++){C=0;if(A){E=z;k.push(y(I))}else{E=G[D].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1;k.push(RegExp.$2&&y(RegExp.$2))}B=E.split(",");H=B.length;for(;C<H;C++){F=B[C];i.push({media:F.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:k.length-1,hasquery:F.indexOf("(")>-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l<h){clearTimeout(r);r=setTimeout(j,h);return}else{l=z}for(var E in i){var K=i[E],C=K.minw,J=K.maxw,A=C===null,L=J===null,y="em";if(!!C){C=parseFloat(C)*(C.indexOf(y)>-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,65 @@
/* Style For Suggestions */
/*
For creating side border like this
| item 1 |
| item 2 |
*/
.suggestions .suggest_item{
padding-bottom: 2px;
padding-top: 2px;
background-color:#EEEEEE;
border-left:1px solid #CCCCCC;
border-right:1px solid #CCCCCC;
}
/*
For creating top border like this
------------
item 1
...
*/
.suggestions .suggest_item.first{
border-top:1px solid #CCCCCC;
}
/*
For creating bottom border like this
...
item 2
------------
*/
.suggestions .suggest_item.last{
border-bottom:1px solid #CCCCCC;
}
/*
For coloring the selected item
*/
.suggestions .suggest_item.selected, .suggestions .suggest_item.selected .description{
background-color:#999999;
color:#FFFFFF;
cursor:pointer;
}
/*
Image thumbnail
*/
.suggestions .suggest_item .thumbnail{
background-color: transparent;
background-position: top center;
background-repeat: no-repeat;
margin: 1px 2px 1px 2px;
float: left;
width: 50px;
height: 50px;
}
/*
Description
*/
.suggestions .suggest_item .description{
font-style: italic;
font-size: 11px;
color: #777;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
/** layui-v2.5.6 MIT License By https://www.layui.com */
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save