sso looks working

This commit is contained in:
msyu
2025-09-14 12:09:18 +03:00
commit 89ac26325d
149 changed files with 7763 additions and 0 deletions
+447
View File
@@ -0,0 +1,447 @@
<cfcomponent
displayname="Application"
output="true"
hint="Handle the application.">
<!--- Pseudoconstructor --->
<!--- Set up the application. --->
<cfset this.Name = "PAYG-REPORT" />
<cfset this.applicationTimeout = createTimeSpan( 0, 0, 0, 30 ) />
<cfset this.sessionmanagement="Yes"/>
<cfset this.clientmanagement="No"/>
<cfset this.sessiontimeout=CreateTimeSpan(0, 0, 0, 20)/>
<cfset this.setclientcookies="No"/>
<cfset this.mappings = structNew() />
<cfset this.mappings["/mod"] = getDirectoryFromPath(getCurrentTemplatePath()) & "mod/" />
<cfset this.customTagPaths = expandPath(getDirectoryFromPath(getCurrentTemplatePath()) & "mod")/>
<cfset this.datasource = "billing"/>
<!--- SSO --->
<cfset this.client_id = "payg-report.deck.nubes.ru"/>
<cfset this.auth_endpoint = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/auth" />
<cfset this.access_token_endpoint = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/token" />
<cfset this.idpCertUrl = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs" />
<cfset this.client_secret = createObject("java", "java.lang.System").getEnv("IDP_CLIENT_SECRET")/>
<!--- <cfset this.client_secret = this.client_secret ?: ""/> --->
<cfset this.defaultdatasource = this.datasource/>
<cfset request.DS = "#this.datasource#">
<!--- кажется, нужно инициализировать датасорцы в псевдоконструкторе - onRequest не получается --->
<!--- <cfset this.datasources["#this.datasource#"]=getDS("#this.datasource#","ds_#this.datasource#")/> --->
<cffunction
name="OnApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="Fires when the application is first created.">
<!--- *** мы не проверяем срок жизни сертификата и его отзыв--->
Obtain idp certificate OnApplicationStart
<cfset application.idpCertificate = getIdpCertificate(this.idpCertUrl)/>
<cfreturn true />
</cffunction>
<cffunction
name="OnRequest"
access="public"
returntype="void"
output="true"
hint="Fires after pre page processing is complete.">
<cfargument name="template" type="string" required="true"/>
<cfset request.startTickCount=getTickCount()/>
<cfset setEncoding("FORM", "UTF-8")>
<cfset setEncoding("URL", "UTF-8")>
<cfset request.PERMISSION_NONE=0/>
<cfset request.PERMISSION_READ=1/>
<cfset request.PERMISSION_WRITE=2/>
<!--- <cfset request.UNDEFINED_USR_ID=-1/>
<cfset request.ANONYMOUS_USR_ID=2/>
<cfset request.GUEST_USR_ID=3/> --->
<!--- global settings --->
<cfset request.RECORDS_PER_PAGE=500/>
<cfset request.APP_VERSION="0.00.000"/>
<cfset request.STAND=getStand()/>
<!--- application constants --->
<!---<cfset request.SMTP_SERVER="172.16.16.16"/>
<cfset request.MAIL_FROM_FOR_NOTIFICATION="Pipeline tracker <pipeline@mail.ru>"/>
<cfset request.SUBJECT_PREFIX="[PIPELINE TRACKER] "/>--->
<!---<cfset request.BASE_URL="https://smtest.dtln.local/pipeline/"/>*** сделать нормально. Внимание! При наличии прокси CGI.SERVER_NAME может быть заменено --->
<cfset local = {} />
<cfset local.basePath = getDirectoryFromPath(
getCurrentTemplatePath()
) />
<cfset local.targetPath = getDirectoryFromPath(
expandPath( arguments.template )
) />
<cfset local.requestDepth = (
listLen( local.targetPath, "\/" ) -
listLen( local.basePath, "\/" )
) />
<cfset request.webRoot = repeatString(
"../",
local.requestDepth
) />
<!---
While we wouldn't normally do this for every page
request (it would normally be cached in the
application initialization), I'm going to calculate
the site URL based on the web root.
--->
<cfset request.siteUrl = (
IIF(
(CGI.server_port_secure <!--- CGI.https EQ "On" does not work with apache+tomcat and nginx+tomcat --->),
DE( "https://" ),
DE( "http://" )
) &
cgi.http_host &
reReplace(
getDirectoryFromPath( arguments.template ), "([^\\/]+[\\/]){#local.requestDepth#}$",
"",
"one"
)
) />
<cfset request.thisPage=Replace(ReplaceNoCase(expandPath(ARGUMENTS.template), local.basePath, ""), "\", "/")/>
<!--- <cfset request.thisUrl="#request.thisPage##len(CGI.queryString)#"/> чревато циклом --->
<!--- получение сертификата может занимать длительное время.
Блокировать на это время приложение или сессию не следует.
Вообще не следует ничего блокировать на время сетевого взаимодействия
Нижеследующая, на первый взгляд, странная конструкция ровно для этого придумана
--->
<cfoutput>onRequest:check for cert started #(getTickCount()-request.startTickCount)#</cfoutput>
<cfset var idpCertificateExists = false/>
<cflock scope="application" type="readonly" timeout=1>
<cfset request.APP_NAME=this.Name/>
<cfset idpCertificateExists = structKeyExists(application,"idpCertificate")/>
</cflock>
<cfif NOT idpCertificateExists>
Obtain IDP Certificate (onRequest)
<cfset var idpCertificate = getIdpCertificate(this.idpCertUrl) />
<cflock scope="application" type="exclusive" timeout=1>
<cfset application.idpCertificate = idpCertificate/>
</cflock>
</cfif>
<cfoutput>onRequest:check for cert finished #(getTickCount()-request.startTickCount)#</cfoutput>
<cfset this.redirect_uri = "https://#CGI.SERVER_NAME#/#CGI.SCRIPT_NAME#" />
<cfinclude template="inc/functions.cfm"/>
<cfcookie name="CFID" value="#session.CFID#"/>
<cfcookie name="CFTOKEN" value="#session.CFTOKEN#"/>
<!--- SSO --->
<cflock scope="session" type="exclusive" timeout="3">
<!--- --->
<cfdump var=#session#/>
<cfoutput>#(getTickCount()-request.startTickCount)#</cfoutput>
<!---
Это первая проба, с сессией
Когда протухнет сессия, мы можем пойти к IDP и повторно аутентифицироваться. Поскольку у нас сохраняются куки IDP, его сессия, возможно, будет жива. Если мы обновляли сессию IDP в другом приложении SSO, по всей видимости, она будет продолжаться. Если мы видим, что сессия IDP состарилась и хочет протухнуть, мы можем ее освежить и получить новый access token (который мы пока не используем - мы пользуемся ответом IDP) Наверное, правильно обходиться для этих целей вообще без сессии *** --->
<!---
сделать логаут
сделать отображение ошибки IDP?
+сделать получение сертификата
сделать рефреш
--->
<cfif structKeyExists(session, "auth")>
<cfset request.auth = structCopy(session.auth)/>
<!--- тут нужно сделать проверку и рефреш токена --->
сессия есть
<cfelse>
сессии нет
<cfset session.auth_state=createGUID().toString()/>
<cfscript>
jwt = new lib.jwt(this.client_secret);
idp = new lib.oauth2(this.client_id, this.client_secret, this.auth_endpoint, this.access_token_endpoint, this.redirect_uri);
/*
часто появляется ошибка: после неудачного запроса к IDP
в адресной строке браузера остается все, с чем его редиректил IDP,
а повторный запрос с этим контентом уже не работает. Получаем 400 Bad Request -
может быть, KeyCloak так защищается от циклических редиректов
Не очень понятно, как предотвратить повторный запрос (можно, конечно, использовать сессию, но странно)
*/
writeOutput(getTickCount()-request.startTickCount);
if(structKeyExists(url, "code")) { //обрабатываем редирект от IDP *** наличие поля code в URL введет нас в заблуждение, но эvar = data, label =то только без валидной сессии
dump(var = url.code, label = "URL.code");
// Request access token from idp with the
// authorization code that we got via the URL
//aFormFields = [];
//data = idp.makeAccessTokenRequest((url.code).content, aFormFields);
try {
writeOutput("idp.makeAccessTokenRequest");
writeOutput(getTickCount()-request.startTickCount);
resp = idp.makeAccessTokenRequest(url.code/*, aFormFields*/);
writeOutput("idp.makeAccessTokenRequest Done");
writeOutput(getTickCount()-request.startTickCount);
dump(resp);
data = deserializeJson(resp.content);
//writedump(data);
// Print full response from idp
dump(var = data, label = "makeAccessTokenRequest - Response from idp");
echo('<a href="./index.cfm?refresh=#data.refresh_token#">Refresh token #data.refresh_token#</a>');
session.auth.expires_in = data.expires_in;
session.auth.refresh_expires_in = data.refresh_expires_in;
session.auth.access_token = data.access_token;
session.auth.refresh_token = data.refresh_token;
session.auth.id_token = data.id_token;
session.auth.token_type = data.token_type;
session.idp_response_content = structCopy(data);
//flush()
lock scope="application" type="readonly" timeout="1" {
token_data = (jwt.decode(data.access_token, application.idpCertificate,"RS256"));
}
writeOutput("jwt.decode Done");
writeOutput(getTickCount()-request.startTickCount);
writedump(token_data);
session.auth.login = token_data.preferred_username;
session.auth.wz = token_data.ClientID;
session.auth.fullname = token_data.name;
session.auth.groups = token_data.groups;
session.auth.session_state = token_data.session_state;
session.auth.sid = token_data.sid;
session.auth.auth_time = token_data.auth_time;
session.auth.exp = token_data.exp;
session.auth.iat = token_data.iat;
//session.sid = token_data.sid;
session.token_data = structCopy(token_data);
location(this.redirect_uri,false);
} catch (e) {echo('<br>****************** #e.message# : #e.detail# **********');}
} else {
strURL = idp.buildRedirectToAuthURL({"scope":'openid profile email',"state":session.auth_state,"allow_signup":false});
echo('<a href="#strURL#">self-made Auth link (idp) #strURL#</a> <br> <br>');
location(strUrl,false);
}
</cfscript>
</cfif>
</cflock><!--- session exclusive --->
<cfif structKeyExists(request, "auth")>
<cfinclude template="#ARGUMENTS.template#"/>
<cfelse>
<cfset currentDir = (
lCase(
replace(
getDirectoryFromPath(
replaceNoCase(
expandPath(
ARGUMENTS.template
),
getDirectoryFromPath(
getCurrentTemplatePath()
),
""
)
), "\", "/", "ALL"
)
)
)/>
<!--- <cfif currentDir EQ "saml/"><!--- note traling slash --->
<cfinclude template="#ARGUMENTS.template#"/>
<cfelse>
<cfinclude template="login.cfm" />
</cfif> --->
</cfif>
<cfreturn />
</cffunction>
<cffunction
name="OnRequestEnd"
access="public"
returntype="void"
output="true"
hint="Fires after the page processing is complete.">
<!--- Attention! Before CF9, OnrequestEnd is not executed in case of redirect. That is why we use session.save_login --->
<cfif structKeyExists(session, "save_login")>
<cfif session.save_login EQ "">
<!--- unset (expire) cookie --->
<cfcookie expires="-1" name="portalUser" value="">
<cfelse>
<!--- set persistent cookie with no expiration --->
<cfcookie expires="NEVER" name="portalUser" value="#encrypt(session.save_login,COOKIEENCKEY)#">
</cfif>
<cfset structDelete(session, "save_login")>
</cfif>
<cfreturn />
</cffunction>
<cffunction
name="getStand"
access="private"
returntype="string"
output="true"><!--- *** duplicated in svc-api --->
<cftry>
<cfquery name=qConfig>
select value as stand from config
where name='STAND'
</cfquery>
<cfreturn qConfig.stand/>
<cfcatch type="ANY">
<!--- do nothing, default will be returned --->
</cfcatch>
</cftry>
<cfreturn ""/>
</cffunction>
<cffunction
name="getDS"
access="private"
returntype="struct"
output="true"
hint="Configure data source from environment variables. Convention: data source name is an environment varialble prefix">
<cfargument name="dsname" type="string" required="true"/>
<cfargument name="prefix" type="string" default=#dsname#/>
<cfset system = createObject("java", "java.lang.System")/>
<cfset var ds={}/>
<cfloop list="class,connectionString,database,driver,dbdriver,host,port,type,url,username,password,bundleName,bundleVersion,connectionLimit,liveTimeout,validate" item="field"><!--- driver vs dbdriver --->
<cfset var value=system.getEnv("#arguments.prefix#_#field#")/>
<cfif isDefined("value") AND len(value)>
<cfset structInsert(ds,field,value)/>
</cfif>
</cfloop>
<cfif structIsEmpty(ds)>
<cfthrow type="application" message="Datasource not configured" detail="Datasource not defined in the environment. Expected prefix is #arguments.prefix#"/>
</cfif>
<!--- test datasource (just to get exception if invalid) --->
<cftry>
<cfquery name="qTestDs" datasource=#ds#>
select 1;
</cfquery>
<cfcatch type="any">
<!--- <cfdump var=#ds#/><cfabort/> --->
<cfrethrow/>
</cfcatch>
</cftry>
<cfreturn ds/>
</cffunction>
<cfscript>
//https://keycloak.nubes.ru/admin
//https://keycloak.nubes.ru/realms/SSH_CA/account //smishchuk@mgmt.nubes.ru
//https://stackoverflow.com/questions/28658735/what-are-keycloaks-oauth2-openid-connect-endpoints
//http://https://keycloak.nubes.ru/realms/SSH_CA/.well-known/openid-configuration
//https://keycloak.nubes.ru/realms/cloud/.well-known/openid-configuration тут ссылка
//https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs тут серт
//только надо его обрамить -----BEGIN CERTIFICATE-----
function getIdpCertificate(certUrl) {
var httpService = new http();
httpService.setMethod( "get" );
httpService.setCharset( "utf-8" );
httpService.setUrl(arguments.certUrl);
var result = httpService.send().getPrefix();
var status_code = result.ResponseHeader['Status_Code'];
if ('200' == status_code) {
var content = deserializeJson(result.FileContent);
//мы подразумеваем структуру конкретно KeyCloak
var key = "";
for (key in content.keys) {
if ("RSA" == key.kty AND "sig" == key.use) {
return "-----BEGIN CERTIFICATE-----" & key.x5c[1] & "-----END CERTIFICATE-----";
}
}
throw(message="RSA cetificate not found");
} else {
throw (message="Cannot obtain IDP certificate, request failed", detail="Status_Code #status_code#");
}
}
function auth() {
client_id = "payg-report.deck.nubes.ru"
client_secret = "********"
auth_endpoint = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/auth"
access_token_endpoint = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/token"
redirect_uri = "https://localhost/payg-report/"
jwt = new lib.jwt(client_secret);
idp = new lib.oauth2(client_id, client_secret, auth_endpoint, access_token_endpoint, redirect_uri);
// Get URL that the user will click on and grant our application all necessary permissions
strURL = idp.buildRedirectToAuthURL({"scope":'openid profile email',"state":createGUID().toString(),"allow_signup":true});
echo('<a href="#strURL#">self-made Auth link (idp) #strURL#</a> <br> <br>');
//redreshURL = github.refreshAccessTokenRequest();
if(structKeyExists(url, "code")) {
writedump(url.code);
// Request access token from idp with the authorization code that we got via the URL
data = deserializeJson(idp.makeAccessTokenRequest(url.code/*, aFormFields*/).content);
// Print full response from idp
dump(var = data, label = "makeAccessTokenRequest - Response from idp");
try {
//parsed=getParamsFromUrlString(data);
writedump(data);
echo('<a href="./index.cfm?refresh=#data.refresh_token#">Refresh token #data.refresh_token#</a>');
//https://keycloak.nubes.ru/realms/cloud/.well-known/openid-configuration тут ссылка
//https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs тут серт
//только надо его обрамить -----BEGIN CERTIFICATE-----
writedump(jwt.decode(data.access_token,"-----BEGIN CERTIFICATE-----
MIICmTCCAYECBgGG7361eDANBgkqhkiG9w0BAQsFADAQMQ4wDAYDVQQDDAVjbG91ZDAeFw0yMzAzMTcxMjEzMjRaFw0zMzAzMTcxMjE1MDRaMBAxDjAMBgNVBAMMBWNsb3VkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn2segSPrciUFaD7Fa+brR9JdZknQr0F8zCzYQdTPsZJMtYnVPuE7MdZlbtGQ9n/HjcUst8FINjMONhzzbwVQSRZHH57pbAEm4r7fM3QDEAKXGERtDXhVLJGQSkg17X9zSWZs4RwkbxNsG6r+3/GT+U75lTG+/LKKzdG5OHK7Wwnrsiqy7sg3wAPFtlSwbebMdXJ70FosEI1SVhPRDn+LuVH3WINvijQU1GV2srWPwZl16fdXDele6NkvnC032l00pTbkVbgBLgySR0sPsI1s5AuMTT//nA0Xm5Ss40SwLJX2BYWyEALvEYdVt9wUZU2QXcZLLgmsCcFye4HjXa2CAwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBlvkOLPRG6+tB30ZElwKSh/xrptnxgTf93RnS4IUDZebSolR5V/77PFAuqw4DTIlBNtJ6i1ffmyvtZIAMlm3sMZK0GuQ+SFq72DHxYzSmZ61cSS5YFKKyHcX3JIFMXYLmrw11GXt69V3xB8/Y0+BnBBpDD7ZKDdXdQa+9IWsERdTAIFk7ucwiG3BuTOJbzU1d+m8hNIVL4+dYR1TAnA9QPaJaQj0kUD0DYgXcIrrTFIQF0IPeB9I+eOyJ0FxJkukffX7QLVGFrc3+dVRHSSWmMpXi0B/VXT5DlsFDstEldH+/r3XnXAY6qadciyksSBRSXR4Rm9ZEq/xk+VmcxomWc
-----END CERTIFICATE-----","RS256"));
} catch (e) {echo('<br>****************** #e.message# : #e.detail# **********');}
}
if(structKeyExists(url, "refresh")) {
// With the refresh_token we can easly request a new access token
refreshedToken = deserializeJson(idp.refreshAccessTokenRequest(url.refresh).content);
dump(var = refreshedToken, label = "refreshAccessTokenRequest - Response from IDP");
echo('<br> <a href="./index.cfm?refresh=#refreshedToken.refresh_token#">Refresh token #refreshedToken.refresh_token#</a>')
writedump(jwt.decode(refreshedToken.access_token));
}
}
</cfscript>
</cfcomponent>
+8
View File
@@ -0,0 +1,8 @@
{
"ds_dwh_class": "org.postgresql.Driver",
"ds_dwh_connectionString": "jdbc:postgresql://db-services.adl.nubes.ru:5432/dwh",
"ds_dwh_username": "smishchuk",
"ds_dwh_password": "encrypted:********",
"ds_dwh_connectionLimit": "5",
"IDP_CLIENT_SECRET": "********",
}
+10
View File
@@ -0,0 +1,10 @@
REM set Windows env
setx ds_dwh_class org.postgresql.Driver /M
setx ds_dwh_connectionString jdbc:postgresql://db-services.adl.nubes.ru:5432/dwh /M
setx ds_dwh_username smishchuk /M
setx ds_dwh_password encrypted:******** /M
setx ds_dwh_connectionLimit 5 /M
setx IDP_CLIENT_SECRET ******** /M
pause
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

+47
View File
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW X8 -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="78.6273mm" height="70.4009mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 37746 33797"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
<![CDATA[
.fil3 {fill:none}
.fil2 {fill:#D7F372}
.fil4 {fill:#FEFEFE;fill-rule:nonzero}
.fil5 {fill:#638328;fill-rule:nonzero}
.fil1 {fill:url(#id1)}
.fil0 {fill:url(#id2)}
]]>
</style>
<clipPath id="id0">
<path d="M20432 0c8718,-38 15581,2266 15458,9209 -25,787 -197,745 -1206,434 -5376,-1662 -8578,-3016 -12410,-6248 -1067,-900 -1945,-1797 -2743,-2837 -478,-648 -8,-545 901,-558zm-18416 19428c1785,-4186 2803,-6725 6956,-9214 1814,-1088 3728,-1795 5744,-2401 5011,-1469 9917,-953 14495,540 1697,562 2833,1208 4123,2158 602,450 989,178 1872,-71 402,-113 1572,-529 1912,-305 933,615 -675,1120 -1291,1389 -1798,785 -1256,251 -1265,1780 -43,7030 -7302,11174 -13250,12374 -3409,688 -7029,1146 -9343,1499 -5916,900 -5060,-1185 -9071,-2819 -937,-381 -2531,-341 -2879,-1361 -223,-655 1540,-2751 1997,-3569z"/>
</clipPath>
<linearGradient id="id1" gradientUnits="userSpaceOnUse" x1="-740.954" y1="15224.8" x2="37478.6" y2="11458.4">
<stop offset="0" style="stop-opacity:1; stop-color:#C6C517"/>
<stop offset="1" style="stop-opacity:1; stop-color:#E7D900"/>
</linearGradient>
<linearGradient id="id2" gradientUnits="userSpaceOnUse" x1="-442.19" y1="20004.6" x2="37830.6" y2="16055.8">
<stop offset="0" style="stop-opacity:1; stop-color:#89A423"/>
<stop offset="1" style="stop-opacity:1; stop-color:#638429"/>
</linearGradient>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<path class="fil0" d="M22767 31689l-14060 2085c-2226,330 -4572,-2956 -6349,-3695 -1559,-649 -1653,-822 -1915,-2004 -266,-1196 -259,-3137 -401,-4460 -150,-1391 203,-1130 973,-2123 591,-795 964,-1292 1359,-2228 1413,-3396 2313,-5352 5285,-7695 3781,-2753 8236,-4067 12877,-4299 774,-89 484,-275 112,-747 -812,-1079 -1165,-2747 -1381,-4068 -68,-416 -308,-2197 198,-2372 228,-79 1093,72 1388,100 101,9 200,16 301,22 1094,51 2280,-41 2615,-17 4852,417 10503,1550 11899,7016 226,935 209,1325 200,2255 -2,142 -8,1026 126,1086 215,97 947,-1057 1467,133 110,344 145,764 169,1126 8,120 17,237 29,356 91,880 115,1755 53,2638 -23,319 -23,817 -223,1077 -611,795 -1576,1292 -2268,2065 -435,506 -635,1974 -834,2703 -720,2633 -1869,4361 -3594,4590l-7936 1054 -90 5402z"/>
<path class="fil1" d="M20432 0c8718,-38 15581,2266 15458,9209 -25,787 -197,745 -1206,434 -5376,-1662 -8578,-3016 -12410,-6248 -1067,-900 -1945,-1797 -2743,-2837 -478,-648 -8,-545 901,-558zm-18416 19428c1785,-4186 2803,-6725 6956,-9214 1814,-1088 3728,-1795 5744,-2401 5011,-1469 9917,-953 14495,540 1697,562 2833,1208 4123,2158 602,450 989,178 1872,-71 402,-113 1572,-529 1912,-305 933,615 -675,1120 -1291,1389 -1798,785 -1256,251 -1265,1780 -43,7030 -7302,11174 -13250,12374 -3409,688 -7029,1146 -9343,1499 -5916,900 -5060,-1185 -9071,-2819 -937,-381 -2531,-341 -2879,-1361 -223,-655 1540,-2751 1997,-3569z"/>
<g style="clip-path:url(#id0)">
<g id="_3107826610240">
<path id="1" class="fil2" d="M32620 15645c91,-46 98,-37 3,-91 -66,80 -20,59 -3,91zm-9180 173l399 13 94 3 24 -102c121,-34 39,27 76,-81l-104 -24c-76,-2 -129,-55 -130,-59 -3,-10 -11,-11 -18,-15l-68 -4c-94,14 -151,38 -213,69l-167 12 -8 120 12 65 103 3zm3362 -16369c31,57 -35,35 43,50 123,23 4,11 64,-18 -27,-64 39,-43 -41,-56 -131,-22 -7,-12 -66,24zm10290 3584c-14,-80 10,-36 -56,-77 -2,4 -94,5 -19,84 51,53 74,-7 75,-7zm2277 11808c100,-46 108,-71 4,-122 -65,81 -40,56 -4,122zm-598 -13384c72,-96 70,-72 -25,-113 -75,90 -74,70 25,113zm-486 7658c-47,-62 -81,7 -83,7 65,99 -66,22 64,80 3,-6 100,22 19,-87zm-14361 -9918c35,-131 44,-89 -39,-138 -4,7 -53,-26 -31,67 27,121 -23,26 70,71zm13953 15010c7,-87 -6,-35 -58,-63 -74,84 -46,57 -4,129 45,-22 53,54 62,-66zm1320 -15163c106,-113 26,-91 4,-126 -51,29 -67,-45 -62,71 4,73 20,40 58,55zm2646 15025c-2,-2 9,-68 -88,-57 -109,12 -37,7 -73,64 105,50 64,60 161,-7zm-292 -3726c48,-52 47,-33 49,-171 -84,-2 -93,-38 -195,78 -83,11 -33,-18 -92,47l115 91c47,-29 48,-35 123,-45zm-2986 3302c-113,22 -40,12 -65,57 182,135 184,-23 184,-24 -10,-6 19,-60 -119,-33zm-1300 1033c-76,-44 -26,-43 -193,-4 18,157 33,163 111,169 166,12 14,18 79,-36l3 -129zm-28 818c-15,-28 43,-120 -226,-46 35,72 -28,65 93,92 164,37 124,-39 133,-46zm-7887 -16516l182 4c21,-158 -15,-177 -161,-176l-21 172zm1556 1675l148 114c99,86 124,57 174,-16 -50,-145 -12,-36 -146,-105 -44,-243 65,-253 -76,-325 -82,93 -25,15 -43,187 -15,145 -10,6 -57,145zm-16717 6826c58,-32 47,42 53,-46 7,-83 4,-30 -50,-59l-24 38c3,61 -11,24 21,67zm-1336 -2651c25,-6 44,9 63,-22 77,-123 10,-42 -8,-80 -80,40 -47,5 -55,102zm-4579 -6954l-112 -3 26 95c101,-38 42,50 86,-92zm7494 3833c33,-24 94,21 33,-122 -79,33 -49,-52 -62,48 -20,150 -16,19 29,74zm14390 12465c-110,-30 -18,-3 -62,20 24,35 -18,154 116,33 -22,-35 -5,-40 -54,-53zm-16336 1107c44,-72 -19,-62 -22,-69 -108,42 -55,-27 -72,102 120,-4 51,36 94,-33zm-15555 -8727c0,-1 54,27 19,-104 -41,1 -53,-32 -83,34 -36,76 49,66 64,70zm29578 -7130c115,91 90,22 123,-26 -55,-41 62,-61 -72,-36 -85,16 -30,37 -51,62zm-15613 10133c8,-12 163,46 3,-107 -158,125 -4,106 -3,107zm19829 6238c-113,-3 -59,-5 -148,25 75,104 35,82 146,96l2 -121zm-1810 -750c-9,127 22,73 56,93 13,-18 98,-37 6,-177 -40,23 -55,-4 -62,84zm-22909 -1701c110,-49 103,-21 88,-170l-170 17 -8 103 29 61 61 -11zm17260 -7459c57,-32 46,52 67,-70 25,-145 -10,-61 -33,-93 -62,23 -49,-63 -69,61 -24,151 20,79 35,102zm6292 8218c-86,10 -54,14 -87,55 20,17 25,52 112,48 130,-7 69,-26 89,-71 -34,-23 -5,-44 -114,-32zm-18726 -12582l138 126c48,-78 33,-47 37,-156 -115,-27 -88,-44 -175,30zm5425 2089c112,8 43,39 121,-26l69 -111c-57,-38 50,-12 -63,-36 -108,-23 -8,-17 -111,3l-16 170zm199 -5155c68,-15 102,32 91,-91 -10,-106 -55,-86 -91,-103 -91,200 -13,173 0,194zm-4498 9344c44,-116 -2,-63 -8,-78 -188,-98 -154,47 -70,159 12,-9 44,9 78,-81zm-14595 -8298l-37 -85 -225 -25c13,84 -5,39 37,90 11,13 11,8 29,27 101,111 -29,62 100,79 134,17 77,-16 96,-28l0 -58zm16516 14224c-51,-40 -1,-28 -113,-50 -41,-8 -243,-20 -290,67 61,129 108,18 237,86 55,29 -10,50 104,69 198,32 132,-42 146,-52 -49,-181 23,-57 -89,-111l5 -9zm-15097 58c48,-69 44,-72 16,-145 -273,51 -22,42 -250,167 31,-165 -35,-99 -48,-114l-10 228 209 8 83 -144zm10508 -4775c26,-191 49,60 -34,-54 -80,69 -76,58 -4,123 52,-55 25,22 38,-69zm2333 -7579c33,-5 125,10 56,-109 -99,52 -45,-60 -56,109zm-3430 -2611c31,53 -29,36 45,50 112,21 9,9 62,-17 -23,-52 62,-39 -40,-56 -76,-13 -10,-11 -67,23zm-5194 1548c20,-171 28,-57 -48,-102 -23,40 -71,-39 -25,67 24,53 -2,25 73,35zm2622 14176c16,-129 5,-16 -32,-67 -96,48 -105,68 -4,128 34,-41 21,52 36,-61zm20631 -662c17,-119 -2,-25 -34,-66 -97,47 -110,67 -4,121 35,-34 24,49 38,-55zm-26456 -15122c101,69 78,57 133,-25 -30,-22 47,-55 -72,-37 -124,19 -29,27 -61,62zm-3047 11843c12,19 -43,82 103,51 57,-13 47,-31 63,-80 -75,-40 -83,-41 -168,-21l2 50zm590 1476c-68,85 -67,86 -5,161 100,-47 96,-110 5,-161zm9676 2249c132,-45 120,-6 96,-144 -185,-46 -50,-16 -91,31 11,22 4,32 23,36 49,12 16,9 52,-9 -39,-41 -1,-18 -75,-27 -8,6 -42,26 -44,28 -15,11 -32,39 -36,33 -3,-7 -12,13 -19,19l7 24c-83,-5 -17,-34 -119,21l-151 150c-7,14 -26,96 -30,118 184,-1 47,-2 195,-98 58,-38 107,-51 184,-77l17 -88 -9 -17zm-10949 -16354c55,-82 68,-123 -24,-178 -4,5 -49,-31 -45,89 4,131 35,74 69,89zm5381 2060c95,56 114,57 192,-23 -73,-75 -188,-91 -192,23zm4150 14183c1,-1 64,-22 50,-106 -19,-117 0,-36 -73,-72 -30,39 -121,103 23,178zm17483 -2004c-59,-80 -103,-72 -188,-35 18,24 -70,68 84,81 141,12 94,-39 104,-46zm-13680 -1675c141,42 169,46 247,-29 -37,-39 -45,-69 -145,-59 -99,10 -73,22 -102,88zm-8064 1221l-36 23c-90,81 -54,49 -56,120 261,25 188,-170 188,-171 -115,-7 34,-13 -60,2l-36 26c7,17 -3,42 39,48 3,1 16,-4 19,-4 5,0 15,-7 23,-10 -39,-35 6,-19 -81,-34zm8633 -1952c-7,-10 54,-79 -137,-26 9,87 13,131 90,196 33,-28 19,-1 55,-52 24,-33 -22,88 23,-39 49,-141 4,-71 -31,-79l-78 -1 25 81 53 -80zm-7088 2769c-11,-74 -88,-139 -148,-163l-43 119 162 129c15,-21 48,44 29,-85zm-7692 303l-2 61 261 28c11,-216 -161,-128 -259,-89zm39584 -10253c14,28 -26,64 65,64 135,1 27,20 78,-60 -44,-33 11,-44 -75,-39 -129,8 -18,-2 -68,35zm419 750c28,-36 34,52 41,-69 10,-164 -9,-60 -36,-101 -30,17 -56,-27 -71,73 -20,138 30,78 66,97zm3066 2473c55,-72 68,-95 66,-198 -92,-19 -136,-38 -155,50 -18,87 89,148 89,148zm2396 -3620c57,42 -52,30 106,49 159,20 20,7 113,-14 -22,-95 28,-126 -112,-132 -102,-5 -86,13 -107,97zm-718 4372l-51 -56c213,-116 92,-238 -70,-239 -152,-1 -176,38 -165,195l14 39c15,128 95,141 227,140l45 -79zm-11882 -7680c96,59 33,27 76,3l-58 -18c-3,-8 -12,11 -18,15zm-21198 15445c35,43 20,47 60,29 5,-2 14,-15 22,-22l-82 -7zm5007 1132l97 3 -6 -58c-40,-60 5,-36 -76,-65 -35,-12 -55,0 -88,1l5 117 68 2zm19326 -14421l-61 0c-35,54 -28,-70 -32,67 -4,136 11,60 30,93 73,-19 31,14 65,-50 146,-35 47,16 96,-68 -57,-55 15,-32 -98,-42zm-8429 13335c39,-6 206,-169 -164,-173 -70,95 -80,76 -102,170l266 3zm14571 -9261c47,74 57,123 127,4 -116,-124 -105,-20 -127,-4zm909 -1194c55,84 170,131 199,-23 -26,-14 -10,-39 -115,-26 -57,8 -60,10 -84,49zm271 2163c-1,-1 34,-56 -85,-37 -107,17 -28,-8 -84,61 38,68 -52,70 107,81 68,5 70,-17 106,-46 -12,-97 2,-33 -44,-59l-117 15 83 62c43,-50 20,-9 34,-77zm2227 -30c105,19 81,28 165,-11 -16,-86 -60,-131 -144,-155 -48,81 -43,60 -21,166zm-680 -1938c36,-37 13,13 35,-54 59,-184 69,-195 19,-219 -7,-2 -19,-13 -22,-4 -3,7 -75,-30 -95,109 -15,102 -6,135 63,168zm-7887 -1031c174,9 174,-15 198,-181l-195 0 -3 181zm-434 -3677c0,-132 -97,-207 -219,-204 -14,163 61,224 219,204zm9067 10670l-228 -20c15,143 32,200 191,182 20,-35 15,-15 29,-68 0,-1 7,-80 8,-94zm-11458 -8654l180 15c41,-77 53,-78 67,-187l-240 -2 -7 174zm-13484 -1787c67,65 -100,40 38,31 70,-5 24,3 66,-28 -77,-64 98,-40 -43,-30 -87,6 4,-25 -61,27zm15318 6420c8,8 -37,96 94,3 -76,-59 111,-37 -40,-27 -71,5 -10,-11 -54,24zm-4361 -5494c0,-176 44,-57 -80,-98 19,109 -24,65 80,98zm5777 11913c-52,-67 -18,-71 -104,-32 75,108 -101,-50 19,46 3,3 11,10 15,12 122,59 35,-5 70,-26zm452 -9192c-16,-105 17,-46 -64,-89 -51,58 -31,28 -37,112l0 24c139,141 57,117 171,135l19 -142 -89 -40zm1300 -184c26,36 -55,67 176,58 3,-16 70,-189 -107,-115 -68,28 -31,-2 -69,57zm-6645 5321c35,-145 -23,-89 -32,-106 -123,17 -84,-60 -108,72 -22,127 47,87 73,100 61,-30 38,56 67,-66zm12539 -5533c161,1 121,36 140,-122 -54,-35 -31,-46 -160,-30 -8,73 -19,77 20,152zm-7898 4642l158 -3 13 -151 -160 -4 -11 158zm-17042 -7038c56,111 45,115 104,4 -52,-38 -53,-32 -104,-4zm9439 14921c154,-74 34,-104 32,-108 -148,63 -33,108 -32,108zm-15492 -14617c77,-131 38,-84 -75,-106 31,146 -22,74 75,106zm2595 5412c115,-55 112,-64 4,-122 -16,20 -39,-42 -33,60 3,61 1,30 29,62zm3716 -5475c14,118 -32,80 92,86 38,-95 6,-127 -92,-86zm-11754 7101c6,-101 5,-86 -98,-105 -13,127 -2,118 98,105zm5801 -8233c54,-27 68,45 62,-68 -3,-75 -27,-45 -58,-61 -2,3 -85,14 -4,129zm-10835 7881c-39,-69 -44,-121 -135,-4 60,52 -67,23 67,40 113,15 27,-3 68,-36zm25397 -740c-39,10 -173,13 -98,95 96,105 86,-47 98,-95zm-2065 8351c-44,-72 23,-10 -75,-89 -65,-51 0,-9 -75,-42l-42 107 31 161c92,9 87,6 142,-32l19 -105zm-14954 -14214c87,52 55,48 150,6 -45,-139 -121,-139 -150,-6zm2674 8592c-160,2 -83,47 -93,81l164 16c3,-66 28,-97 -71,-97zm-12857 -11651c60,116 145,73 198,6 -88,-66 -119,-55 -198,-6zm14730 9603c8,31 -35,70 85,81 110,11 71,-14 85,-76 -83,-43 -68,-37 -170,-5zm-1945 -4959c-114,-51 -60,-57 -140,3l-4 58c93,64 166,73 228,-21 -41,-48 23,-26 -84,-40l-116 0c37,83 -28,35 83,68 54,-39 15,12 33,-68zm1791 10456c-76,-57 -141,-72 -205,22 16,13 16,57 118,48 109,-8 68,-30 87,-70zm6791 -1117c36,-46 36,70 46,-94 8,-128 -24,-68 -40,-87 -41,17 -64,-27 -71,84 -7,141 28,77 65,97zm-19845 -1831c156,4 126,-56 115,-191 -148,46 -119,6 -115,191zm28588 2560c110,14 138,-57 145,-166l-129 10c-85,158 -16,155 -16,156zm-24535 1960c-95,25 -67,45 -80,133 123,4 100,21 190,-35 -15,-82 23,-133 -110,-98zm-1340 -12555c34,-29 35,29 35,-82 -176,-85 -220,125 -198,245 233,90 139,21 170,-18l-9 -56 2 -89zm-138 10191c7,-3 15,-9 19,-11 187,-98 143,-30 160,-133 -81,-49 -97,-61 -235,49 -9,7 -14,11 -18,14l-10 -4 3 8c-6,4 -7,6 -36,40 48,43 -12,16 62,44 104,41 37,-1 55,-7zm8367 -12746l142 -3 17 -140c-107,-42 -56,-44 -174,-39 -39,107 -19,70 15,182zm13541 9864c19,-155 31,-118 -58,-202l-114 -68 -18 135c5,4 38,33 47,42 111,117 -30,57 143,93zm988 4753c45,-102 30,10 23,-135l-34 -127c-82,44 -10,4 -55,41l-47 40c-59,65 -45,-8 -44,128 63,55 64,54 157,53zm12225 -12623c69,-36 48,37 60,-51 11,-77 1,-29 -27,-74 -74,34 -47,-58 -61,47 -12,85 -16,23 28,78zm-541 532c79,-38 56,43 72,-73 18,-134 -33,-95 -37,-102 -62,28 -51,-64 -71,68 -26,164 18,78 36,107zm3249 -2408c42,-47 40,67 48,-70 9,-158 -18,-67 -43,-99 -62,25 -63,-61 -81,69 -20,138 47,86 76,100zm1303 9111c11,10 -39,54 99,53 166,-1 78,-27 103,-76 -9,-7 35,-50 -103,-50 -165,1 -70,41 -99,73zm-491 -3647c91,-9 105,-16 198,-88 -55,-161 -128,-160 -199,-171 8,167 44,104 1,259zm-24692 -3316c89,44 53,43 105,-26 -38,-27 54,-78 -66,-29 -4,1 -13,8 -16,10l-23 45zm13671 13200c-34,-129 31,-90 -104,-104 13,123 -20,66 104,104zm-2531 -392c-27,-46 15,-108 -118,-32 19,31 -50,43 47,68 133,33 20,3 71,-36zm7334 520c-76,-6 -56,36 -71,58 59,45 -67,20 67,36 129,15 17,4 69,-31 -26,-54 52,-54 -65,-63zm-2346 -1174c-22,-102 14,-11 -61,-51 -44,43 -78,-66 -39,94 19,78 18,22 64,42 41,-48 53,-4 36,-85zm-2672 1531c-126,3 -69,18 -100,66 34,27 41,99 222,7 -23,-40 -10,-76 -122,-73zm2389 -1391c-144,-10 -215,11 -139,175l166 10 -27 -185zm-13510 -6878c31,-55 21,-40 3,-86 -56,59 -65,-88 -32,42 34,130 -97,-14 29,44zm11036 7899c51,38 -7,20 62,28 135,17 -25,23 42,-24 -37,-35 4,-24 -62,-33 -161,-23 46,-43 -42,29zm-26597 -10879c62,73 10,58 96,32 -17,-44 72,-25 -23,-45 -72,-14 -23,-8 -73,13zm24877 10019c-13,-82 1,-14 -47,-36 -75,86 -26,63 26,92 24,-39 30,7 21,-56zm-13301 -13607c15,-24 58,33 23,-60 -25,-65 14,-8 -49,-43 -39,74 -63,63 26,103zm-1474 10770c72,-89 63,-70 -26,-109 -101,108 -21,86 26,109zm2490 -9768c5,-7 104,11 5,-148 -44,51 -53,-76 -44,73 6,81 4,33 39,75zm-455 582l45 -26c-21,-110 32,-69 -101,-93 -6,111 -40,72 56,119zm-2645 4875c5,-126 -3,-96 -98,-104 -11,117 -39,123 98,104zm-15387 -7335c18,35 -39,43 62,61 137,25 73,-13 98,-27 -5,-10 32,-155 -160,-34zm3775 14905c-5,113 34,83 37,87 96,-48 93,-123 5,-181 -22,29 -35,-53 -42,94zm16124 -7293c1,0 19,130 175,5 -14,-31 12,-58 -77,-63 -125,-7 -71,37 -98,58zm4169 4706c36,-17 59,39 73,-89 14,-124 -31,-78 -39,-88 -47,21 -58,-27 -69,83 -13,129 26,80 35,94zm-14149 1449c-78,-12 -84,28 -88,128l195 -3c-12,-79 -17,-110 -107,-125zm-10285 -377c144,13 156,25 270,-28 -59,-65 -141,-121 -249,-121l-21 149zm30877 -12750c85,40 49,47 105,-26 -20,-16 24,-117 -105,26zm-4545 -547c57,-82 74,-71 -25,-119 -65,93 -66,76 25,119zm6390 36c29,-122 42,-90 -84,-116 14,175 -38,71 84,116zm5154 2987c-1,45 -19,42 30,111 107,-34 39,71 81,-92 -1,-4 -13,-87 -13,-87 -16,-49 -13,-36 -31,-65 -83,37 -49,-29 -67,133zm-7078 -529c164,-26 122,59 107,-100 -108,-4 -71,-31 -107,100zm1289 -911c4,-125 47,-86 -67,-119 -93,100 -38,96 67,119zm2389 12606c-126,16 -58,-23 -117,61 78,102 120,95 117,-61zm-6679 -14484c93,-49 101,-26 33,-126 -50,15 -41,-45 -66,34 -45,140 4,62 33,92zm-6632 -463c15,26 -10,57 69,74 138,32 72,-15 95,-30 -35,-82 47,-48 -65,-68 -29,-6 -93,19 -99,24zm9162 3323c39,-11 64,56 82,-82 14,-103 -25,-89 -47,-113 -98,45 -81,123 -35,195zm11121 7323c77,-41 52,57 68,-98 6,-49 -11,-65 -20,-97 -60,22 -76,-44 -92,91 -17,134 36,91 44,104zm-6944 6433l64 2c35,-109 52,-107 -11,-201 -29,8 -65,-56 -82,91 -8,64 4,48 29,108zm-9851 -12707c33,-80 14,-192 -50,-252 -80,-76 -14,-26 -117,-47 51,222 26,39 90,163 44,86 -28,59 77,136zm17007 11129c-5,-4 -12,-10 -18,-14l-82 -58c-96,106 -9,225 150,201 10,-144 19,-76 -50,-129zm-14523 -7357l6 118 177 17 4 -157c-119,-17 -93,-25 -187,22zm1634 621c122,-10 52,43 137,-39 82,-80 30,-20 53,-141l-179 10 -11 170zm4069 -5651l169 46c4,-99 16,-85 -35,-146 -85,-102 -17,-50 -154,-73l20 173zm10176 12053c-10,-85 13,-6 -49,-52 -38,41 -37,-9 -30,69 9,97 -12,14 55,43 37,-56 37,58 24,-60zm-8682 -13172c37,61 -40,39 51,54 69,12 24,3 66,-21 -13,-32 49,-134 -117,-33zm2107 1274c32,-19 113,33 33,-122 -78,35 -50,-47 -63,48 -17,129 -11,23 30,74zm-2180 -3663l-108 -3c2,174 -2,49 42,106 98,-52 42,59 66,-103zm10237 6623c21,-30 58,43 35,-71 -21,-101 17,-22 -68,-66 -52,93 -66,71 33,137zm-4681 8279c36,-113 -28,-91 -30,-94 -79,34 -36,-30 -61,65 -8,29 10,72 15,95 50,-25 47,25 76,-66zm1712 -10475c91,-11 72,27 106,-40 54,-109 -37,-81 -62,-94l-37 44c-16,57 -18,8 -7,90zm-2158 653c14,19 -16,66 79,65 118,-2 32,5 75,-60 -18,-16 33,-129 -154,-5zm-9161 -4516c140,63 104,33 149,-46 -10,-8 40,-74 -77,-47 -186,44 -11,10 -72,93zm14791 10390c-148,-15 -74,13 -105,64 54,49 -82,47 102,53 102,4 98,-46 99,-47 -19,-29 7,-60 -96,-70zm-7396 -6688c36,71 -84,46 67,61 7,-6 18,-26 21,-20l74 -89c49,-90 34,-58 -1,-120 -66,20 -27,3 -73,42 -4,4 -10,10 -14,14 -4,4 -10,10 -14,14 -5,5 -12,11 -16,16l-35 33 -9 49zm3325 -2979c18,41 -50,73 94,76 129,2 71,-21 95,-70 -6,-6 38,-52 -90,-53 -164,-1 -55,12 -99,47zm-4326 1161l115 0c21,-126 29,-84 -30,-190 -116,49 -118,87 -85,190zm5264 1728c3,-4 48,17 51,-93 3,-169 -3,-47 -45,-100 -39,16 -76,-51 -89,107 -7,77 16,64 83,86zm3737 8908c127,-174 17,-185 6,-201 -65,17 -98,-21 -96,100 3,114 51,86 90,101zm-578 -7651c-69,-84 28,-32 -83,-63 -47,-14 -89,-4 -137,1 12,162 117,193 220,62zm-10792 -2729c100,-7 112,56 202,-184l-175 3 -27 181zm11216 4612c69,-72 57,-54 46,-178l-200 -7c-4,7 -10,9 -11,18l-76 95c135,22 67,-7 160,87l81 -15zm-25274 1701c77,60 7,56 87,3 -48,-47 101,-40 -34,-29 -73,6 -3,-17 -53,26zm-2320 -4177c8,14 14,124 93,3 -55,-40 95,-28 -36,-22 -55,3 -22,-1 -57,19zm3531 6166c27,41 -51,47 54,45 61,-2 16,-6 40,-42 -34,-25 -1,-17 -55,-23 -3,0 -17,14 -19,7 -3,-7 -13,9 -20,13zm9742 -9188c141,-30 64,23 96,-75 -192,-10 -27,10 -96,75zm-816 7909c14,-101 12,5 -30,-35 -126,99 -4,94 -3,96 46,-55 21,17 33,-61zm4718 4713c-57,112 -6,23 20,71 19,-13 146,-53 23,-91 -70,-21 -30,-5 -43,20zm-8122 -431c-16,-86 16,-10 -58,-43 -83,124 13,93 34,107 35,-58 47,63 24,-64zm17489 -3007c175,99 121,19 148,5 -163,-141 -131,-17 -148,-5zm-22342 4930c132,-4 153,38 191,-77l-183 -33c-126,37 -56,-3 -107,63 48,51 -83,44 99,47zm12980 -12068c-5,14 -15,15 -16,31 -2,16 -12,19 -13,27 -6,30 -6,60 -4,92l176 14 5 -153 -148 -11zm3361 -432c36,-54 25,-37 3,-87 -60,72 -60,-95 -28,43 33,144 -77,-37 25,44zm-4106 70c11,-16 62,31 29,-65 -27,-79 22,-7 -54,-51 -28,44 -74,-63 -27,70 23,65 -11,17 52,46zm4107 -1014c84,-42 48,57 62,-54 19,-151 13,-10 -29,-78 -90,38 -52,-66 -66,48 -12,105 -22,20 33,84zm5309 -1291c25,-37 79,60 36,-83 -31,-104 27,-9 -60,-59 -32,47 -83,-71 -36,83 27,91 -22,17 60,59zm1248 6583c63,-42 37,35 61,-54 36,-132 -10,-66 -27,-91 -56,21 -39,-53 -66,42 -50,177 2,67 32,103zm-3412 -2551c58,-28 78,64 72,-75 -4,-112 -22,-47 -68,-70 0,1 -117,-7 -4,145zm-290 -1225c21,58 -53,43 42,70 192,56 47,8 103,-36 -35,-66 28,-44 -52,-65 -126,-33 -82,23 -93,31zm-5356 -3095l-18 46c15,128 58,97 106,82 112,-34 73,-59 86,-77 -19,-13 -52,-43 -84,-53l-90 2zm8115 7257c60,-74 70,111 51,-115 -8,-93 -53,-79 -74,-92 -6,7 -48,-10 -51,93 -7,206 -25,60 74,114zm-358 -3417c71,-45 53,62 74,-83 25,-183 -18,-80 -39,-116 -80,37 -60,-87 -83,79 -26,191 22,83 48,120zm-17157 14c84,70 -122,41 42,30 72,-5 22,6 65,-27 -62,-52 99,-38 -41,-29 -76,5 -12,-10 -66,26zm5328 -1528c64,-38 48,39 53,-51 7,-103 14,-24 -49,-60 -33,49 -32,66 -4,111zm-27615 8986c78,-37 55,63 54,-88 -92,2 -45,-22 -73,27 -47,84 8,41 19,61zm32764 3684c-10,-69 1,-14 -45,-37 -107,108 -16,75 26,101 17,-36 27,-9 19,-64zm-6438 -13319c1,0 47,9 52,-34 12,-113 25,-18 -49,-67 -15,24 -88,9 -3,101zm-2549 -1315c-17,8 -170,44 -28,87 58,17 34,0 42,-20 45,-117 9,-15 -14,-67zm4500 3122c50,-16 41,47 55,-34 13,-73 3,-24 -22,-71 -54,37 -107,11 -33,105zm100 11390c59,41 -62,18 67,32 141,16 7,10 72,-28 -141,-125 -131,-11 -139,-4zm5906 333c26,-38 129,23 33,-116 -108,38 -98,26 -33,116zm-36586 -127c129,-18 2,10 67,-35 -65,-124 -157,-104 -185,26 57,9 59,18 118,9zm29127 1316c73,-30 40,-35 106,4 -33,22 14,19 -51,22 -116,5 -14,2 -55,-26zm-38 58l179 5 2 -117 -181 -1 0 113zm-23361 -15949c1,-1 61,10 45,-97 -16,-103 8,-32 -68,-78 -13,20 -65,-31 -41,104 21,124 2,35 64,71zm7079 11660c-101,8 -43,-8 -107,52 -56,54 -46,20 -62,107l176 18 -7 -177zm27110 -785c-83,-43 -52,-52 -103,26 49,34 -62,39 59,24 76,-9 15,3 44,-50zm-1211 -2487c86,-45 122,22 33,-115 -52,20 -45,-52 -59,40 -13,86 -25,15 26,75zm849 -5816c135,-10 77,32 107,-104 -166,22 -89,-39 -107,104zm-8045 -1393l59 -2c61,-97 37,-142 -53,-191 -5,7 -123,39 -6,193zm-12585 2344c3,-126 9,-31 -32,-70 -25,25 -18,13 -37,64l39 57 30 -51zm21445 8401c-173,28 -5,162 -5,162 17,-23 34,53 35,-88 2,-133 2,-16 -30,-74zm-7726 -10714c54,-16 48,46 60,-34 14,-86 9,-15 -27,-73 -49,31 -121,-28 -33,107zm2226 -437c29,-40 52,53 35,-69 -15,-105 -2,-34 -59,-73 -14,17 -58,-43 -43,72 17,126 -14,33 67,70zm-13381 14473c-108,-44 -32,2 -69,25 153,144 93,45 120,32 -37,-65 17,-30 -51,-57zm-16107 -2399c103,-46 70,-13 61,-117 -96,10 -54,-27 -90,34 -46,78 29,83 29,83zm6804 -10029c-8,-5 -18,-24 -24,-15l-95 -9c0,144 -25,145 119,124l0 -100c-90,37 -68,-13 -76,69 108,-5 13,38 76,-69zm-11048 7103c11,-112 26,21 -39,-41l8 93c60,-55 22,37 31,-52zm6 -5040c76,71 -99,41 38,30 70,-5 11,13 56,-27 -53,-44 90,-32 -36,-25 -65,4 -11,-8 -58,22zm701 2991c38,31 32,40 85,3 -102,-100 -85,-3 -85,-3zm38576 5668c152,93 87,13 102,3 -42,-43 17,-22 -57,-32l-45 29z"/>
<path class="fil2" d="M22443 33531c91,-46 99,-37 3,-91 -65,80 -19,59 -3,91zm-9179 174l399 12 94 3 23 -102c121,-33 40,27 77,-81l-104 -24c-77,-2 -129,-55 -130,-59 -3,-10 -12,-11 -18,-15l-68 -4c-94,14 -152,38 -213,70l-167 11 -9 121 13 64 103 4zm3362 -16370c31,57 -35,35 43,50 123,23 4,11 64,-17 -27,-65 39,-44 -41,-57 -132,-21 -7,-12 -66,24zm10290 3584c-14,-80 9,-36 -56,-77 -3,4 -94,6 -19,84 51,53 74,-6 75,-7zm2277 11808c100,-46 108,-71 3,-122 -64,81 -39,56 -3,122zm-598 -13384c72,-96 69,-72 -26,-113 -75,90 -73,70 26,113zm-487 7658c-46,-62 -80,7 -82,7 65,99 -67,22 63,80 4,-5 100,22 19,-87zm-14360 -9918c34,-131 44,-88 -39,-138 -4,7 -53,-26 -32,67 28,121 -23,26 71,71zm13953 15010c6,-87 -6,-35 -58,-63 -75,84 -46,57 -4,130 44,-23 53,54 62,-67zm1319 -15162c106,-114 26,-92 4,-127 -51,29 -67,-45 -61,71 4,73 20,40 57,56zm2647 15024c-2,-2 8,-68 -88,-57 -109,12 -38,7 -73,64 105,50 64,60 161,-7zm-293 -3726c49,-51 48,-33 50,-171 -85,-2 -93,-38 -195,78 -83,12 -33,-18 -93,47l116 91c47,-29 48,-34 122,-45zm-2986 3302c-112,22 -39,12 -64,57 182,135 183,-23 184,-23 -10,-7 18,-61 -120,-34zm-1299 1033c-77,-44 -27,-43 -194,-4 19,157 34,164 112,169 166,12 14,18 78,-36l4 -129zm-29 818c-14,-28 44,-120 -225,-46 34,72 -28,65 93,92 164,37 124,-39 132,-46zm-7886 -16516l181 4c22,-158 -15,-177 -160,-176l-21 172zm1555 1675l149 114c98,86 124,57 174,-16 -50,-145 -13,-36 -146,-105 -44,-243 65,-253 -76,-325 -82,93 -26,15 -43,187 -15,145 -11,7 -58,145zm-16716 6826c57,-32 46,42 53,-46 6,-83 4,-30 -50,-59l-24 38c3,61 -12,24 21,67zm-1337 -2651c26,-6 45,9 64,-22 76,-123 9,-42 -9,-80 -79,40 -46,5 -55,102zm-4578 -6954l-112 -3 26 95c100,-38 42,50 86,-92zm7494 3833c33,-24 94,21 33,-122 -79,33 -50,-52 -63,48 -20,150 -15,19 30,74zm14390 12465c-111,-30 -19,-3 -63,20 25,35 -17,155 117,33 -23,-35 -5,-39 -54,-53zm-16337 1107c45,-72 -18,-62 -21,-68 -108,41 -55,-28 -72,101 119,-4 51,36 93,-33zm-15554 -8727c0,0 54,27 19,-104 -42,1 -53,-32 -84,34 -35,76 50,66 65,70zm29578 -7130c115,91 90,22 123,-26 -55,-41 62,-61 -72,-36 -85,16 -31,37 -51,62zm-15614 10133c9,-12 164,46 4,-107 -159,125 -4,106 -4,107zm19830 6238c-114,-3 -59,-5 -148,25 75,104 35,82 145,96l3 -121zm-1810 -750c-9,127 22,73 56,93 12,-18 98,-37 5,-177 -39,23 -54,-4 -61,84zm-22909 -1701c109,-48 103,-21 88,-170l-170 17 -8 103 28 61 62 -11zm17260 -7459c57,-31 46,52 67,-70 25,-145 -11,-61 -33,-93 -63,23 -49,-63 -69,61 -24,151 20,79 35,102zm6292 8218c-87,10 -54,14 -87,55 20,17 25,52 112,48 129,-7 69,-26 89,-70 -34,-24 -5,-45 -114,-33zm-18726 -12582l138 126c48,-78 33,-47 37,-155 -115,-28 -88,-44 -175,29zm5425 2089c111,8 43,39 121,-26l69 -111c-57,-37 50,-12 -63,-36 -108,-23 -9,-17 -111,3l-16 170zm198 -5155c69,-15 103,32 92,-91 -10,-106 -55,-86 -92,-103 -90,200 -13,173 0,194zm-4497 9344c43,-116 -3,-63 -8,-78 -188,-98 -155,47 -70,159 12,-9 44,9 78,-81zm-14595 -8298l-38 -84 -224 -26c12,84 -6,39 36,90 11,13 12,8 29,28 102,110 -28,62 101,78 134,18 76,-16 96,-27l0 -59zm16516 14224c-52,-40 -1,-28 -113,-50 -42,-8 -243,-19 -291,67 61,129 109,18 238,86 55,29 -10,50 104,69 197,32 132,-42 145,-52 -48,-181 24,-57 -88,-111l5 -9zm-15098 58c48,-69 45,-72 17,-145 -274,51 -23,42 -250,167 30,-165 -35,-99 -48,-113l-11 227 209 8 83 -144zm10508 -4775c27,-191 50,60 -34,-54 -79,69 -75,58 -4,123 52,-55 26,22 38,-69zm2333 -7579c33,-5 126,10 57,-109 -99,52 -45,-60 -57,109zm-3429 -2611c31,53 -29,36 45,50 112,21 8,9 62,-17 -23,-52 62,-39 -41,-56 -76,-13 -10,-11 -66,23zm-5194 1548c20,-171 28,-57 -49,-102 -23,40 -71,-39 -24,67 24,53 -2,25 73,35zm2621 14176c16,-129 6,-16 -31,-67 -97,48 -106,68 -4,128 34,-41 21,52 35,-61zm20632 -662c16,-119 -2,-25 -34,-66 -97,47 -111,67 -4,122 35,-34 23,48 38,-56zm-26456 -15122c101,69 77,57 133,-25 -31,-22 47,-55 -73,-37 -124,19 -29,27 -60,62zm-3048 11843c12,19 -42,82 104,51 57,-12 47,-31 63,-80 -76,-39 -83,-41 -168,-21l1 50zm591 1476c-69,86 -68,86 -5,161 100,-47 96,-110 5,-161zm9675 2249c133,-45 121,-5 97,-144 -185,-45 -50,-16 -91,31 11,22 3,32 23,36 48,12 16,9 52,-9 -40,-40 -1,-18 -75,-27 -8,6 -43,27 -44,28 -15,11 -33,39 -36,33 -3,-7 -13,13 -19,19l7 24c-84,-5 -18,-34 -119,21l-151 150c-8,14 -26,96 -31,118 184,-1 48,-2 196,-98 58,-38 107,-51 184,-77l16 -87 -9 -18zm-10948 -16354c55,-82 67,-123 -24,-178 -4,5 -50,-31 -46,89 4,132 36,74 70,89zm5381 2060c95,56 114,57 192,-23 -74,-75 -188,-91 -192,23zm4150 14183c1,-1 63,-22 50,-106 -19,-117 0,-36 -74,-72 -29,39 -120,103 24,178zm17482 -2004c-59,-80 -103,-72 -188,-35 18,24 -69,68 85,81 140,12 94,-39 103,-46zm-13680 -1675c142,42 170,46 247,-29 -36,-39 -44,-68 -144,-58 -99,9 -73,21 -103,87zm-8064 1221l-36 23c-90,81 -54,49 -55,120 261,25 188,-170 188,-171 -115,-6 33,-13 -60,2l-37 26c8,17 -2,42 39,48 4,1 17,-4 20,-4 4,0 15,-7 22,-10 -39,-35 7,-19 -81,-34zm8634 -1952c-7,-10 54,-79 -138,-26 10,87 13,131 91,196 33,-28 19,-1 54,-52 25,-33 -21,88 23,-39 49,-141 5,-71 -30,-79l-79 -1 26 81 53 -80zm-7088 2769c-11,-74 -89,-139 -148,-163l-44 119 162 129c15,-21 49,45 30,-85zm-7692 303l-2 61 260 28c12,-216 -160,-128 -258,-89zm39584 -10253c14,28 -26,64 64,64 136,1 28,20 79,-60 -44,-33 10,-44 -75,-38 -129,7 -19,-3 -68,34zm419 750c28,-36 34,52 41,-69 10,-164 -9,-60 -36,-101 -30,17 -56,-27 -71,73 -20,138 30,78 66,97zm3065 2473c56,-72 68,-95 66,-198 -91,-19 -135,-38 -154,50 -19,87 88,148 88,148zm2397 -3620c57,42 -53,30 105,50 159,19 21,7 114,-15 -23,-95 27,-126 -112,-132 -103,-5 -87,13 -107,97zm-719 4372l-51 -56c213,-116 93,-238 -69,-239 -152,-1 -176,38 -165,195l14 39c14,128 95,141 226,140l45 -79zm-11881 -7680c95,59 33,27 75,3l-58 -18c-2,-8 -11,11 -17,15zm-21198 15445c35,43 20,47 60,29 5,-2 14,-15 21,-22l-81 -7zm5007 1132l96 3 -5 -58c-40,-60 5,-36 -76,-65 -36,-12 -55,0 -88,1l4 117 69 2zm19325 -14421l-61 0c-35,54 -27,-70 -32,67 -4,136 12,61 31,94 73,-20 31,13 65,-51 145,-35 46,16 95,-68 -56,-55 16,-32 -98,-42zm-8429 13335c40,-6 207,-169 -164,-173 -69,95 -80,76 -101,170l265 3zm14572 -9261c47,74 56,123 127,4 -117,-124 -105,-20 -127,-4zm909 -1194c54,84 169,131 199,-23 -27,-13 -10,-39 -116,-25 -56,7 -60,9 -83,48zm271 2163c-1,-1 33,-56 -85,-37 -108,17 -29,-7 -85,61 38,68 -51,70 108,81 68,5 70,-17 106,-46 -12,-97 2,-33 -44,-59l-117 16 83 62c42,-51 19,-10 34,-78zm2226 -30c105,20 81,29 165,-11 -16,-86 -60,-131 -144,-155 -47,81 -42,60 -21,166zm-680 -1938c37,-37 13,14 35,-54 59,-183 70,-195 20,-219 -8,-1 -19,-13 -23,-4 -2,7 -74,-30 -94,109 -15,102 -7,135 62,168zm-7886 -1031c174,9 174,-15 198,-181l-195 0 -3 181zm-435 -3677c1,-132 -96,-207 -218,-204 -14,163 61,224 218,204zm9068 10670l-229 -20c16,143 33,200 192,182 19,-35 15,-15 28,-68 1,-1 7,-80 9,-94zm-11458 -8654l179 16c42,-78 53,-79 68,-188l-240 -2 -7 174zm-13484 -1787c67,65 -101,40 38,31 69,-5 24,3 66,-28 -78,-63 97,-40 -43,-30 -88,6 4,-25 -61,27zm15318 6420c8,8 -38,96 94,3 -76,-59 111,-37 -40,-27 -71,5 -10,-11 -54,24zm-4361 -5494c0,-176 44,-57 -80,-98 19,110 -24,65 80,98zm5776 11913c-52,-67 -17,-71 -103,-32 75,108 -101,-50 18,46 3,3 12,10 15,12 123,59 36,-5 70,-26zm452 -9192c-15,-105 18,-46 -63,-89 -52,58 -31,28 -37,112l0 24c138,141 57,117 171,135l18 -141 -89 -41zm1300 -184c26,36 -55,67 177,58 3,-16 69,-189 -108,-115 -67,28 -30,-2 -69,57zm-6644 5321c34,-145 -23,-89 -32,-106 -123,17 -85,-60 -108,72 -22,127 47,87 73,100 61,-30 38,56 67,-66zm12539 -5533c161,1 121,36 140,-122 -54,-35 -31,-46 -161,-30 -7,73 -19,77 21,152zm-7899 4642l158 -3 14 -151 -161 -4 -11 158zm-17041 -7038c56,111 45,115 103,4 -51,-38 -52,-32 -103,-4zm9438 14921c155,-74 35,-103 33,-108 -148,63 -33,108 -33,108zm-15491 -14617c76,-131 38,-84 -75,-106 30,146 -22,74 75,106zm2595 5412c114,-55 112,-64 4,-122 -17,20 -39,-42 -33,60 3,62 0,30 29,62zm3715 -5475c14,118 -32,80 93,86 37,-95 5,-127 -93,-86zm-11753 7101c5,-101 4,-86 -99,-104 -13,126 -1,117 99,104zm5801 -8233c54,-27 68,45 62,-68 -4,-75 -27,-45 -58,-61 -3,3 -85,14 -4,129zm-10835 7881c-39,-69 -44,-121 -135,-4 59,52 -68,23 66,40 114,15 28,-3 69,-36zm25397 -740c-39,10 -173,13 -98,95 96,105 85,-47 98,-95zm-2065 8351c-44,-72 23,-10 -75,-89 -65,-51 0,-9 -75,-42l-43 107 31 161c93,9 88,6 142,-32l20 -105zm-14954 -14214c87,52 55,48 150,6 -45,-139 -121,-139 -150,-6zm2674 8593c-160,1 -84,46 -93,80l164 16c3,-66 28,-97 -71,-96zm-12857 -11652c59,116 145,73 198,6 -89,-66 -119,-55 -198,-6zm14729 9603c9,31 -34,70 86,81 110,11 71,-13 85,-75 -84,-44 -68,-38 -171,-6zm-1945 -4959c-113,-51 -59,-57 -140,3l-3 59c93,63 166,72 228,-22 -42,-48 23,-26 -85,-40l-115 0c37,83 -28,35 82,68 55,-38 15,12 33,-68zm1792 10456c-77,-56 -141,-72 -205,23 16,12 15,56 118,47 109,-8 68,-30 87,-70zm6791 -1117c36,-46 36,70 46,-94 7,-128 -25,-68 -41,-87 -41,17 -64,-27 -70,84 -8,141 28,77 65,97zm-19845 -1831c156,4 126,-56 115,-191 -148,47 -119,6 -115,191zm28588 2560c110,14 138,-57 145,-166l-129 10c-85,158 -17,155 -16,156zm-24536 1960c-95,25 -67,45 -79,133 122,4 100,21 190,-35 -16,-82 22,-133 -111,-98zm-1339 -12555c34,-29 35,29 35,-82 -176,-85 -220,125 -198,245 232,90 139,21 169,-18l-8 -56 2 -89zm-138 10191c6,-3 15,-9 19,-11 187,-98 143,-30 160,-133 -81,-49 -97,-61 -235,49 -9,7 -15,11 -19,14l-10 -4 4 8c-6,4 -7,6 -36,41 47,43 -13,15 61,44 105,40 38,-2 56,-8zm8367 -12746l142 -3 16 -140c-106,-42 -55,-43 -174,-39 -38,108 -18,70 16,182zm13540 9864c20,-155 32,-118 -57,-201l-114 -69 -18 135c4,4 38,33 46,42 112,117 -30,57 143,93zm988 4753c45,-102 30,10 24,-135l-34 -127c-82,44 -11,4 -56,41l-47 40c-58,65 -44,-8 -43,128 63,55 64,54 156,53zm12226 -12623c69,-36 48,37 60,-51 10,-77 0,-29 -27,-74 -74,34 -47,-58 -62,47 -11,85 -16,23 29,78zm-541 532c79,-38 56,43 72,-73 18,-134 -33,-95 -37,-102 -62,28 -51,-64 -72,68 -25,164 18,78 37,107zm3249 -2408c42,-47 39,67 47,-70 10,-158 -17,-67 -42,-99 -63,25 -63,-60 -82,69 -19,138 47,86 77,100zm1303 9111c11,10 -39,54 99,53 165,-1 78,-27 103,-76 -9,-7 34,-50 -103,-50 -165,1 -71,41 -99,73zm-492 -3647c92,-9 106,-16 198,-88 -55,-161 -128,-160 -198,-171 8,167 44,104 0,259zm-24691 -3316c88,44 53,43 105,-26 -39,-27 54,-78 -66,-29 -4,1 -13,8 -16,10l-23 45zm13670 13200c-33,-129 32,-90 -103,-104 13,123 -21,66 103,104zm-2530 -391c-27,-47 15,-109 -119,-33 20,31 -50,44 47,68 133,33 20,3 72,-35zm7333 519c-75,-6 -55,36 -70,58 59,45 -67,20 67,36 128,15 17,5 68,-31 -26,-54 53,-54 -65,-63zm-2346 -1174c-21,-102 14,-11 -60,-51 -44,43 -78,-66 -39,94 19,78 18,22 64,42 41,-48 52,-4 35,-85zm-2671 1531c-126,3 -69,18 -100,67 33,26 41,98 222,6 -23,-40 -11,-75 -122,-73zm2389 -1391c-144,-10 -216,11 -140,175l167 10 -27 -185zm-13510 -6878c31,-55 21,-40 2,-86 -55,59 -65,-88 -31,42 34,130 -97,-14 29,44zm11036 7899c51,38 -7,20 62,28 135,17 -26,24 42,-24 -37,-35 3,-24 -62,-33 -162,-23 46,-43 -42,29zm-26597 -10879c61,73 10,58 96,32 -17,-44 72,-25 -24,-45 -72,-14 -22,-8 -72,13zm24876 10019c-12,-82 2,-14 -47,-36 -75,86 -25,63 27,92 24,-39 30,7 20,-56zm-13300 -13607c15,-24 58,33 23,-60 -25,-65 14,-8 -49,-43 -39,74 -64,63 26,103zm-1474 10770c72,-89 63,-70 -26,-109 -102,108 -21,86 26,109zm2490 -9768c5,-7 104,11 5,-148 -45,51 -53,-76 -44,73 5,81 3,34 39,75zm-455 582l45 -26c-21,-109 31,-69 -102,-93 -6,111 -39,73 57,119zm-2646 4875c5,-126 -2,-96 -98,-104 -10,117 -38,124 98,104zm-15387 -7335c19,35 -38,43 63,61 137,25 73,-13 97,-27 -4,-10 32,-155 -160,-34zm3776 14905c-5,113 33,83 36,87 97,-48 94,-123 6,-180 -22,28 -35,-54 -42,93zm16124 -7293c1,0 19,130 175,5 -14,-31 11,-58 -77,-63 -125,-7 -71,37 -98,58zm4168 4706c37,-17 60,39 74,-88 13,-125 -31,-79 -39,-89 -47,21 -58,-27 -69,83 -13,129 25,80 34,94zm-14149 1449c-77,-12 -83,28 -88,128l196 -3c-13,-79 -18,-110 -108,-125zm-10285 -377c145,13 156,25 271,-27 -60,-66 -141,-122 -250,-121l-21 148zm30878 -12750c85,40 49,48 105,-26 -21,-16 24,-117 -105,26zm-4545 -547c57,-82 74,-71 -26,-119 -64,93 -65,76 26,119zm6389 36c29,-122 43,-90 -83,-116 14,175 -39,72 83,116zm5155 2988c-2,44 -19,42 29,111 108,-35 40,70 81,-93 0,-4 -13,-87 -13,-87 -15,-49 -13,-36 -31,-65 -82,38 -49,-29 -66,134zm-7078 -530c164,-26 121,59 106,-100 -107,-4 -71,-31 -106,100zm1288 -911c5,-125 48,-86 -66,-119 -93,100 -38,96 66,119zm2390 12606c-127,16 -58,-23 -117,61 77,102 120,95 117,-61zm-6680 -14484c93,-49 102,-26 33,-126 -50,15 -40,-45 -66,34 -44,140 5,62 33,92zm-6631 -463c15,26 -10,57 69,75 138,31 72,-16 95,-31 -35,-82 47,-48 -66,-68 -28,-5 -93,19 -98,24zm9161 3323c39,-11 65,56 83,-82 13,-103 -26,-89 -48,-112 -98,44 -81,122 -35,194zm11122 7323c77,-41 52,57 68,-98 5,-49 -11,-64 -20,-96 -60,21 -77,-45 -93,90 -16,134 36,91 45,104zm-6944 6433l64 2c34,-109 52,-107 -11,-201 -30,8 -66,-56 -83,91 -7,64 4,48 30,108zm-9852 -12707c33,-80 15,-192 -49,-252 -81,-76 -14,-26 -117,-47 50,222 25,40 89,163 45,86 -28,59 77,136zm17007 11129c-5,-4 -12,-10 -17,-14l-83 -58c-95,106 -8,225 151,201 10,-144 18,-76 -51,-129zm-14522 -7357l6 118 177 17 4 -157c-119,-17 -94,-25 -187,22zm1633 621c122,-9 53,43 137,-39 83,-80 31,-20 54,-141l-180 10 -11 170zm4070 -5651l169 46c4,-99 16,-85 -35,-146 -85,-102 -17,-49 -154,-73l20 173zm10175 12053c-9,-85 14,-6 -49,-52 -37,41 -36,-9 -29,69 9,97 -12,14 55,43 36,-56 37,58 23,-60zm-8682 -13171c38,60 -39,38 51,53 70,12 25,3 66,-21 -12,-32 50,-133 -117,-32zm2108 1273c32,-19 113,33 33,-122 -78,35 -51,-47 -63,49 -17,128 -11,22 30,73zm-2180 -3663l-109 -3c3,174 -2,49 43,106 98,-52 42,59 66,-103zm10237 6624c21,-31 58,42 35,-72 -21,-101 16,-22 -69,-66 -51,93 -65,71 34,138zm-4681 8278c35,-113 -29,-91 -30,-94 -79,35 -36,-30 -61,65 -8,30 9,72 15,95 49,-25 47,25 76,-66zm1712 -10475c90,-11 72,27 105,-40 54,-109 -36,-81 -61,-94l-37 44c-16,57 -18,8 -7,90zm-2159 653c14,19 -15,66 80,65 117,-2 32,5 75,-60 -19,-16 33,-129 -155,-5zm-9160 -4516c140,63 103,33 149,-46 -10,-8 40,-74 -77,-47 -186,44 -11,10 -72,93zm14791 10390c-149,-15 -74,13 -105,64 54,49 -82,47 102,53 102,4 97,-46 99,-47 -19,-29 7,-60 -96,-70zm-7396 -6688c36,71 -84,46 66,62 8,-7 18,-27 22,-21l74 -89c49,-90 34,-58 -1,-120 -66,20 -27,3 -73,42 -5,4 -10,10 -14,14 -5,4 -11,10 -15,14 -4,5 -11,12 -16,16l-35 34 -8 48zm3324 -2979c19,41 -49,73 95,76 129,2 70,-21 95,-70 -7,-6 38,-52 -90,-53 -165,-1 -56,12 -100,47zm-4325 1161l115 0c20,-126 28,-84 -30,-190 -117,49 -118,87 -85,190zm5264 1728c2,-3 48,17 50,-92 4,-170 -3,-48 -44,-101 -39,16 -77,-51 -90,107 -6,77 17,64 84,86zm3736 8908c128,-174 17,-185 7,-200 -65,16 -98,-21 -96,99 2,114 50,86 89,101zm-577 -7651c-69,-84 28,-31 -83,-63 -48,-14 -90,-4 -138,1 13,162 117,193 221,62zm-10793 -2729c100,-7 113,56 202,-184l-174 3 -28 181zm11216 4612c69,-72 58,-54 46,-178l-199 -7c-4,7 -10,9 -12,18l-76 95c135,22 68,-7 161,87l80 -15zm-25273 1701c76,60 6,56 86,3 -47,-47 102,-40 -34,-29 -72,6 -2,-17 -52,26zm-2321 -4177c9,14 14,125 94,3 -55,-40 95,-28 -36,-22 -55,3 -22,-1 -58,19zm3532 6166c27,41 -52,47 54,45 61,-2 15,-6 40,-42 -34,-25 -1,-17 -55,-23 -4,0 -17,14 -19,7 -3,-7 -13,9 -20,13zm9741 -9188c141,-29 65,23 97,-75 -192,-10 -27,11 -97,75zm-816 7909c15,-101 13,5 -29,-35 -126,99 -5,94 -3,96 46,-55 21,17 32,-61zm4719 4713c-57,112 -6,24 19,71 20,-12 147,-53 24,-91 -71,-21 -31,-5 -43,20zm-8123 -431c-15,-86 16,-10 -58,-43 -82,124 13,93 35,107 35,-58 46,63 23,-64zm17490 -3007c175,100 121,20 148,5 -164,-141 -131,-17 -148,-5zm-22342 4930c132,-4 153,38 190,-77l-182 -33c-126,37 -57,-3 -107,63 47,51 -83,44 99,47zm12980 -12068c-5,14 -15,15 -17,31 -2,16 -11,19 -13,27 -5,31 -5,60 -3,92l176 14 5 -153 -148 -11zm3361 -432c36,-54 25,-37 3,-87 -60,72 -60,-95 -28,43 33,144 -77,-37 25,44zm-4106 70c11,-16 62,31 29,-65 -28,-79 21,-7 -55,-51 -27,44 -74,-63 -27,70 23,65 -11,17 53,46zm4107 -1014c83,-42 48,57 62,-54 19,-151 12,-10 -29,-78 -91,38 -53,-66 -66,49 -13,104 -23,19 33,83zm5309 -1291c25,-37 79,60 36,-83 -31,-103 26,-8 -61,-59 -32,47 -82,-71 -36,83 28,92 -21,17 61,59zm1248 6583c63,-42 37,35 61,-54 35,-132 -11,-66 -27,-91 -56,21 -40,-53 -67,42 -50,177 3,67 33,103zm-3413 -2551c58,-28 79,64 73,-75 -5,-112 -22,-47 -68,-70 -1,1 -117,-7 -5,145zm-289 -1224c21,57 -53,42 41,69 192,56 47,8 104,-36 -35,-66 27,-44 -52,-65 -126,-33 -82,23 -93,32zm-5357 -3096l-17 46c15,129 58,97 106,82 112,-34 72,-59 86,-77 -20,-13 -52,-43 -84,-53l-91 2zm8116 7257c60,-74 70,111 51,-114 -8,-94 -53,-80 -74,-93 -6,8 -48,-10 -52,93 -7,206 -24,60 75,114zm-359 -3417c72,-45 54,62 74,-83 26,-183 -17,-80 -38,-116 -80,37 -61,-87 -83,79 -26,191 21,83 47,120zm-17157 14c85,70 -121,41 43,30 71,-4 21,6 65,-27 -62,-52 98,-38 -42,-29 -76,5 -12,-10 -66,26zm5329 -1528c63,-38 47,39 53,-51 6,-102 14,-24 -50,-60 -32,49 -31,66 -3,111zm-27615 8986c78,-36 55,63 54,-88 -92,3 -46,-22 -73,28 -47,83 8,40 19,60zm32764 3684c-10,-69 0,-14 -45,-36 -107,107 -16,74 26,100 17,-35 26,-9 19,-64zm-6439 -13319c1,0 48,9 52,-33 12,-114 25,-19 -48,-68 -16,24 -89,9 -4,101zm-2549 -1315c-16,8 -169,44 -28,87 59,17 35,0 43,-20 45,-117 8,-15 -15,-67zm4501 3122c50,-16 41,47 55,-34 13,-73 3,-24 -23,-71 -53,37 -106,11 -32,105zm100 11390c59,41 -62,18 66,32 141,16 8,10 73,-28 -142,-125 -131,-11 -139,-4zm5906 333c25,-38 129,23 33,-116 -109,38 -98,26 -33,116zm-36586 -127c129,-18 2,10 67,-34 -65,-125 -157,-104 -185,25 57,9 59,18 118,9zm29127 1317c73,-31 40,-35 105,3 -33,22 15,19 -51,22 -115,5 -13,3 -54,-25zm-38 57l179 5 2 -117 -181 -1 0 113zm-23361 -15949c1,-1 61,10 45,-96 -16,-104 8,-33 -69,-78 -13,19 -64,-32 -40,103 21,124 1,35 64,71zm7078 11660c-100,8 -43,-8 -106,52 -56,54 -46,20 -62,107l175 18 -7 -177zm27110 -785c-82,-43 -51,-52 -102,26 49,34 -62,39 58,24 76,-9 15,3 44,-50zm-1210 -2487c86,-45 122,22 32,-114 -51,19 -45,-53 -58,39 -14,86 -25,15 26,75zm849 -5816c135,-10 76,32 106,-104 -166,22 -89,-39 -106,104zm-8045 -1393l58 -2c62,-97 37,-142 -52,-191 -5,7 -124,39 -6,193zm-12585 2344c3,-126 9,-31 -32,-70 -26,25 -18,13 -37,64l38 57 31 -51zm21445 8402c-173,27 -5,161 -5,161 16,-23 33,53 35,-88 2,-133 2,-16 -30,-73zm-7726 -10715c54,-16 48,46 60,-34 13,-86 8,-15 -27,-73 -49,31 -122,-28 -33,107zm2226 -437c29,-40 52,53 35,-69 -16,-105 -3,-34 -60,-73 -13,17 -57,-43 -42,72 16,126 -15,33 67,70zm-13381 14473c-109,-44 -32,2 -69,25 153,144 93,45 120,33 -37,-65 17,-30 -51,-58zm-16107 -2399c103,-46 70,-13 61,-117 -97,10 -54,-27 -90,34 -46,78 29,83 29,83zm6804 -10029c-8,-5 -18,-24 -24,-15l-96 -9c1,144 -24,145 120,124l0 -100c-90,37 -68,-13 -76,69 108,-5 13,38 76,-69zm-11049 7103c12,-112 26,21 -38,-41l7 93c60,-55 22,37 31,-52zm7 -5040c76,71 -99,41 37,30 71,-5 11,13 56,-27 -52,-44 90,-32 -35,-25 -65,4 -11,-8 -58,22zm700 2992c39,30 32,39 86,2 -102,-100 -86,-3 -86,-2zm38577 5667c152,93 87,13 102,3 -42,-43 16,-22 -58,-32l-44 29z"/>
</g>
</g>
<path class="fil3" d="M20432 0c8718,-38 15581,2266 15458,9209 -25,787 -197,745 -1206,434 -5376,-1662 -8578,-3016 -12410,-6248 -1067,-900 -1945,-1797 -2743,-2837 -478,-648 -8,-545 901,-558zm-18416 19428c1785,-4186 2803,-6725 6956,-9214 1814,-1088 3728,-1795 5744,-2401 5011,-1469 9917,-953 14495,540 1697,562 2833,1208 4123,2158 602,450 989,178 1872,-71 402,-113 1572,-529 1912,-305 933,615 -675,1120 -1291,1389 -1798,785 -1256,251 -1265,1780 -43,7030 -7302,11174 -13250,12374 -3409,688 -7029,1146 -9343,1499 -5916,900 -5060,-1185 -9071,-2819 -937,-381 -2531,-341 -2879,-1361 -223,-655 1540,-2751 1997,-3569z"/>
<path class="fil4" d="M10113 32164l548 -85c566,-87 655,-815 655,-1696 0,-1108 -152,-1559 -630,-1485l-573 89 0 3177zm-872 -3711l1541 -239c770,-120 1425,167 1425,1818l0 225c0,1013 -203,2283 -1374,2464l-1592 246 0 -4514z"/>
<path class="fil4" d="M14753 30269l-349 -2047 -421 2167 770 -120zm-922 -2527l1171 -182 1019 4358 -943 146 -216 -1141 -987 152 -274 1218 -935 145 1165 -4696z"/>
<polygon class="fil4" points="17968,31617 17096,31752 17096,27924 16014,28092 16014,27404 19050,26934 19050,27622 17968,27790 "/>
<path class="fil5" d="M24269 30700l88 -3885 -824 115 -106 4640 2357 -329 17 -755 -1532 214zm2552 396l105 -4640 -824 115 -106 4640 825 -115zm3488 -5112l-525 1811c-157,575 -298,1154 -410,1687l-17 3c-83,-518 -193,-1044 -319,-1586l-423 -1679 -1020 143 -395 4680 752 -105 124 -1798c41,-577 85,-1269 109,-1855l17 -3c87,553 207,1162 334,1668l432 1780 624 -87 566 -1950c157,-539 327,-1176 462,-1748l17 -3c-16,472 -6,1216 3,1822l37 1793 785 -109 -139 -4606 -1014 142zm2380 3547l29 -1291 1399 -196 16 -730 -1398 196 25 -1123 1483 -207 17 -748 -2307 322 -106 4640 2396 -334 17 -749 -1571 220z"/>
<path class="fil4" d="M21036 29298l-350 -2048 -420 2166 770 -118zm-923 -2529l1172 -182 1019 4359 -943 145 -217 -1141 -986 152 -274 1218 -936 145 1165 -4696z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<style type="text/css">
.st0{fill:#555555;}
</style>
<g>
<path class="st0" d="M476.7,88.3h-88.3c0-48.8-39.5-88.3-88.3-88.3s-88.3,39.5-88.3,88.3h-88.3c-19.5,0-35.3,15.8-35.3,35.3v88.3
C39.5,211.9,0,251.4,0,300.1s39.5,88.3,88.3,88.3v88.3c0,19.5,15.8,35.3,35.3,35.3h123.6v-35.3c0-29.3,23.7-53,53-53s53,23.7,53,53
V512h123.6c19.5,0,35.3-15.8,35.3-35.3V353.1h-35.3c-29.3,0-53-23.7-53-53s23.7-53,53-53H512V123.6
C512,104.1,496.2,88.3,476.7,88.3z M388.4,300.1c0,48.8,39.5,88.3,88.3,88.3v88.3h-88.3c0-31.5-16.8-60.7-44.1-76.5
c-27.3-15.8-61-15.8-88.3,0c-27.3,15.8-44.1,44.9-44.1,76.5h-88.3V353.1H88.3c-29.3,0-53-23.7-53-53s23.7-53,53-53h35.3V123.6
h123.6V88.3c0-29.3,23.7-53,53-53s53,23.7,53,53v35.3h123.6v88.3C427.9,211.9,388.4,251.4,388.4,300.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 889 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 81 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+16
View File
@@ -0,0 +1,16 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
<polyline points="14 2 14 8 20 8" />
<path d="M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1" />
<path d="M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1" />
</svg>

After

Width:  |  Height:  |  Size: 498 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 51 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 84 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

+356
View File
@@ -0,0 +1,356 @@
<cfscript>
/* Все глобальные функции экспортированы в request scope */
function plain2htm(s) {
return replace(replace(s, chr(13),'',"ALL"),chr(10),'<br/>', "ALL");
}
request.plain2htm = plain2htm;
function htm2plain(s) {
return replaceNoCase(s, '<br/>', '#chr(13)##chr(10)#', "ALL");
}
request.htm2plain = htm2plain;
function cleanHtm(s) {
return replaceList(s, '<,>,"', '&lt;,&gt;,&quot;');
}
request.cleanHtm = cleanHtm;
function clean4CDATA(s) {
LF = chr(10);
return replaceNoCase(replaceList(s, '[,]', '&91;,&93;'),"<br>",LF,"ALL");
}
request.clean4CDATA = clean4CDATA;
function numFmt(num, decimalPlaces = 0){
var sFormat = ",";
if (decimalPlaces GT 0) {sFormat = sFormat & "." & repeatString("0", decimalPlaces);}
return replace(NumberFormat(num, sFormat), ",", " ", "ALL");
}
request.numFmt = numFmt;
function nFmt(num, decimalPlaces = 2){
if (num EQ 0) return "";
return numFmt(num, decimalPlaces);
}
request.nFmt = nFmt;
function dateFmt(date, sFormat = 'YYYY-MM-DD'){
return dateFormat(date, sFormat);
}
request.dateFmt = dateFmt;
function dateTimeFmt(date, sDateFormat = 'YYYY-MM-DD', sTimeFormat='HH:MM'){
return dateFormat(date, sDateFormat) & ' ' & timeFormat(date, sTimeFormat);
}
request.dateTimeFmt = dateTimeFmt;
function timeFmt(date, sFormat = 'HH:MM'){
return timeFormat(date, sFormat);
}
request.timeFmt = timeFmt;
function usrAuthenticated() {
return request.usr_id GT 0 AND NOT (request.usr_id EQ request.ANONYMOUS_USR_ID);
}
request.usrAuthenticated = usrAuthenticated;
function filterOn(filter) {
return (isStruct(filter) AND NOT structIsEmpty(filter));
}
request.filterOn = filterOn;
function stripWhiteSpace(sNumber) {
return reReplace(sNumber, "[[:space:]]", "", "ALL");
}
request.stripWhiteSpace = stripWhiteSpace;
/*
// never used
function cleanNumber(sNumber) {
var s = reReplace(sNumber, "[[:space:]]", "", "ALL");
if ( find(",", s) ) { //watch argument order!!!
// assume Russian format with decimal comma and spaces for thousand separator
return replace(s, ",", ".");
} else {
// assume English format with decimal point and commas for thousand separator
return replace(s, ",", "", "ALL");
}
}
request.cleanNumber = cleanNumber;
*/
/*https://cflib.org/udf/queryColumnToArray*/
/**
* Takes a selected column of data from a query and converts it into an array.
*
* @param query The query to scan. (Required)
* @param column The name of the column to return data from. (Required)
* @return Returns an array.
* @author Peter J. Farrell (pjf@maestropublishing.com)
* @version 1, July 22, 2005
*/
function queryColumnToArray(qry, column) {
var arr = arrayNew(1);
var ii = "";
var loop_len = arguments.qry.recordcount;
for (ii=1; ii lte loop_len; ii=ii+1) {
arrayAppend(arr, arguments.qry[arguments.column][ii]);
}
return arr;
}
request.queryColumnToArray = queryColumnToArray;
/* ************************************* */
function loginPasswordPolicyCheck(usr_id, login, passwd, passwd2) {
msg = "";
// для старого логина длина не проверяется, все равно ничего не поделаешь
if (NOT(usr_id GT 0) AND len(login) LE 3) {
msg="Слишком короткий логин (минимальная длина логина 3 символа)";
} else {
if (passwd NEQ passwd2) {
msg="Пароль и подтверждение не совпадают";
} else {
if (len(passwd) LT "8") msg="Слишком короткий пароль (минимальная длина пароля 8 символов)";
}
}
return msg;
}
request.loginPasswordPolicyCheck = loginPasswordPolicyCheck;
function i18(label,label_en=label) {
//примитивная 2-язычная версия
if (request.language EQ 'en') {
return label_en;
} else {
return label;
};
}
request.i18 = i18;
function passwordHashCreate(password) {
return GenerateArgon2Hash('#ARGUMENTS.password#', 'argon2id', 1, 16000, 2);
}
request.passwordHashCreate = passwordHashCreate;
function passwordHashCheck(password, passwordHash) {
return Argon2CheckHash('#ARGUMENTS.password#', ARGUMENTS.passwordHash, 'argon2id');
}
request.passwordHashCheck = passwordHashCheck;
/*
function skuCode(area_code="", abstract_service_code="") {
var s="#arguments[1]#.#arguments[2]#";
if (arrayLen(arguments) GE 3) {
if (len(arguments[3]) GT 0) {
s="#s#.#arguments[3]#";
} else {
s="#s#.0";
};
};
if (arrayLen(arguments) GE 4) {
if (len(arguments[4]) GT 0) {
s="#s#.#arguments[4]#"
}
};
if (arrayLen(arguments) GE 5) {
var pricingModelSuffix=arguments[5];
s="#s#-#pricingModelSuffix#";
}
return s;
}
request.skuCode = skuCode;
*/
function roundSafe(a, precision) {
return (isNumeric(a) AND isNumeric(precision)) ? round(a,precision) : a;
}
request.roundSafe = roundSafe;
function timeUnitLabel(n, value=0, locale="ru") {
var labels = ["сек.","мин.","ч.","д.","мес."];
if (n LE 5 AND n GE 1) {return labels[n];}
else if (n EQ 6) { // в зависимости от числа - "год" г. или "лет" л.
var m = value MOD 100;
if (m GE 11 AND m LE 20) {
return "л.";
}
m = m MOD 10;
if (m GE 1 AND m LE 4) {
return "г.";
}
return "л.";
}
throw (message="timeUnitLabelRu: index out of bounds", detail="Index must be from 1 to 6");
}
request.timeUnitLabel = timeUnitLabel;
function dateDiffVerbose(dateFrom, dateTo, maxParts=6, maxPrecision=1, locale="ru") {
// returns formatted datetime interval duration, e.g. 1 hour 5 minutes or 3 years 0 months 12 days
//(currently, only Russian supported)
//
//maxParts specifies, how many parts to display
//maxPrecision starts froms seconds: 1=seconds, 2=minutes, 3=hours, 4=days, 5=months, 6=years
//if maxPrecision specified is greater than given time interval, output is nothing
//locale=ru just for interface, not used
//attention: truncates the tail, not rounds
//example: request.dateDiffVerbose(Now(),Now()+373.1234567, 3, 1) produces 1 г. 0 мес. 8 д.
//example: request.dateDiffVerbose(Now(),Now()+373.1234567, 6, 1) produces 1 г. 0 мес. 8 д. 2 ч. 57 мин. 46 сек.
//intended common usage: request.dateDiffVerbose(dateFrom, dateTo, 2, 1) - prints 2 senior parts of the interval,
//with presision not better than second
//
// this is not the same task as converting number of seconds to days-hours-minutes-seconds,
// because months contain different number of days, and days number of february depends on year
try {
if (NOT (isDate(dateFrom) AND isDate(dateTo))) return "";
var UNIT_CODES = ["s","n","h","d","m","yyyy"];
var start = dateFrom;
var finish = dateTo;
var sOut = "";
var nUnits = 0;
var nPrintedPositions = 0;
var printStart = false;
for (i=ArrayLen(UNIT_CODES); i GT 0; i=i-1) {
nUnits = dateDiff(UNIT_CODES[i], start, finish);
start = dateAdd(UNIT_CODES[i], nUnits, start);
if (nPrintedPositions GT 0) {nPrintedPositions=nPrintedPositions+1;} //print started, so increment position
if (nPrintedPositions GT maxParts) {break;}
if (i LT maxPrecision) {break;}
if (nUnits NEQ 0 AND nPrintedPositions EQ 0) {nPrintedPositions=1;}
if (nPrintedPositions GT 0) {
if (len(sOut)) {sOut=sOut & " ";}
sOut=sOut & nUnits & " " & request.timeUnitLabel(i, nUnits, "ru");
}
}
return sOut;
} catch(e) {
return "";
}
}
request.dateDiffVerbose = dateDiffVerbose;
/*
function secondsToDHMS(nSeconds,partsToKeep) {
//format seconds to days-hours-minutes-seconds and truncate to specified precision
{
days = n / (24 * 3600);
n = n % (24 * 3600);
hours = n / 3600;
n %= 3600;
minutes = n / 60 ;
n %= 60;
seconds = n;
return days & " " & "days "
& hours & " " & "hours "
& minutes & " " & "minutes "
& seconds & " " & "seconds ");
}
}
*/
/**
* Formats a JSON string with indents and new lines.
* v1.0 by Ben Koshy (modified)
*
* @param str JSON string (Required)
* @return Returns a string of indent-formated JSON
* @author Ben Koshy (cf@animex.com)
* @version 0, September 16, 2012
*/
// formatJson() :: formats and indents JSON string
// based on blog post @ http://ketanjetty.com/coldfusion/javascript/format-json/
// modified for CFScript By Ben Koshy @animexcom
// usage: result = formatJson('STRING TO BE FORMATTED') OR result = formatJson(StringVariableToFormat);
// генерирует html разметку, чтобы не использовать <pre> и выровнять пробелы
// содержит ошибку: делает перевод строки после запятой в строке в кавычках
public string function formatJsonString(str) {
var fjson = '';
var pos = 0;
var strLen = len(arguments.str);
var indentStr = '&nbsp; '; // Adjust Indent Token If you Like (замыкающий пробел - для выравнивания при пробелах после запятой)
var newLine = '<br/>'; // Adjust New Line Token If you Like <BR>
for (var i=1; i<=strLen; i++) { //fix: <=
var char = mid(arguments.str,i,1);
if (char == '}' || char == ']') {
fjson &= newLine;
pos = pos - 1;
for (var j=1; j <= pos; j++) {
fjson &= indentStr;
}
}
fjson &= char;
if (char == '{' || char == '[' || char == ',') {
fjson &= newLine;
if (char == '{' || char == '[') {
pos = pos + 1;
}
for (var k=1; k <= pos; k++) {
fjson &= indentStr;
}
}
}
return fjson;
}
request.formatJsonString = formatJsonString;
//нужна еще функция, которая сериализует структуру как pretty printed json. См. https://github.com/bennadel/JsonSerializer.cfc (все не совсем просто, например, не заранее не определен формат даты)
</cfscript>
<cffunction name=structGetKey>
<cfargument name="struct" type="struct"/>
<cfargument name="key" type="string"/>
<cfargument name="default" type="string" default=""/>
<cftry>
<cfif StructKeyExists(ARGUMENTS.struct, ARGUMENTS.key)>
<cfreturn structFind(ARGUMENTS.struct, ARGUMENTS.key)/>
<cfelse>
<cfreturn ARGUMENTS.default/>
</cfif>
<cfcatch type="any">
<cfreturn ARGUMENTS.default/>
</cfcatch>
</cftry>
<!--- можно проще - просто обработать исключение. вряд ли будет сильно хуже --->
</cffunction>
<cfset request.structGetKey = structGetKey/>
<cffunction name="setError">
<cfargument name="container" type="struct"/>
<cfargument name="message" type="string"/>
<cfset arguments.container.errorState=true/>
<cfset arguments.container.errorMessage=arguments.message/>
</cffunction>
<cfset request.setError = setError/>
<cffunction name="snake2camel"
access="public"
returntype="any"
output="false"
hint="convert snake style name to camel style name">
<cfargument name="snake" type="string" required="true" />
<cfreturn #reReplace(ARGUMENTS.snake,"_([a-z])","\u\1","ALL")#/>
</cffunction>
<cfset request.snake2camel = snake2camel/>
<cffunction name="camel2snake"
access="public"
returntype="any"
output="false"
hint="convert camel style name to snake style name">
<cfargument name="snake" type="string" required="true" />
<cfreturn #reReplace(ARGUMENTS.snake,"([A-Z])","_\l\1","ALL")#/>
</cffunction>
<cfset request.camel2snake = camel2snake/>
+58
View File
@@ -0,0 +1,58 @@
<cfimport prefix="m" taglib="../lib"/>
<cfimport prefix="c" taglib="../lib/controls"/>
<cfparam name="ATTRIBUTES.fwx" default=""/>
<cfparam name="ATTRIBUTES.thisUrl" default=""/>
<cfset i18=request.i18/>
<!---<style>ul#mainmenu li.menu-item-noaction a.inline{display:inline;}</style>--->
<cfoutput>
<ul id="mainmenu">
<cfif request.usrAuthenticated()></cfif>
<li class="menu-title">Реестры</li>
<c:menu_item acl="" page="deal_ls.cfm" label="Сделки"/>
<c:menu_item acl="" page="contract_ls.cfm" label="Договоры"/>
<c:menu_item acl="" page="additional_agreement_ls.cfm" label="Доп. соглашения"/>
<!---
<c:menu_item acl="" page="specification_ls.cfm" label="Спецификации"/>
<c:menu_item acl="" page="agreement_ls.cfm" label="Сделки"/>
<c:menu_item acl="" page="specification_item_ls.cfm" label="Экземпляры услуг"/>--->
<li class="menu-title">Отчеты</li>
<c:menu_item acl="" page="payg.cfm" label="PAYG"/>
<!--- <c:menu_item acl="" page="detail_daily_rpt.cfm" label="Детализация по дням"/>
<c:menu_item acl="" page="income_daily_rpt.cfm" label="Выручка по дням"/>
<c:menu_item acl="" page="income_monthly_rpt.cfm" label="Выручка по месяцам"/> --->
<li class="menu-title">Справочники</li>
<!--- <c:menu_item acl="" page="svc_ls.cfm" label="Сервисы"/> --->
<c:menu_item acl="" page="contragent_ls.cfm" label="Контрагенты"/>
<!--- <c:menu_item acl="" page="measure_ls.cfm" label="Единицы измерения"/>
<c:menu_item acl="" page="usr_ls.cfm" label="Пользователи"/>
--->
<!--- <li class="menu-title">Пользователь</li>
<cfif request.usrAuthenticated()>
<cfquery name="qUsr" datasource="#request.DS#">
select shortname/*, login, firstname, middlename, lastname*/
from usr
where usr_id=<cfqueryparam cfsqltype="CF_SQL_INTEGER" value=#request.usr_id#/>
</cfquery>
<li class="menu-item-noaction">#qUsr.shortname#</li> <!---#request.usr_id#--->
<c:menu_item acl="" page="password.cfm" queryString="#ATTRIBUTES.fwx#" label="Смена пароля"/>
<c:menu_item acl="" page="logout.cfm" queryString="target_page=#URLEncodedFormat(ATTRIBUTES.thisUrl)#" label="Выход"/>
<cfelse>
<c:menu_item acl="" page="saml/login.cfm" queryString="target_page=#URLEncodedFormat(ATTRIBUTES.thisUrl)#" label="Вход через WebSSO"/>
<c:menu_item acl="" page="login.cfm" queryString="#ATTRIBUTES.fwx#" label="Вход"/>
<c:menu_item acl="" page="logout.cfm" queryString="target_page=#URLEncodedFormat(ATTRIBUTES.thisUrl)#" label="Выход"/>
</cfif> --->
</ul>
</cfoutput>
<cfexit method="exittag"/>
+7
View File
@@ -0,0 +1,7 @@
<h1>PAYG REPORT</h1>
Установление сессии.
Если валидной сессии нет, отправляем браузер за аутентификацией к IDP.
Получаем в токене данные пользователя и время жизни, кладем в сессию.
По истечении установленного времени (скажем, половины срока жизни токена) идем к IDP за рефрешем
Сертификат открытого ключа можно каждый раз получать от IDP.
Запрос к IDP идет только для освежения сессии, а не на каждый запрос. Логаут на IDP не проверяется при каждом запросе.
+4
View File
@@ -0,0 +1,4 @@
/*! jQuery v1.7.1 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
+3
View File
@@ -0,0 +1,3 @@
/* JQuery Searchable DropDown Plugin | Copyright (c) 2012 xhaggi */
/*modidfed 14.11.2016|18.01.2018 by msyu - display:inline-block, padding-top: 0 for chrome; BUG: maxListSize IS IGNORED, use instead maxMultiMatch; chrome highlighted position correction;*/
(function($){var B=register("searchable");B.defaults={maxListSize:100,maxMultiMatch:50,exactMatch:false,wildcards:true,ignoreCase:true,warnMultiMatch:"top {0} matches ...",warnNoMatch:"no matches ...",latency:200,zIndex:"auto"};B.execute=function(g,h){var j=null;var k=null;var l=null;if($.browser.msie&&parseInt(jQuery.browser.version)<7)return this;if(this.nodeName!="SELECT"||this.size>1)return this;var m=$(this);var n={index:-1,options:null};var o="lang";var p=false;$.browser.chrome=/chrome/.test(navigator.userAgent.toLowerCase());if($.browser.chrome)$.browser.safari=false;if($.meta){g=$.extend({},options,m.data())}var q=$("<div/>");var r=$("<div/>");var t=$("<input/>");var u=$("<select/>");var x=$("<option>"+g.warnMultiMatch.replace(/\{0\}/g,g.maxMultiMatch)+"</option>").attr("disabled","true");var y=$("<option>"+g.warnNoMatch+"</option>").attr("disabled","true");var z={option:function(a){return $(u.get(0).options[a])},selected:function(){return u.find(":selected")},selectedIndex:function(a){if(a>-1)u.get(0).selectedIndex=a;return u.get(0).selectedIndex},size:function(a){u.attr("size",Math.max(2,Math.min(a,20)))},reset:function(){if((m.get(0).selectedIndex-1)==m.data("index"))return;var a=m.get(0).selectedIndex;var b=m.get(0).length;var c=Math.floor(g.maxMultiMatch/2);var d=Math.max(1,(a-c));var e=Math.min(b,Math.max(g.maxMultiMatch,(a+c)));var f=a-d;u.empty();this.size(e-d);for(var i=d;i<e;i++)u.append($(m.get(0).options[i]).clone().attr(o,i-1));if(e>g.maxMultiMatch)u.append(x);u.get(0).selectedIndex=f}};draw();var A=false;r.mouseover(function(){A=true});r.mouseout(function(){A=false});u.mouseover(function(){A=true});u.mouseout(function(){A=false});t.click(function(e){if(!p)enable(e,true);else disable(e,true)});t.blur(function(e){if(!A&&p)disable(e,true)});m.keydown(function(e){if(e.keyCode!=9&&!e.shiftKey&&!e.ctrlKey&&!e.altKey)t.click()});m.click(function(e){u.focus()});u.click(function(e){if(z.selectedIndex()<0)return;disable(e)});u.focus(function(e){t.focus()});u.blur(function(e){if(!A)disable(e,true)});u.mousemove(function(e){if($.browser.opera&&parseFloat(jQuery.browser.version)>=9.8)return true;var a=Math.floor(parseFloat(/([0-9\.]+)px/.exec(z.option(0).css("font-size"))));var b=4;if($.browser.opera)b=2.5;if($.browser.safari)b=3;if($.browser.chrome)b=3.4;a+=a/b;z.selectedIndex(Math.floor((e.pageY-u.offset().top+this.scrollTop)/a))});r.click(function(e){t.click()});t.keyup(function(e){if(jQuery.inArray(e.keyCode,new Array(9,13,16,33,34,35,36,38,40))>-1)return true;l=$.trim(t.val().toLowerCase());clearSearchTimer();j=setTimeout(searching,g.latency)});t.keydown(function(e){if(e.keyCode==9){disable(e)}if(e.shiftKey||e.ctrlKey||e.altKey)return;switch(e.keyCode){case 13:disable(e);m.focus();break;case 27:disable(e,true);m.focus();break;case 33:if(z.selectedIndex()-u.attr("size")>0){z.selectedIndex(z.selectedIndex()-u.attr("size"))}else{z.selectedIndex(0)}synchronize();break;case 34:if(z.selectedIndex()+u.attr("size")<u.get(0).options.length-1){z.selectedIndex(z.selectedIndex()+u.attr("size"))}else{z.selectedIndex(u.get(0).options.length-1)}synchronize();break;case 38:if(z.selectedIndex()>0){z.selectedIndex(z.selectedIndex()-1);synchronize()}break;case 40:if(z.selectedIndex()<u.get(0).options.length-1){z.selectedIndex(z.selectedIndex()+1);synchronize()}break;default:return true}return false});function draw(){m.css("text-decoration","none");m.width(m.outerWidth());m.height(m.outerHeight());q.css("position","relative");/*msyu*/q.css("display","inline-block");q.css("margin","0");/*/msyu*/q.css("width",m.outerWidth());if($.browser.msie)q.css("z-index",h);r.css({"position":"absolute","top":0,"left":0,"width":m.outerWidth(),"height":m.outerHeight(),/*msyu*/"background-color":"#BBEE55","opacity":"0.2"/*/msyu*/});t.attr("type","text");t.hide();t.height(m.outerHeight());t.css({"position":"absolute","top":0,"left":0,"margin":"0px","padding":"0px","outline-style":"none","border-style":"solid","border-bottom-style":"none","border-color":"transparent","background-color":"transparent"});var a=new Array();a.push("border-left-width");a.push("border-top-width");a.push("font-size");a.push("font-stretch");a.push("font-variant");a.push("font-weight");a.push("color");a.push("text-align");a.push("text-indent");a.push("text-shadow");a.push("text-transform");a.push("padding-left");a.push("padding-top");for(var i=0;i<a.length;i++)t.css(a[i],m.css(a[i]));if($.browser.msie&&parseInt(jQuery.browser.version)<8){t.css("padding","0px");t.css("padding-left","3px");t.css("border-left-width","2px");t.css("border-top-width","3px")}else if($.browser.chrome){t.height(m.innerHeight());t.css("text-transform","none");t.css("padding-left",parseFloatPx(t.css("padding-left"))+3);t.css("padding-top",/*2*/0)}else if($.browser.safari){t.height(m.innerHeight());t.css("padding-top",2);t.css("padding-left",3);t.css("text-transform","none")}else if($.browser.opera){t.height(m.innerHeight());var b=parseFloatPx(m.css("padding-left"));t.css("padding-left",b==1?b+1:b);t.css("padding-top",0)}else if($.browser.mozilla){t.css("padding-top","0px");t.css("border-top","0px");t.css("padding-left",parseFloatPx(m.css("padding-left"))+3)}else{t.css("padding-left",parseFloatPx(m.css("padding-left"))+3);t.css("padding-top",parseFloatPx(m.css("padding-top"))+1)}var c=parseFloatPx(m.css("padding-left"))+parseFloatPx(m.css("padding-right"))+parseFloatPx(m.css("border-left-width"))+parseFloatPx(m.css("border-left-width"))+23;t.width(m.outerWidth()-c);var w=m.css("width");var d=m.outerWidth();m.css("width","auto");d=d>m.outerWidth()?d:m.outerWidth();m.css("width",w);u.hide();z.size(m.get(0).length);u.css({"position":"absolute","top":m.outerHeight(),"left":0,"width":d,"border":"1px solid #333","font-weight":"normal","padding":0,"background-color":m.css("background-color"),"text-transform":m.css("text-transform")});var e=/^\d+$/.test(m.css("z-index"))?m.css("z-index"):1;if(g.zIndex&&/^\d+$/.test(g.zIndex))e=g.zIndex;r.css("z-index",(e).toString(10));t.css("z-index",(e+1).toString(10));u.css("z-index",(e+2).toString(10));m.wrap(q);m.after(r);m.after(t);m.after(u)};function enable(e,s,v){if(m.attr("disabled"))return false;m.prepend("<option />");if(typeof v=="undefined")p=!p;z.reset();synchronize();store();if(s)u.show();t.show();t.focus();t.select();m.get(0).selectedIndex=0;if(typeof e!="undefined")e.stopPropagation()};function disable(e,a){p=false;m.find(":first").remove();clearSearchTimer();t.hide();u.hide();if(typeof a!="undefined")restore();populate();if(typeof e!="undefined")e.stopPropagation()};function clearSearchTimer(){if(j!=null)clearTimeout(j)};function populate(){if(z.selectedIndex()<0||z.selected().get(0).disabled)return;m.get(0).selectedIndex=parseInt(u.find(":selected").attr(o));m.change();m.data("index",new Number(m.get(0).selectedIndex))};function synchronize(){if(z.selectedIndex()>-1&&!z.selected().get(0).disabled)t.val(u.find(":selected").text());else t.val(m.find(":selected").text())};function store(){n.index=z.selectedIndex();n.options=new Array();for(var i=0;i<u.get(0).options.length;i++)n.options.push(u.get(0).options[i])};function restore(){u.empty();for(var i=0;i<n.options.length;i++)u.append(n.options[i]);z.selectedIndex(n.index);z.size(n.options.length)};function escapeRegExp(a){var b=["/",".","*","+","?","|","(",")","[","]","{","}","\\","^","$"];var c=new RegExp("(\\"+b.join("|\\")+")","g");return a.replace(c,"\\$1")};function searching(){if(k==l){j=null;return}var a=0;k=l;u.hide();u.empty();var b=escapeRegExp(l);if(g.exactMatch)b="^"+b;if(g.wildcards){b=b.replace(/\\\*/g,".*");b=b.replace(/\\\?/g,".")}var c=null;if(g.ignoreCase)c="i";l=new RegExp(b,c);for(var i=1;i<m.get(0).length&&a<g.maxMultiMatch;i++){if(l.length==0||l.test(m.get(0).options[i].text)){var d=$(m.get(0).options[i]).clone().attr(o,i-1);if(m.data("index")==i)d.text(m.data("text"));u.append(d);a++}}if(a>=1){z.selectedIndex(0)}else if(a==0){u.append(y)}if(a>=g.maxMultiMatch){u.append(x)}z.size(a);u.show();j=null};function parseFloatPx(a){try{a=parseFloat(a.replace(/[\s]*px/,""));if(!isNaN(a))return a}catch(e){}return 0};return};function register(d){var e=$[d]={};$.fn[d]=function(b){b=$.extend(e.defaults,b);var c=this.size();return this.each(function(a){e.execute.call(this,b,c-a)})};return e}})(jQuery);
+79
View File
@@ -0,0 +1,79 @@
<!---
Access check aka проверка доступа.
Если доступа нет, код, заключенный внутри тега, не выполняется, текст не выводится.
Два варианта использования.
1. При заданном значении действия проверяется наличие этого доступа к объекту, ответ да-нет
2. Проверяется уровень доступа к заданному объекту
Для пустого объекта
Если задать строковый атрибут output, в переменную с таким именем запишется
TRUE(доступ разрешен)/FALSE(доступ запрещен).
Тег обязательно должен быть закрыт.
---><cfsilent>
<!--- проверка на закрытость тега - без закрытия возможна неоднозначность со вложенными тегами --->
<cfif NOT thisTag.hasEndTag>
<cfthrow
type="custom" message="Unclosed AC.CFM tag found."
detail="AC.CFM tag must be closed. Self-closed tag is acceptable, e.g.: &lt;cfmodule template=""mod/ac.cfm"" /&gt;.">
</cfif>
<cfif thisTag.ExecutionMode is 'start'>
<cfparam name="ATTRIBUTES.obj" type="string" default=""/><!---
объект, к которому проверяется доступ --->
<cfparam name="ATTRIBUTES.act" type="numeric" default="#request.PERMISSION_READ#"/><!---
действие, которое проверяется --->
<cfparam name="ATTRIBUTES.output" type="string" default=""/>
<cfparam name="ATTRIBUTES.permissionOut" type="string" default=""/>
<cfset permission=request.PERMISSION_NONE/>
<cfif ATTRIBUTES.obj EQ "">
<cfif #request.usrAuthenticated()#>
<cfset permission=request.PERMISSION_WRITE/>
<cfelse>
<cfset permission=request.PERMISSION_READ/>
</cfif>
<cfset permitted=(ATTRIBUTES.act EQ #request.PERMISSION_READ# OR #request.usrAuthenticated()#)/>
<cfelse>
<cftry>
<cfset permitted=(len(ATTRIBUTES.obj) GT 0)>
<!---*** Максимальный доступ для перечисленных объектов и ролей
Можно подумать о минимальном--->
<cfquery name="qACL" datasource="#request.DS#">
select coalesce(max(permission),0) as permission
from usr_role ur
join acl on acl.role_id=ur.role_id
where ur.usr_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#request.usr_id#">
and acl.obj in (<cfqueryparam cfsqltype="cf_sql_varchar" value="#ATTRIBUTES.obj#" list="true">)
</cfquery>
<cfset permitted=(qACL.permission GE ATTRIBUTES.act)>
<cfset permission=#qACL.permission#/>
<cfcatch type="database">
<cfset permitted="Yes"/><!---***--->
<cfrethrow/>
</cfcatch>
</cftry>
</cfif>
<cfif len(ATTRIBUTES.output)>
<cfset setVariable("CALLER.#ATTRIBUTES.output#", permitted)><!---boolean--->
</cfif>
<cfif len(ATTRIBUTES.permissionOut)>
<cfset setVariable("CALLER.#ATTRIBUTES.permissionOut#", permission)><!---integer 0 1 2--->
</cfif>
<cfif NOT permitted><cfexit method="EXITTAG"></cfif>
</cfif><!---thisTag.ExecutionMode is 'start'--->
</cfsilent>
+12
View File
@@ -0,0 +1,12 @@
<!---v0.2 19:01 06.10.2020
---><cfparam name="ATTRIBUTES.contenttype"/>
<cfswitch expression=#ATTRIBUTES.contenttype#>
<cfcase value="text/plain"><img src="img/mimetype/text.png"/></cfcase>
<cfcase value="text/html"><img src="img/mimetype/html.png"/></cfcase>
<cfcase value="application/pdf"><img src="img/mimetype/pdf.png"/></cfcase>
<cfcase value="image/gif,image/png,image/jpeg"><img src="img/mimetype/image.png"/></cfcase>
<cfcase value="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"><img src="img/mimetype/excel.png"/></cfcase>
<cfcase value="application/vnd.ms-powerpoint"><img src="img/mimetype/powerpoint.png"/></cfcase>
<cfcase value="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"><img src="img/mimetype/word.png"/></cfcase>
<cfdefaultcase><img src="img/mimetype/document.png"/></cfdefaultcase>
</cfswitch><cfexit method="exittag"/>
+23
View File
@@ -0,0 +1,23 @@
<cfsilent>
<cfparam name="ATTRIBUTES.name"/>
<cfparam name="ATTRIBUTES.value" default="1"/>
<cfif structKeyExists(ATTRIBUTES,"checked")>
<cfset checked=!(ATTRIBUTES.checked EQ "0" OR ATTRIBUTES.checked EQ "")/>
<cfelse>
<cfset checked=!(ATTRIBUTES.container[ATTRIBUTES.name] EQ "0" OR ATTRIBUTES.container[ATTRIBUTES.name] EQ "")/>
</cfif>
<cfparam name="ATTRIBUTES.suffix" default=""/>
<cfparam name="ATTRIBUTES.id" default="#ATTRIBUTES.name##ATTRIBUTES.suffix#"/>
<cfparam name="ATTRIBUTES.disabled" type="boolean" default="No"/>
<cfset attributeList="name,value,checked,container,suffix,id,disabled"/>
</cfsilent><cfoutput><input type="checkbox" name="#ATTRIBUTES.name#"<!---
---><cfif len(ATTRIBUTES.id)> id=#ATTRIBUTES.id#</cfif> value="#ATTRIBUTES.value#"<!---
---><cfif checked> checked="checked"</cfif><!---
---><cfif ATTRIBUTES.disabled> disabled="disabled"</cfif><!---
passthrough additional attributes
---><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop>/></cfoutput><cfexit method="exittag"/>
+30
View File
@@ -0,0 +1,30 @@
<cfparam name="ATTRIBUTES.lang" type="string" default=""/>
<cfparam name="request.language" type="string" default=""/>
<cfif len(ATTRIBUTES.lang) AND #ATTRIBUTES.lang# NEQ #request.language#>
<cfexit method="exittag"/>
</cfif>
<cfif thisTag.executionMode IS "end">
<!--- <cfloop collection=#CALLER# item="item">
<cfset structInsert(variables, item, CALLER[item], false)/>
</cfloop> --->
<cfassociate basetag="cf_table" datacollection="columns"/>
<cfset attributeList=""/> <!--- *** сделать проброс атрибутов --->
<cfparam name="thisTag.th" type="array" default=#[{content="",field=""}]#/><!---контейнер для данных вложенного элемента TH. Предусмотрен только один элемент массива, остальные игнорируются--->
<!---<cfparam name="thisTag.td" type="array" default=#[{content="",field=""}]#/>--->
<cfparam name="thisTag.td" type="array" default=#thisTag.th#/><!---контейнер для данных вложенного элемента TD. Предусмотрен только один элемент массива, остальные игнорируются--->
<!---Зачем массив? - потому что массив вложенных тегов, а у нас считается только первый вложенный тег TD--->
<cfset ATTRIBUTES.td=#thisTag.td#/><!---поле, видное включающему тегу table в коллекции columns--->
<cfset ATTRIBUTES.th=#thisTag.th#/><!---поле, видное включающему тегу table в коллекции columns--->
<cfset ATTRIBUTES.content=thisTag.generatedContent/>
<cfparam name="ATTRIBUTES.field" default="#thisTag.td[1].field#"/><!---***---><!---настоящий атрибут - имя поля запроса (query) для ВЫВОДА, может задаваться как атрибут тега--->
<cfparam name="ATTRIBUTES.formatter" type="function" default=#function (x) {return x;}#/>
<cfparam name="ATTRIBUTES.sortable" type="boolean" default=true/>
<cfparam name="ATTRIBUTES.visible" type="boolean" default=true/>
<cfparam name="ATTRIBUTES.columnOrder" type="integer" default=0/>
<!--- Желательное поведение сортировки колонок: для некоторых колонок указан порядок, на этом месте они и оказываются. Не указан - идут в порядке появления в коде. Если 2 колонки с одним порядком сортировки, первой выводится та, которая первая по тексту. --->
</cfif>
+46
View File
@@ -0,0 +1,46 @@
<cfsilent>
<cfimport prefix="c" taglib="."/>
<!---*** идея включить титул в метаданные была не совсем пустой, но когда титул определяется в селекте, это не слишком удобно --->
<cfassociate basetag="cf_grid_head" datacollection="headersArray"/>
<cfset envelope=getBaseTagData('cf_grid_head',1)/>
<cfparam name="ATTRIBUTES.title" type="string" default="#envelope.ATTRIBUTES.titleMap[ATTRIBUTES.name].title#"/>
<cfparam name="ATTRIBUTES.name" type="string"/><!--- Заголовок указвается на том поле, по которому будет сортировка, а не на том, которе отображается --->
<cfparam name="ATTRIBUTES.arrows" type="boolean" default="Yes"/>
<cfset attributeList="name,arrows,title"/>
<!--- В данном случае реализован подход: дополнительные атрибуты передаются вниз.
Другой вариант - создавать атрибут extra, в который писать суффикс QueryString.
Первый подход, использованный здесь, позволяет иметь доступ к дополнительным атрибутам, но непонятно, зачем - ведь их имена все равно неизвестны.
Очевидный минус этого подхода - возможный конфликт имен с именами существующих атрибутов --->
<cfset extraAttributes=structNew()/>
<!--- дополнительные атрибуты родительского тега--->
<cfif StructKeyExists(envelope, "extraAttributes") AND isStruct(envelope.extraAttributes)>
<cfloop collection=#envelope.extraAttributes# item="attr">
<cfif NOT listFindNoCase(attributeList, attr)><!--- проверка относительно локальных атрибутов, чтобы их не перетереть--->
<cfset val="#structFind(envelope.extraAttributes, attr)#"/>
<cfif IsSimpleValue(val)>
<cfset structInsert(extraAttributes, attr, val)/>
</cfif>
</cfif>
</cfloop>
</cfif>
<cfloop collection=#ATTRIBUTES# item="attr">
<cfif NOT listFindNoCase(attributeList, attr)>
<cfset val="#structFind(ATTRIBUTES, attr)#"/>
<cfif IsSimpleValue(val)>
<cfset structInsert(extraAttributes, attr, val, "Yes")/><!--- локальные атрибуты перетрут родительские --->
</cfif>
</cfif>
</cfloop>
</cfsilent><cfif thisTag.executionMode is "end"><cfoutput>#ATTRIBUTES.title#
<cfif ATTRIBUTES.arrows><c:order_arrows sortArray=#envelope.ATTRIBUTES.sortArray# n=#envelope.ATTRIBUTES.titleMap[ATTRIBUTES.name].ordinal# attributeCollection=#extraAttributes#/></cfif></cfoutput></cfif>
+178
View File
@@ -0,0 +1,178 @@
<!--- combobox
v3.1 23.10.2020 support of list in multiple selection
v3.0 12.08.2016 ATTRIBUTES.readonly
v2.1 04.05.2016 ATTRIBUTES.disabled
v2 с форматным выводом
---><cfprocessingdirective suppresswhitespace="true">
<!---
<cfparam name="ATTRIBUTES.query" type="query"/>
<cfparam name="ATTRIBUTES.queryString" type="string"/>
<cfparam name="ATTRIBUTES.list" type="string"/>
--->
<cfparam name="ATTRIBUTES.DS" type="string" default="#request.DS#"/>
<cfparam name="ATTRIBUTES.combo"/><!--- имя контрола (name)--->
<cfparam name="ATTRIBUTES.key"/><!--- Имя ключевого поля---><!--- ограничение: не поддерживаем составные ключи --->
<cfparam name="ATTRIBUTES.display" default=""/><!--- имя поля резалтсета --->
<cfparam name="ATTRIBUTES.displayf" default=""/><!--- форматный вывод, поля резалтсета писать: ##field##, например "*##field1##:##field2##*" --->
<cfparam name="ATTRIBUTES.selected" default=""/><!--- в случае base64 - завернуто в base64--->
<cfparam name="ATTRIBUTES.base64" default="No"/><!---*** это архитектурная ошибка. Base64 is url unsafe. Но поскольку все передается POST-ом, обычно не проявляется --->
<cfparam name="ATTRIBUTES.disabled" type="boolean" default="No"/>
<cfparam name="ATTRIBUTES.style_selector" default=""/>
<cfparam name="ATTRIBUTES.style_spec" type="struct" default=#structNew()#/>
<cfparam name="ATTRIBUTES.class_selector" default=""/>
<cfparam name="ATTRIBUTES.class_spec" type="struct" default=#structNew()#/>
<cfparam name="ATTRIBUTES.flag_disabled" type="string" default=""/><!--- проверяется на > 0. Возможно, не следует отключать выбранное значение --->
<cfparam name="ATTRIBUTES.readonly" type="boolean" default="false"/><!--- в случае readonly выводится текст и скрытое поле с ID, если множественное выделение, то надо наверно выводить все выделенные элементы? --->
<cfparam name="ATTRIBUTES.extra" type="string" default=""/><!--- --->
<cfset attributeList="template,query,queryString,combo,key,display,displayf,selected,empty,DS,base64,disabled,style_selector,style_spec,class_selector,class_spec,flag_disabled,readonly,extra"/>
<cffunction name="escape64" returnType="string">
<cfargument name="val" type="string">
<cfif #ATTRIBUTES.base64#>
<cfreturn ToBase64(val)>
<cfelse>
<cfreturn val>
</cfif>
</cffunction>
<cffunction name="isSelected" returnType="boolean">
<!--- tests for presense of key (second arg) in passed array (first arg) or, if sel is simple value just compares key and sel.
Used for checking against multiple alternatives like "save" OR "saveAndClose"
--->
<cfargument name="sel">
<cfargument name="key">
<cfscript>
if (isArray(sel)) {
for(i=1; i <= ArrayLen(sel); i++){
if (sel[i]==key) {return true;}
}
return false;
} else { //считаем, что из сложных типов тут бывает только массив
if (!isSimpleValue(sel)) {return false;}
/*return (sel == key);*/
return listFind(sel,key);
}
</cfscript>
</cffunction>
<cffunction name="strSelected" returnType="string">
<cfargument name="sel">
<cfargument name="key">
<!---unsupported in CF8: <cfreturn (isSelected(sel,key)? " selected" : "")>--->
<cfif isSelected(sel,key)>
<cfreturn " selected">
<cfelse>
<cfreturn "">
</cfif>
</cffunction>
<!--- функция условного обертывания --->
<cffunction name="w" returnType="string">
<cfargument name="prefix"/>
<cfargument name="input"/>
<cfargument name="suffix" default=""/>
<cfif len(input) GT 0>
<cfreturn "#prefix##input##suffix#"/>
<cfelse>
<cfreturn ""/>
</cfif>
</cffunction>
<cffunction name="strAttribute" returnType="string">
<!---returns formatted string ' attribute="value"',
where attribute name is the first argument,
and value is taken from passed structure(third argument) by key (second argument)--->
<cfargument name="name"/>
<cfargument name="selector"/>
<cfargument name="spec" type="struct"/>
<cfif StructKeyExists(spec, selector)>
<cfreturn ' #name#="#structFind(spec, selector)#"'/>
<cfelse>
<cfreturn "">
</cfif>
</cffunction>
<!--- ---------------------------------------------------------------------------------- --->
<cfif structKeyExists(ATTRIBUTES,"query")>
<cfset qSel=ATTRIBUTES.query>
<cfelseif structKeyExists(ATTRIBUTES,"queryString")>
<cfquery name="qSel" datasource="#ATTRIBUTES.DS#">
#preserveSingleQuotes(ATTRIBUTES.queryString)#
</cfquery>
<cfelseif structKeyExists(ATTRIBUTES,"list")>
<cfset qSel=#queryNew("item")#/>
<cfloop list=#ATTRIBUTES.list# item="item">
<cfset queryAddRow(qSel,{"item":"#item#"})/>
</cfloop>
</cfif>
<!--- parse class specifications--->
<cfscript>
</cfscript>
<cfif ATTRIBUTES.readonly>
<cfif isArray(ATTRIBUTES.selected)>
<cfset selectedList=ArrayToList(ATTRIBUTES.selected)/>
<cfelse>
<cfset selectedList=ATTRIBUTES.selected/>
</cfif>
<cfquery name="qSelFiltered" dbtype="query">
select * from qSel where <cfif len(selectedList)>#ATTRIBUTES.key# in (#selectedList#)<cfelse>1=0</cfif>
</cfquery>
<cfoutput>
<div class="textbox-disabled" style="display:inline-block;"<cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop>>
<cfif qSelFiltered.recordCount GT 0>
<cfloop query="qSelFiltered"><!---
---><cfset key=evaluate("#ATTRIBUTES.key#")/><!---
---><cfset key=trim(escape64(key))/><!---
---><div><input type="hidden" name="#ATTRIBUTES.combo#" value="#key#"/>#Evaluate(ATTRIBUTES.display)#<cfset Evaluate("WriteOutput('#ATTRIBUTES.displayf#')")/></div>
</cfloop>
<cfelseif isDefined("ATTRIBUTES.empty")>
<input type="hidden" name="#ATTRIBUTES.combo#" value="#ATTRIBUTES.empty#"/><!-- #ATTRIBUTES.combo#: nothing selected -->
&nbsp;&nbsp;&nbsp;
<cfelse>
&nbsp;&nbsp;&nbsp;
</cfif>
</div>
</cfoutput>
<cfelse><!--- ATTRIBUTES.readonly --->
<cfoutput>
<select name="#ATTRIBUTES.combo#"<!---
passthrough additional attributes
---><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop><cfif ATTRIBUTES.disabled> disabled="disabled"</cfif><cfif len(ATTRIBUTES.extra)>#ATTRIBUTES.extra#</cfif>>
<cfif isDefined("ATTRIBUTES.empty")>
<option value="#ATTRIBUTES.empty#"></option><!--- *** Надо было делать не пустое, а дефолтное значение, чтобы можно было ввести, например, {N/A, -1} --->
</cfif>
<cfloop query=qSel>
<cfset key=evaluate("#ATTRIBUTES.key#")/><!--- в контексте запроса, поэтому находится в цикле! *** не самый лучший способ в смысле производительности --->
<cfset key=trim(escape64(key))/>
<cfset str_sel=strSelected(ATTRIBUTES.selected, key)/>
<option value="#key#"#str_sel#<!---
---><cfif len(ATTRIBUTES.style_selector) GT 0>#strAttribute("style",
Evaluate(ATTRIBUTES.style_selector),ATTRIBUTES.style_spec)#</cfif><!---
---><cfif len(ATTRIBUTES.class_selector) GT 0>#strAttribute("class", Evaluate(ATTRIBUTES.class_selector),ATTRIBUTES.class_spec)#</cfif><!---
---><cfif len(ATTRIBUTES.flag_disabled) GT 0><cfif Evaluate(ATTRIBUTES.flag_disabled) GT 0> disabled="1"</cfif></cfif><!---
--->>#Evaluate(ATTRIBUTES.display)#<cfset Evaluate("WriteOutput('#ATTRIBUTES.displayf#')")/></option>
</cfloop>
</select>
</cfoutput>
</cfif>
</cfprocessingdirective><cfexit method="EXITTAG"/>
+21
View File
@@ -0,0 +1,21 @@
<cfsilent>
<cfparam name="ATTRIBUTES.name"/>
<cfif structKeyExists(ATTRIBUTES,"value")>
<cfset value=#ATTRIBUTES.value#/>
<cfelse>
<cfset value=#ATTRIBUTES.container[ATTRIBUTES.name]#/>
</cfif>
<cfparam name="ATTRIBUTES.suffix" default=""/>
<cfparam name="ATTRIBUTES.id" default="#ATTRIBUTES.name##ATTRIBUTES.suffix#"/>
<cfparam name="ATTRIBUTES.format" default="YYYY-MM-DD"/>
<cfparam name="ATTRIBUTES.size" default="#len(ATTRIBUTES.format)#"/>
<cfparam name="ATTRIBUTES.disabled" type="boolean" default="No"/>
<cfset attributeList="name,value,container,suffix,id,format,size,disabled"/>
</cfsilent><cfoutput><input type="text" name="#ATTRIBUTES.name#"<cfif len(ATTRIBUTES.id)> id=#ATTRIBUTES.id#</cfif> value="#dateFormat(value, ATTRIBUTES.format)#" size="#ATTRIBUTES.size#"<cfif ATTRIBUTES.disabled> disabled="disabled"</cfif><!---
passthrough additional attributes
---><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop>/></cfoutput><cfexit method="exittag"/>
+29
View File
@@ -0,0 +1,29 @@
<cfsilent>
<cfparam name="ATTRIBUTES.name"/>
<cfif structKeyExists(ATTRIBUTES,"value")>
<cfset value=#ATTRIBUTES.value#/>
<cfelse>
<cfset value=#ATTRIBUTES.container[ATTRIBUTES.name]#/>
</cfif>
<cfparam name="ATTRIBUTES.suffix" default=""/>
<cfparam name="ATTRIBUTES.id" default="#ATTRIBUTES.name##ATTRIBUTES.suffix#"/>
<cfparam name="ATTRIBUTES.dformat" default="YYYY-MM-DD"/>
<cfparam name="ATTRIBUTES.tformat" default="HH:MM"/>
<cfparam name="ATTRIBUTES.size" default="#len(ATTRIBUTES.dformat)+len(ATTRIBUTES.tformat)+1#"/>
<cfparam name="ATTRIBUTES.disabled" type="boolean" default="No"/>
<cfparam name="ATTRIBUTES.timeFirst" type="boolean" default="No"/>
<cfif ATTRIBUTES.timeFirst>
<cfset value="#timeFormat(value, ATTRIBUTES.tformat)# #dateFormat(value, ATTRIBUTES.dformat)#"/>
<cfelse>
<cfset value="#dateFormat(value, ATTRIBUTES.dformat)# #timeFormat(value, ATTRIBUTES.tformat)#"/>
</cfif>
<cfset attributeList="name,value,container,suffix,id,dformat,tformat,size,disabled"/>
</cfsilent><cfoutput><input type="text" name="#ATTRIBUTES.name#"<cfif len(ATTRIBUTES.id)> id=#ATTRIBUTES.id#</cfif> value="#value#" size="#ATTRIBUTES.size#"<cfif ATTRIBUTES.disabled> disabled="disabled"</cfif><!---
passthrough additional attributes
---><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop>/></cfoutput><cfexit method="exittag"/>
+18
View File
@@ -0,0 +1,18 @@
<!---moved to layout--->
<!---<cfif thisTag.executionMode IS "end" OR NOT thisTag.hasEndTag>
<cfparam name="ATTRIBUTES.backUrl" type="string" default="."/>
<cfparam name="ATTRIBUTES.enable" type="boolean" default="No"/>
<cfoutput>
<div class="row" style="margin:0px;">
<div class="col-sm-3" style="padding: 0px;">
<button type="submit" name="save" class="btn btn-secondary" style="width: 100%; padding: 6px 0px;"<cfif NOT ATTRIBUTES.enable> disabled</cfif>>#request.i18("Сохранить","Save")#</button>
</div>
<div class="col-sm-6" style="padding: 0px 5px;">
<button type="submit" name="saveAndClose" class="btn btn-secondary" style="width: 100%; padding: 6px 0px;"<cfif NOT ATTRIBUTES.enable> disabled</cfif>>#request.i18("Сохранить и закрыть","Save and Close")#</button>
</div>
<div class="col-sm-3" style="padding: 0px;">
<button type="button" name="close" class="btn btn-secondary" style="width: 100%; padding: 6px 0px;" onClick="document.location.href='#ATTRIBUTES.backUrl#'">#request.i18("Закрыть","Close")#</button>
</div>
</div>
</cfoutput>
</cfif>--->
+18
View File
@@ -0,0 +1,18 @@
<cfsilent>
<cfparam name="ATTRIBUTES.titleMap" default=#structNew()#/>
<cfparam name="ATTRIBUTES.sortArray" default=#arrayNew(1)#/>
<cfset attributeList="titleMap,sortArray"/>
<cfset extraAttributes=structNew()/>
<cfloop collection=#ATTRIBUTES# item="attr">
<cfif NOT listFindNoCase(attributeList, attr)>
<cfset val="#structFind(ATTRIBUTES, attr)#"/>
<cfif IsSimpleValue(val)>
<cfset structInsert(extraAttributes, attr, val)/>
</cfif>
</cfif>
</cfloop>
</cfsilent><!---
---><cfif thisTag.executionMode is "start"><tr><cfelseif thisTag.executionMode is "end"></tr></cfif>
+11
View File
@@ -0,0 +1,11 @@
<cfsilent>
<cfparam name="ATTRIBUTES.canWrite" type="boolean" default="Yes"/>
<cfif NOT ATTRIBUTES.canWrite>
<cfexit method="exitTag"/>
</cfif>
<cfparam name="ATTRIBUTES.entity"/>
<cfparam name="ATTRIBUTES.key" default="#ATTRIBUTES.entity#_id"/>
<cfparam name="ATTRIBUTES.extra" default=""/>
<cfparam name="ATTRIBUTES.fwx"/>
<cfparam name="ATTRIBUTES.title" default="создать"/>
</cfsilent><cfoutput><a href="#ATTRIBUTES.entity#.cfm?#ATTRIBUTES.key#=-1<cfif len(ATTRIBUTES.extra)>&#ATTRIBUTES.extra#</cfif>&#ATTRIBUTES.fwx#" title="#ATTRIBUTES.title#" class="add"></a></cfoutput><cfexit method="exitTag"/>
+10
View File
@@ -0,0 +1,10 @@
<cfsilent>
<cfparam name="ATTRIBUTES.canWrite" type="boolean" default="Yes"/>
<cfif NOT ATTRIBUTES.canWrite>
<cfexit method="exitTag"/>
</cfif>
<cfparam name="ATTRIBUTES.entity"/>
<cfparam name="ATTRIBUTES.key" default="#ATTRIBUTES.entity#_id"/>
<cfparam name="ATTRIBUTES.id"/>
<cfparam name="ATTRIBUTES.fwx"/>
</cfsilent><cfoutput><a href="#ATTRIBUTES.entity#_del.cfm?#ATTRIBUTES.key#=#ATTRIBUTES.id#&#ATTRIBUTES.fwx#" title="удалить" name="#ATTRIBUTES.id#" class="del"></a></cfoutput><cfexit method="exitTag"/>
+9
View File
@@ -0,0 +1,9 @@
<!---***deprecated. Use link_view_edit---><cfsilent>
<cfparam name="ATTRIBUTES.canWrite" type="boolean" default="Yes"/>
<cfparam name="ATTRIBUTES.entity"/>
<cfparam name="ATTRIBUTES.key" default="#ATTRIBUTES.entity#_id"/>
<cfparam name="ATTRIBUTES.id"/>
<cfparam name="ATTRIBUTES.fwx"/>
<cfparam name="ATTRIBUTES.title_edit" default="редактировать"/>
<cfparam name="ATTRIBUTES.title_view" default="просмотреть"/>
</cfsilent><cfoutput><a href="#ATTRIBUTES.entity#.cfm?#ATTRIBUTES.key#=#ATTRIBUTES.id#&#ATTRIBUTES.fwx#" name="#ATTRIBUTES.id#" <cfif ATTRIBUTES.canWrite>title="#ATTRIBUTES.title_edit#" class="edit"<cfelse>title="#ATTRIBUTES.title_view#" class="view"</cfif>></a></cfoutput><cfexit method="exitTag"/>
+6
View File
@@ -0,0 +1,6 @@
<cfsilent>
<cfparam name="ATTRIBUTES.entity"/>
<cfparam name="ATTRIBUTES.key" default="#ATTRIBUTES.entity#_id"/>
<cfparam name="ATTRIBUTES.id"/>
<cfparam name="ATTRIBUTES.fwx"/>
</cfsilent><cfoutput><a href="#ATTRIBUTES.entity#.cfm?#ATTRIBUTES.key#=#ATTRIBUTES.id#&#ATTRIBUTES.fwx#" title="просмотреть" name="#ATTRIBUTES.id#" class="view"></a></cfoutput><cfexit method="exitTag"/>
+9
View File
@@ -0,0 +1,9 @@
<cfsilent>
<cfparam name="ATTRIBUTES.canWrite" type="boolean" default="Yes"/>
<cfparam name="ATTRIBUTES.entity"/>
<cfparam name="ATTRIBUTES.key" default="#ATTRIBUTES.entity#_id"/>
<cfparam name="ATTRIBUTES.id"/>
<cfparam name="ATTRIBUTES.fwx"/>
<cfparam name="ATTRIBUTES.title_edit" default="редактировать"/>
<cfparam name="ATTRIBUTES.title_view" default="просмотреть"/>
</cfsilent><cfoutput><a href="#ATTRIBUTES.entity#.cfm?#ATTRIBUTES.key#=#ATTRIBUTES.id#&#ATTRIBUTES.fwx#" name="#ATTRIBUTES.id#" <cfif ATTRIBUTES.canWrite>title="#ATTRIBUTES.title_edit#" class="edit"<cfelse>title="#ATTRIBUTES.title_view#" class="view"</cfif>></a></cfoutput><cfexit method="exitTag"/>
+25
View File
@@ -0,0 +1,25 @@
<cfprocessingdirective suppressWhitespace="YES"><cfsilent>
<cfparam name="ATTRIBUTES.page" type="string"/>
<cfparam name="ATTRIBUTES.queryString" type="string" default=""/>
<cfparam name="ATTRIBUTES.acl" type="string" default=""/>
<cfparam name="ATTRIBUTES.label" type="string" default=""/>
<cfif structKeyExists(#ATTRIBUTES#,"external")>
<cfset class="menu-item-ext"/>
<cfset target=' target="_blank"'/>
<cfelse>
<cfset class="menu-item"/>
<cfset target=''/>
</cfif>
</cfsilent><!---
---><cfmodule template="../ac.cfm" obj="#ATTRIBUTES.acl#"><cfif NOT (request.thisPage EQ ATTRIBUTES.page)><cfsilent>
<cfif len(ATTRIBUTES.queryString)>
<cfset pageUrl="#ATTRIBUTES.page#?#ATTRIBUTES.queryString#"/>
<cfelse>
<cfset pageUrl="#ATTRIBUTES.page#"/>
</cfif>
</cfsilent><cfoutput><li class="#class#"><a href="#pageUrl#"#target#>#ATTRIBUTES.label#</a></li></cfoutput>
<cfelse><cfoutput><li class="selected">#ATTRIBUTES.label#</li></cfoutput></cfif><!---
---></cfmodule></cfprocessingdirective><cfexit method="EXITTAG"/>
+6
View File
@@ -0,0 +1,6 @@
<cfsilent>
<cfparam name="ATTRIBUTES.targetid"/>
<cfparam name="ATTRIBUTES.enabled" default="Yes"/>
<cfparam name="ATTRIBUTES.suffix" default=""/>
<cfparam name="ATTRIBUTES.title" default="Сейчас"/>
</cfsilent><cfoutput><button onclick="document.getElementById(#ATTRIBUTES.targetid#).value=""></</cfoutput><cfexit method="exittag"/>
+36
View File
@@ -0,0 +1,36 @@
<cfsilent>
<cfparam name="ATTRIBUTES.n" type="numeric"/>
<cfset attributeList="n,sortArray"/>
<cfset img_up="arr_up.png"/>
<cfset img_dn="arr_dn.png"/>
<cfset HIGHLIGHTED_CNT=2/>
<cfif isDefined("ATTRIBUTES.sortArray")>
<cfset i=1>
<cfloop condition="i LE HIGHLIGHTED_CNT AND i LE arrayLen(ATTRIBUTES.sortArray)">
<cftry>
<cfif ATTRIBUTES.sortArray[i].fld EQ ATTRIBUTES.n>
<cfif ATTRIBUTES.sortArray[i].asc>
<cfset img_up="arr_up#i#.png">
<cfelse>
<cfset img_dn="arr_dn#i#.png">
</cfif>
</cfif>
<cfcatch type="Any"></cfcatch>
</cftry>
<cfset i=i+1>
</cfloop>
</cfif>
<cfset extra_query_string=""/>
<cfloop collection=#ATTRIBUTES# item="attr">
<cfif NOT listFindNoCase(attributeList,attr)>
<cfset val="#structFind(ATTRIBUTES,attr)#"/>
<cfif IsSimpleValue(val)>
<cfset extra_query_string="#extra_query_string#&#attr#=#val#"/>
</cfif>
</cfif>
</cfloop>
</cfsilent><cfoutput><a href="?sort=#ATTRIBUTES.n#a#extra_query_string#" class="noprint" style="padding:2px;" title="по возрастанию"><img src="img/#img_up#" alt="по возрастанию"></a><a href="?sort=#ATTRIBUTES.n#d#extra_query_string#" title="по убыванию"><img src="img/#img_dn#" alt="по убыванию"></a></cfoutput><cfexit method="exittag"/>
+80
View File
@@ -0,0 +1,80 @@
<cfparam name="nStart" type="integer" default="1"/>
<cfparam name="ATTRIBUTES.recordCount" type="integer"/>
<cfparam name="ATTRIBUTES.recordsPerPage" type="integer"/>
<cfparam name="ATTRIBUTES.thisPage" type="string" default=""/>
<cfparam name="ATTRIBUTES.addtionalUrlParams" type="string" default=""/>
<cfparam name="ATTRIBUTES.self" type="string" default=""/>
<!---<cfparam name="ATTRIBUTES.fwx" type="string" default=""/>--->
<cfparam name="ATTRIBUTES.output" type="string" default="paginator"/>
<!--- Исключение: рассчитанный индекс страницы превышает количество существующих страниц - надо возвращаться на первую --->
<cfset nPages = Int((ATTRIBUTES.recordCount-1)/ATTRIBUTES.recordsPerPage)+1/>
<cfset nCurrentPage = Int((nStart-1)/ATTRIBUTES.recordsPerPage)+1/>
<cfif nStart GT ATTRIBUTES.recordCount>
<cfset nStart=1/>
</cfif>
<cfset UrlSuffix=""/>
<cfif len(ATTRIBUTES.addtionalUrlParams) GT 0>
<cfset UrlSuffix="&#ATTRIBUTES.addtionalUrlParams#"/>
</cfif>
<cfif len(ATTRIBUTES.self) GT 0>
<cfset UrlSuffix="&track=#ATTRIBUTES.self#"/>
</cfif>
<cfset somePages=3/>
<cfsavecontent variable="pages">
<cfif ATTRIBUTES.recordCount GT ATTRIBUTES.recordsPerPage>
<cfset doMerge = false/>
<cfloop index="i" from="1" to="#nPages#">
<cfset nPageStartRecordNum=(i-1)*ATTRIBUTES.recordsPerPage+1>
<!---
схема, которая обеспечивает дихотомический поиск
первые несколько страниц (не менее 2)
если есть разрыв - многоточие
посередине
если есть разрыв - многоточие
несколько страниц до текушей
текущую без ссылки
несколько страниц после текущей
если есть разрыв - многоточие
посередине
если есть разрыв - многоточие
последние несколько страниц
--->
<!---Можно сделать на многоточии ссылку на середину интервала!--->
<!---Хочется добиться, чтобы при хождении вперед-назад значения повторялись--->
<!---забавный эффект, когда остается разрыв в 1 страницу, а там все равно многоточие--->
<cfoutput>
<cfif i NEQ nCurrentPage>
<cfif i GT somePages AND (nCurrentPage-i) GT somePages>
<cfif NOT doMerge><!---*** неуклюже--->
<cfset nMidPage = ceiling(nCurrentPage/2)/>
<cfset nMidStartRecord = (nMidPage-1)*ATTRIBUTES.recordsPerPage+1/>
<a href="#ATTRIBUTES.thisPage#?nStart=#nMidStartRecord##UrlSuffix#" title="#nMidPage#">...</a>&nbsp;<cfset doMerge=true/>
</cfif>
<cfelseif (i-nCurrentPage) GT somePages AND (nPages-i) GT somePages>
<cfif NOT doMerge>
<cfset nMidPage = ceiling((nCurrentPage+nPages)/2)/>
<cfset nMidStartRecord = (nMidPage-1)*ATTRIBUTES.recordsPerPage+1/>
<a href="#ATTRIBUTES.thisPage#?nStart=#nMidStartRecord##UrlSuffix#" title="#nMidPage#">...</a>&nbsp;<cfset doMerge=true/>
</cfif>
<cfelse>
<a href="#ATTRIBUTES.thisPage#?nStart=#nPageStartRecordNum##UrlSuffix#">#i#</a>&nbsp;
<cfset doMerge=false/>
</cfif>
<cfelse>
<b>#i#</b>&nbsp;
</cfif>
</cfoutput>
</cfloop>
</cfif>
</cfsavecontent>
<cfset "CALLER.#ATTRIBUTES.output#.links"=#pages#/>
<cfset "CALLER.#ATTRIBUTES.output#.recordsPerPage"=#ATTRIBUTES.recordsPerPage#/>
<cfexit method="exittag"/>
+154
View File
@@ -0,0 +1,154 @@
<cfimport prefix="c" taglib="."/>
<cfif thisTag.executionMode IS "end">
<!--- <cfloop collection=#CALLER# item="item">
<cfset structInsert(variables, item, CALLER[item], false)/>
</cfloop> --->
<cfparam name="ATTRIBUTES.query" type="query"/>
<cfparam name="ATTRIBUTES.recordsPerPage" type="integer" default="500"/>
<cfparam name="ATTRIBUTES.nStart" type="integer" default="1"/>
<cfparam name="ATTRIBUTES.titleMap" type="struct" default=srtuctNew()/><!---for definition see: field_set.cfm--->
<cfparam name="ATTRIBUTES.sortArray" type="array" default=arrayNew(1)/>
<cfset tableAttributeList="query,recordsPerPage,nStart,titleMap,sortArray"/>
<cfset colAttributeList="lang,th,td,content,field,formatter,sortable,visible,columnOrder"/>
<cfset tdAttributeList="content,field"/>
<cfparam name="thisTag.columns" type="array"/>
<cffunction name=reorderColumns output="No">
<!--- Вариант сортировки. Вынимаем все элементы с указанным порядком в отдельную коллекцию,
после чего вставляем их в оставшуюся коллекцию на указанные позиции.
нет смысла делать вид, что мы реализуем что-то универсальное
(поле для сортировки в совершенно конкретном поле структуры в массиве),
поэтому ничего не передаем в аргументах, спокойно ссылаемся на окружение--->
<cfset var tmpOrderedIndexes=ArrayNew(1)/>
<cfset var tmpUnorderedIndexes=ArrayNew(1)/>
<cfloop from=1 to=#arrayLen(thisTag.columns)# index="i">
<cfif thisTag.columns[i].columnOrder GT 0>
<cfset arrayAppend(tmpOrderedIndexes,i)/>
<cfelse>
<cfset arrayAppend(tmpUnorderedIndexes,i)/>
</cfif>
</cfloop>
<cfloop from=#arrayLen(tmpOrderedIndexes)# to=1 step=-1 index="i">
<!--- counting up-down preserves entry order for equal columnOrders --->
<cfset var pos=max(min(thisTag.columns[tmpOrderedIndexes[i]].columnOrder, len(tmpUnorderedIndexes)+1),1)/>
<cfset arrayInsertAt(tmpUnorderedIndexes,pos,tmpOrderedIndexes[i])/>
</cfloop>
<cfset var sortedColumns=ArrayNew(1)/>
<cfloop from=1 to=#arrayLen(tmpUnorderedIndexes)# index="i">
<cfset sortedColumns[i]=thisTag.columns[tmpUnorderedIndexes[i]]/>
</cfloop>
<cfreturn sortedColumns/>
</cffunction>
<cfset sortedColumns=reorderColumns()/>
<cfset thisTag.generatedContent=""/>
<table<!--- passthrough additional attributes
---><cfoutput><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(tableAttributeList,attr)<!--- AND isSimpleValue(structFind(ATTRIBUTES,attr))--->> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop></cfoutput>>
<thead>
<tr>
<cfloop array=#sortedColumns# index="column">
<cfset th=column.th[1]/>
<th<!--- атрибуты колонки передаются в TH, хотя это выглядит не очень нужным --->
<cfloop collection=#column# item="colAttr">
<cfif NOT listFindNoCase(colAttributeList,colAttr)><cfoutput>#colAttr#="#structFind(column,colAttr)#" </cfoutput></cfif>
</cfloop>>
<cfif len(column.field) AND column.sortable>
<c:order_arrows sortArray=#ATTRIBUTES.sortArray# n=#ATTRIBUTES.titleMap[column.field].ordinal#<!--- attributeCollection=#extraAttributes#--->/>
</cfif>
<cfif len(th.content)>
<cfset Evaluate("WriteOutput('#th.content#')")/>
<cfelseif len(column.field)>
<cfif structKeyExists(ATTRIBUTES.titleMap[column.field],"title")>
<cfoutput>#ATTRIBUTES.titleMap[column.field].title#</cfoutput>
</cfif>
</cfif>
</th>
</cfloop>
</tr>
</thead>
<tbody>
<cfoutput query=#ATTRIBUTES.query# maxrows=#ATTRIBUTES.recordsPerPage# startrow=#ATTRIBUTES.nStart#>
<tr>
<cfloop array=#sortedColumns# index="column">
<cfset td=column.td[1]/>
<td<!--- Если нужно передать атрибут в TD, можно ввести тег <C:TD class="r"/> только как плейсхолдер для атрибутов, а поле будет получено от колонки --->
<cfloop collection=#td# item="tdAttr">
<cfif NOT listFindNoCase(tdAttributeList,tdAttr)>#tdAttr#="#structFind(td,tdAttr)#" </cfif>
</cfloop>
><cfif len(td.content)><cfset Evaluate("WriteOutput('#td.content#')")/><!---#td.content#--->
<cfelseif len(td.field)>#ATTRIBUTES.query[td.field][currentRow]#
<cfelseif len(column.field)>#column.formatter(ATTRIBUTES.query[column.field][currentRow])#
</cfif></td>
</cfloop>
</tr>
</cfoutput>
</tbody>
</table>
<!--- <cfdump var=#variables#/> --->
</cfif>
<!--- <cfexit method="exitTag"/> --->
<cfscript>
/**
* Sorts an array of structures based on a key in the structures.
*
* @param aofS Array of structures.
* @param key Key to sort by.
* @param sortOrder Order to sort by, asc or desc.
* @param sortType Text, textnocase, or numeric.
* @param delim Delimiter used for temporary data storage. Must not exist in data. Defaults to a period.
* @return Returns a sorted array.
* @author Nathan Dintenfass (nathan@changemedia.com)
* @version 1, December 10, 2001
*/
function arrayOfStructsSort(aOfS,key){
//by default we'll use an ascending sort
var sortOrder = "asc";
//by default, we'll use a textnocase sort
var sortType = "textnocase";
//by default, use ascii character 30 as the delim
var delim = ".";
//make an array to hold the sort stuff
var sortArray = arraynew(1);
//make an array to return
var returnArray = arraynew(1);
//grab the number of elements in the array (used in the loops)
var count = arrayLen(aOfS);
//make a variable to use in the loop
var ii = 1;
//if there is a 3rd argument, set the sortOrder
if(arraylen(arguments) GT 2)
sortOrder = arguments[3];
//if there is a 4th argument, set the sortType
if(arraylen(arguments) GT 3)
sortType = arguments[4];
//if there is a 5th argument, set the delim
if(arraylen(arguments) GT 4)
delim = arguments[5];
//loop over the array of structs, building the sortArray
for(ii = 1; ii lte count; ii = ii + 1)
sortArray[ii] = aOfS[ii][key] & delim & ii;
//now sort the array
arraySort(sortArray,sortType,sortOrder);
//now build the return array
for(ii = 1; ii lte count; ii = ii + 1)
returnArray[ii] = aOfS[listLast(sortArray[ii],delim)];
//return the array
return returnArray;
}
</cfscript>
+15
View File
@@ -0,0 +1,15 @@
<cfif thisTag.executionMode IS "end">
<!--- <cfloop collection=#CALLER# item="item">
<cfset structInsert(variables, item, CALLER[item], false)/>
</cfloop> --->
<cfassociate basetag="cf_column" datacollection="td"/>
<cfset attributeList="field"/>
<cfparam name="ATTRIBUTES.field" default=""/>
<cfset ATTRIBUTES.content=thisTag.generatedContent/>
</cfif>
<!---<cfparam name="ATTRIBUTES.lang" type="string" default=""/>
<cfparam name="request.language" type="string" default=""/>
<cfif len(ATTRIBUTES.lang) AND #ATTRIBUTES.lang# NEQ #request.language#>
<cfexit method="exittag"/>
</cfif>--->
+20
View File
@@ -0,0 +1,20 @@
<cfsilent>
<cfparam name="ATTRIBUTES.name"/>
<cfif structKeyExists(ATTRIBUTES,"value")>
<cfset value=#ATTRIBUTES.value#/>
<cfelse>
<cfset value=#ATTRIBUTES.container[ATTRIBUTES.name]#/>
</cfif>
<cfparam name="ATTRIBUTES.suffix" default=""/>
<cfparam name="ATTRIBUTES.id" default="#ATTRIBUTES.name##ATTRIBUTES.suffix#"/>
<cfparam name="ATTRIBUTES.size" default=""/>
<cfparam name="ATTRIBUTES.disabled" type="boolean" default="No"/>
<cfset attributeList="name,value,container,suffix,id,size,disabled"/>
</cfsilent><cfoutput><input type="text" name="#ATTRIBUTES.name#"<cfif len(ATTRIBUTES.id)> id=#ATTRIBUTES.id#</cfif> value="#value#"<cfif len(ATTRIBUTES.size)> size="#ATTRIBUTES.size#"</cfif><cfif ATTRIBUTES.disabled> disabled="disabled"</cfif><!---
passthrough additional attributes
---><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop>/></cfoutput><cfexit method="exittag"/>
+6
View File
@@ -0,0 +1,6 @@
<cfif thisTag.executionMode IS "end">
<cfassociate basetag="cf_column" datacollection="th"/>
<cfset attributeList="field"/>
<cfparam name="ATTRIBUTES.field" default=""/>
<cfset ATTRIBUTES.content=thisTag.generatedContent/>
</cfif>
+21
View File
@@ -0,0 +1,21 @@
<cfsilent>
<cfparam name="ATTRIBUTES.name"/>
<cfif structKeyExists(ATTRIBUTES,"value")>
<cfset value=#ATTRIBUTES.value#/>
<cfelse>
<cfset value=#ATTRIBUTES.container[ATTRIBUTES.name]#/>
</cfif>
<cfparam name="ATTRIBUTES.suffix" default=""/>
<cfparam name="ATTRIBUTES.id" default="#ATTRIBUTES.name##ATTRIBUTES.suffix#"/>
<cfparam name="ATTRIBUTES.format" default="HH:MM"/>
<cfparam name="ATTRIBUTES.size" default="#len(ATTRIBUTES.format)#"/>
<cfparam name="ATTRIBUTES.disabled" type="boolean" default="No"/>
<cfset attributeList="name,value,container,suffix,id,format,size,disabled"/>
</cfsilent><cfoutput><input type="text" name="#ATTRIBUTES.name#"<cfif len(ATTRIBUTES.id)> id=#ATTRIBUTES.id#</cfif> value="#timeFormat(value, ATTRIBUTES.format)#" size="#ATTRIBUTES.size#"<cfif ATTRIBUTES.disabled> disabled="disabled"</cfif><!---
passthrough additional attributes
---><cfloop collection=#ATTRIBUTES# item="attr"><!---
---><cfif NOT listFindNoCase(attributeList,attr)> #attr#="#structFind(ATTRIBUTES,attr)#"</cfif><!---
---></cfloop>/></cfoutput><cfexit method="exittag"/>
+401
View File
@@ -0,0 +1,401 @@
<!---
bean v0.96
msyu@mail.ru
2013-08-29 v0.1
2013-09-04 v0.2 tested with CF8 and Railo
2013-10-14 added meta attribute - can now export each parameter metadata
2014-12-26 POST-GET read-pass-save
2015-01-19 read-pass-save, добавлен formmarker, убрано определение режима по POST-GET
2015-01-19 убран formmarker, упразднен режим init (используется pass)
2015-07-16 добавлен passmarker для перерисовки формы с введенными значениями
2015-10-02 поддержка составных ключей
2015-10-09 v0.9 если задано value параметра, считается, что он hasInput (корректно работает в составе ключа)
2015-11-25 добавлен readmarker, mode (принудительная установка режима)
2015-11-26 добавлен mode=skip
2016-09-01 изменена трактовка processingMode. Теперь понимается как исходная команда, фиксируется до начала действий. Можно использовать для управления
2018-09-16 добавлена ограниченная поддержка нецелых первичных ключей (idstamp)
child tag: param
to save - should send parameter with name from list ATTRIBUTES.savemarker (value doesn't matter) in FORM, e.g. URL.save="trtrtr", while ATTRIBUTES.savemarker="save,saveAndClose"; for multiple forms on a page (and bean tags) different savemarkers should be used
2022-01-06 PostgreSQL (MSSQL incompatibility because of scope_identity)
2024-04-13 PostgreSQL GUID, autoincrement by RETURNING
2024-09-05 added status.recordExists (*** при вставке принудительно устанавливаем в true, веря, что если insert прошел, то запись появилась)
--->
<!---
Автогенерируемое поле GUID можно заполнять несколькими способами
- как default или init bean/param, но это не очень удобно, потому что может потеряться удобный признак новой записи - инвалидный ключ, и сейчас init-default взаимодействуют некорректно, по крайней мере, неочевидно
- генерируемое в БД (например, как default). Для PostgreSQL значение возвращается через Returning, как это делать для других БД, непонятно.
- можно генерировать при сохранении в bean, но для этого нужно расширение синтаксиса, зато не зависит от БД (*** TODO)
--->
<cfif thisTag.ExecutionMode is 'end'>
<cfparam name="ATTRIBUTES.readmarker" type="string" default="read"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда перечитывания. Имеет приоритет перед savemarker, passmarker. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.savemarker" type="string" default="save,saveAndClose"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда сохранения. Обычно это имя кнопки. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.passmarker" type="string" default="pass"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда заполнить форму отправленными данными без перечитывания. В форме такое поле обычно есть. Команда сохранения имеет приоритет перед пробросом. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.datasource" type="string"/>
<cfparam name="ATTRIBUTES.table" type="string"/>
<cfparam name="ATTRIBUTES.output" type="string"/><!--- имя переменной (структуры) области CALLER, в которую возвращаются данные. Обычно "d" --->
<cfparam name="ATTRIBUTES.info" type="string" default=""/>
<cfparam name="ATTRIBUTES.meta" type="string" default=""/>
<cfparam name="ATTRIBUTES.status" type="string"/><!--- имя переменной (структуры) области CALLER, в которую возвращается статуc. Обычно "status" --->
<cfparam name="ATTRIBUTES.readonly" type="boolean" default="No"/>
<cfparam name="ATTRIBUTES.mode" type="string" default=""/> <!--- Принудительный режим read|pass|save|skip. Имеет приоритет перед маркерами --->
<cfif ATTRIBUTES.mode EQ "skip">
<!---<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorState", false) />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorMessage", "") />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.processingMode", "skip") />--->
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(false,"","skip",false))/><!--- *** можно было не создавать компонент, он все равно не имеет логики, это map из нескольких полей. С другой стороны, хоть поля декларированы. Не очень удобно, что в отдельном файле --->
<cfexit method="exittag"/>
</cfif>
<cfset validationOk="true" />
<cfset errorState="false" />
<cfset errorMessage="" />
<cfset warningState="false" />
<cfset warningMessage="" />
<!---<cfset keyField=""/>
<cfset keyValue=""/>--->
<cfset hasAutoIncrement="false"/>
<cfset autoIncrementKeyIndex=0/><!--- сгенерированное значение присваивается первому полю, отмеченному как autoincrement --->
<cfset recordExists = "false"/>
<cfset keyInvalid = "false"/>
<!--- разбор метаданных - поиск ключа --->
<!--- поддерживаются только простые целочисленные ключи --->
<cfset keys=arrayNew(1)/>
<!--- *** почему где-то копируем поля param в key, а где-то прямо цикл по параметрам --->
<!--- коллекция thistag.params формируется вложенными тегами param --->
<cfloop array=#thistag.params# index="param">
<!---<cfdump var=#param#/>--->
<cfif structFind(param,"key")><!--- not just structKeyExists! Not exisis, OR exists, but FALSE! --->
<cfset key = structNew()/>
<cfset ArrayAppend(keys, key)/>
<cfset key.name = param.param />
<cfset key.field = param.field />
<cfset key.type = param.type />
<cfset key.value = param.value /><!--- должно уже быть присвоено --->
<cfset key.null = param.null />
<cfif param.errorState OR !param.hasInput>
<cfset keyInvalid="true"/>
<cfelse>
<cfset keyInvalid=!checkDataFormat(param.type, param.value)/>
</cfif>
<cfif !hasAutoIncrement><!--- take only first field with "autoincrement" attribute--->
<cfif structFind(param, "autoincrement")>
<cfset hasAutoIncrement = true/>
<cfset autoIncrementKeyIndex = arrayLen(keys)/>
</cfif>
</cfif>
</cfif>
</cfloop>
<!---<cfdump var=#keys#/>--->
<cfif !keyInvalid>
<!--- *** дублируется похожий cfqueryparam, перепутал один раз --->
<cfquery name="qCheckExistence" datasource="#ATTRIBUTES.datasource#">
select count(*) as cnt
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfset recordExists = (qCheckExistence.cnt GT 0)/>
<!--- <cfdump var=#qCheckExistence#/> --->
<cfelse>
<cfset recordExists = "false"/>
</cfif>
<cfif listFindNoCase("read,pass,save", ATTRIBUTES.mode)>
<cfset processingMode=ATTRIBUTES.mode/>
<cfelse>
<!--- ищем команду принудительного перечитывания --->
<cfset doRead = false/>
<cfloop list=#ATTRIBUTES.readmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doRead = true/>
<cfbreak/>
</cfif>
</cfloop>
<!--- ищем команду сохранения --->
<cfset doSave = false/>
<cfif !doRead AND !ATTRIBUTES.readonly>
<cfloop list=#ATTRIBUTES.savemarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doSave = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- ищем команду проброса --->
<cfset doPass = false/>
<cfif !doRead AND !doSave>
<cfloop list=#ATTRIBUTES.passmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doPass = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- определяем режим --->
<cfif doRead>
<cfset processingMode="read"/>
<cfelseif doSave>
<cfset processingMode="save"/>
<cfelse>
<cfif doPass OR !recordExists>
<cfset processingMode="pass"/>
<cfelse>
<cfset processingMode="read"/>
</cfif>
</cfif>
</cfif>
<cfset initialProcessingMode = processingMode/>
<!---debug <cfoutput>processingMode:#processingMode#</cfoutput>--->
<!--- ---------------------------------------------------------- --->
<!---*** Необходимость вставки (против апдейта) определяется по существованию записи. Это небезопасно, поскольку наличие записи с ключом -1 может прекратить создание новых записей. Конечно, можно добавить констрейнт на ключевое поле, но это лишняя зависимость.
Можно явно передавать команду вставки, а не заморачиваться с анализом ключа. Просто традиционно мы сигнализировали необходимость вставки, передавая невалидное значение ключа, обычно -1. Для целочисленных ключей можно было бы просто проверять положительность (что всю жизнь отлично работало), но хочется более общего.
--->
<cfif processingMode IS "save"> <!--- validation lookup --->
<cfloop array=#thistag.params# index="param">
<cfif !param.key>
<cfif param.warningState>
<cfif NOT warningState><!--- catch the first fault --->
<cfset warningMessage=param.warningMessage />
</cfif>
<cfset warningState="true" />
</cfif>
<cfif param.errorState>
<cfif NOT errorState><!--- catch the first fault --->
<cfset errorMessage=param.errorMessage />
</cfif>
<cfset errorState="true" />
<cfset validationOk="false"/>
</cfif>
</cfif>
<cfif errorState>
<!--- clear warning state --->
<cfset warningMessage="" />
<cfset warningState=false />
<!--- finish lookup --->
<cfbreak/>
</cfif>
</cfloop>
<cfif validationOk>
<!---<cfdump var=#param#/> --->
<cftry>
<cfif recordExists><!--- update. Наличие keyValue гарантировано (уверен) --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#" result="qSaveResult">
update #ATTRIBUTES.table# set
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<!--- не обновляем ключевые поля --->
<cfif NOT (StructFind(param, "key")
OR StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipUpdate")
)><cfif i++ GT 0>,</cfif>
#param.field#=<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#"/>
</cfloop>
</cfquery>
<!---<cfdump var=#qSaveResult#/>--->
<cfelse><!--- insert --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#">
insert into #ATTRIBUTES.table#
(
<cfset i=0 />
<!--- ключевые поля без автоинкремента попадают в insert! --->
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
#param.field#
</cfif>
</cfloop>
)
values
(
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
)
<!--- /*MSSQL syntax*/
<cfif hasAutoIncrement>
select scope_identity() as id;
</cfif>
--->
<!---*** PostgreSQL incompatible hack follows--->
<cfif hasAutoIncrement>
returning #thistag.params[autoIncrementKeyIndex].field# as id;
</cfif>;
</cfquery>
<!--- <cfdump var=#qSave#/> --->
<cfif hasAutoIncrement>
<cfset keys[autoIncrementKeyIndex].value=qSave.id/>
</cfif>
<!--- здесь можно установить recordExists=true, если твердо верить, что вставка прошла, если нет исключения --->
<cfset recordExists=true/>
</cfif>
<!--- recordExists --->
<cfset processingMode="read"/>
<cfcatch type="database">
<cfset errorState="true" />
<cfset errorMessage="Ошибка при записи в базу данных. #cfcatch.message# #cfcatch.detail#" />
<cfset processingMode="pass" />
</cfcatch>
</cftry>
<cfelse><!--- (not) validationOk --->
<cfset processingMode="pass"/>
</cfif><!--- validationOk --->
</cfif><!--- processingMode EQ "save" --->
<!--- экспортируем данные --->
<cfswitch expression=#processingMode#>
<cfcase value="read">
<cfquery name="qRead" datasource="#ATTRIBUTES.datasource#">
select
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfset i=i+1/>
#param.field#<cfif i LT ArrayLen(thistag.params)>,</cfif>
</cfloop>
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
/*#sqlType(key.type)#*/
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfloop array=#thistag.params# index="param"><!--- *** --->
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", structFind(qRead, #param.field#)) />
</cfloop>
</cfcase>
<cfcase value="pass"><!--- заполнить все поля. Если значения переданы в форме или урле, тег параметра обязан их разобрать и подставить, в противном случае подставить инит-значения. Инит-значение по умолчанию пустая строка, дефолт по умолчанию тоже пустая строка --->
<cfloop array=#thistag.params# index="param">
<!--- <cfdump var=#param#/>--->
<cfif param.hasInput>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.submittedValue) /><!---*** дефект: 03.12.2015, передаваемая строкой, при обработке dateFormat неправильно парсится --->
<cfelse>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.init) />
</cfif>
</cfloop>
</cfcase>
<cfdefaultcase>
</cfdefaultcase>
</cfswitch>
<cfif len(ATTRIBUTES.info)><!--- экспортируем дополнительные сведения--->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.submittedValue", #param.submittedValue#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorState", #param.errorState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorMessage", #param.errorMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningState", #param.warningState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningMessage", #param.warningMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.null", #param.null#) />
</cfloop>
</cfif>
<cfif len(ATTRIBUTES.meta)><!--- экспортируем метаданные параметра - для инвариантности вызовов --->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.param", #param.param#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.field", #param.field#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.type", #param.type#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.displayName", #param.displayName#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.default", #param.default#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.size", #param.size#) />
</cfloop>
</cfif>
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(errorState,errorMessage,initialProcessingMode,recordExists))/>
</cfif><!--- thisTag.ExecutionMode is 'end'--->
<!--- quick and dirty --->
<cffunction name="sqlType">
<cfargument name="type"/>
<cfswitch expression=#type#>
<cfcase value="guid,uuid,idstamp"><cfreturn "CF_SQL_OTHER"/></cfcase><!--- hack for PostgreSQL uuid --->
<cfdefaultcase><cfreturn uCase("CF_SQL_#type#")/></cfdefaultcase>
</cfswitch>
</cffunction>
<cffunction name="checkDataFormat">
<cfargument name="type"/>
<cfargument name="value"/>
<cfswitch expression=#type#>
<cfcase value="integer"><cfreturn isValid("integer",value)/></cfcase>
<cfcase value="guid,uuid,idstamp"><cfreturn isValid("guid",value)/></cfcase>
<cfdefaultcase><cfreturn true/></cfdefaultcase>
</cfswitch>
</cffunction>
<!--- //quick and dirty
function sqlType(type) {
switch (type) {
case "guid,idstamp": return "CF_SQL_OTHER"; /*hack for PostgreSQL uuid*/ /*break not needed!*/
default: return uCase("CF_SQL_#type#");
}
}
function checkDataFormat(type,value) {
switch (type) {
case "integer": return isValid("integer",value); /*break not needed!*/
case "guid,uuid,idstamp": return isValid("guid",value); /*break not needed!*/ /*INCORRECT cfscript switch-case does not support lists*/
default: return true;
}
} --->
<cfscript>
//readonly может транслироваться в pass!
function translateMode(readonly) {
if (readonly) {
return "read";
} else {
return "";
}
}
</cfscript>
+400
View File
@@ -0,0 +1,400 @@
<!---
bean v0.95
msyu@mail.ru
2013-08-29 v0.1
2013-09-04 v0.2 tested with CF8 and Railo
2013-10-14 added meta attribute - can now export each parameter metadata
2014-12-26 POST-GET read-pass-save
2015-01-19 read-pass-save, добавлен formmarker, убрано определение режима по POST-GET
2015-01-19 убран formmarker, упразднен режим init (используется pass)
2015-07-16 добавлен passmarker для перерисовки формы с введенными значениями
2015-10-02 поддержка составных ключей
2015-10-09 v0.9 если задано value параметра, считается, что он hasInput (корректно работает в составе ключа)
2015-11-25 добавлен readmarker, mode (принудительная установка режима)
2015-11-26 добавлен mode=skip
2016-09-01 изменена трактовка processingMode. Теперь понимается как исходная команда, фиксируется до начала действий. Можно использовать для управления
2018-09-16 добавлена ограниченная поддержка нецелых первичных ключей (idstamp)
child tag: param
to save - should send parameter with name from list ATTRIBUTES.savemarker (value doesn't matter) in FORM, e.g. URL.save="trtrtr", while ATTRIBUTES.savemarker="save,saveAndClose"; for multiple forms on a page (and bean tags) different savemarkers should be used
2022-01-06 PostgreSQL (MSSQL incompatibility because of scope_identity)
2024-04-13 PostgreSQL GUID, autoincrement by RETURNING
--->
<!---
Автогенерируемое поле GUID можно заполнять несколькими способами
- как default или init bean/param, но это не очень удобно, потому что может потеряться удобный признак новой записи - инвалидный ключ, и сейчас init-default взаимодействуют некорректно, по крайней мере, неочевидно
- генерируемое в БД (например, как default). Для PostgreSQL значение возвращается через Returning, как это делать для других БД, непонятно.
- можно генерировать при сохранении в bean, но для этого нужно расширение синтаксиса, зато не зависит от БД (*** TODO)
--->
<cfif thisTag.ExecutionMode is 'end'>
<cfparam name="ATTRIBUTES.readmarker" type="string" default="read"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда перечитывания. Имеет приоритет перед savemarker, passmarker. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.savemarker" type="string" default="save,saveAndClose"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда сохранения. Обычно это имя кнопки. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.passmarker" type="string" default="pass"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда заполнить форму отправленными данными без перечитывания. В форме такое поле обычно есть. Команда сохранения имеет приоритет перед пробросом. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.datasource" type="string"/>
<cfparam name="ATTRIBUTES.table" type="string"/>
<cfparam name="ATTRIBUTES.output" type="string"/>
<cfparam name="ATTRIBUTES.info" type="string" default=""/>
<cfparam name="ATTRIBUTES.meta" type="string" default=""/>
<cfparam name="ATTRIBUTES.status" type="string"/>
<cfparam name="ATTRIBUTES.readonly" type="boolean" default="No"/>
<cfparam name="ATTRIBUTES.mode" type="string" default=""/> <!--- Принудительный режим read|pass|save|skip. Имеет приоритет перед маркерами --->
<cfif ATTRIBUTES.mode EQ "skip">
<!---<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorState", false) />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorMessage", "") />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.processingMode", "skip") />--->
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(false,"","skip"))/>
<cfexit method="exittag"/>
</cfif>
<cfset validationOk="true" />
<cfset errorState="false" />
<cfset errorMessage="" />
<cfset warningState="false" />
<cfset warningMessage="" />
<!---<cfset keyField=""/>
<cfset keyValue=""/>--->
<cfset hasAutoIncrement="false"/>
<cfset autoIncrementKeyIndex=0/><!--- сгенерированное значение присваивается первому полю, отмеченному как autoincrement --->
<cfset recordExists = "false"/>
<cfset keyInvalid = "false"/>
<!--- разбор метаданных - поиск ключа --->
<!--- поддерживаются только простые целочисленные ключи --->
<cfset keys=arrayNew(1)/>
<!--- *** почему где-то копируем поля param в key, а где-то прямо цикл по параметрам --->
<!--- коллекция thistag.params формируется вложенными тегами param --->
<cfloop array=#thistag.params# index="param">
<!---<cfdump var=#param#/>--->
<cfif structFind(param,"key")><!--- not just structKeyExists! Not exisis, OR exists, but FALSE! --->
<cfset key = structNew()/>
<cfset ArrayAppend(keys, key)/>
<cfset key.name = param.param />
<cfset key.field = param.field />
<cfset key.type = param.type />
<cfset key.value = param.value /><!--- должно уже быть присвоено --->
<cfset key.null = param.null />
<cfif param.errorState OR !param.hasInput>
<cfset keyInvalid="true"/>
<cfelse>
<cfset keyInvalid=!checkDataFormat(param.type, param.value)/>
</cfif>
<cfif !hasAutoIncrement><!--- take only first field with "autoincrement" attribute--->
<cfif structFind(param, "autoincrement")>
<cfset hasAutoIncrement = true/>
<cfset autoIncrementKeyIndex = arrayLen(keys)/>
</cfif>
</cfif>
</cfif>
</cfloop>
<!---<cfdump var=#keys#/>--->
<cfif !keyInvalid>
<!--- *** дублируется похожий cfqueryparam, перепутал один раз --->
<cfquery name="qCheckExistence" datasource="#ATTRIBUTES.datasource#">
select count(*) as cnt
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfset recordExists = (qCheckExistence.cnt GT 0)/>
<!--- <cfdump var=#qCheckExistence#/> --->
<cfelse>
<cfset recordExists = "false"/>
</cfif>
<cfif listFindNoCase("read,pass,save", ATTRIBUTES.mode)>
<cfset processingMode=ATTRIBUTES.mode/>
<cfelse>
<!--- ищем команду принудительного перечитывания --->
<cfset doRead = false/>
<cfloop list=#ATTRIBUTES.readmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doRead = true/>
<cfbreak/>
</cfif>
</cfloop>
<!--- ищем команду сохранения --->
<cfset doSave = false/>
<cfif !doRead AND !ATTRIBUTES.readonly>
<cfloop list=#ATTRIBUTES.savemarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doSave = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- ищем команду проброса --->
<cfset doPass = false/>
<cfif !doRead AND !doSave>
<cfloop list=#ATTRIBUTES.passmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doPass = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- определяем режим --->
<cfif doRead>
<cfset processingMode="read"/>
<cfelseif doSave>
<cfset processingMode="save"/>
<cfelse>
<cfif doPass OR !recordExists>
<cfset processingMode="pass"/>
<cfelse>
<cfset processingMode="read"/>
</cfif>
</cfif>
</cfif>
<cfset initialProcessingMode = processingMode/>
<!---debug <cfoutput>processingMode:#processingMode#</cfoutput>--->
<!--- ---------------------------------------------------------- --->
<!---*** Необходимость вставки (против апдейта) определяется по существованию записи. Это небезопасно, поскольку наличие записи с ключом -1 может прекратить создание новых записей. Конечно, можно добавить констрейнт на ключевое поле, но это лишняя зависимость.
Можно явно передавать команду вставки, а не заморачиваться с анализом ключа. Просто традиционно мы сигнализировали необходимость вставки, передавая невалидное значение ключа, обычно -1. Для целочисленных ключей можно было бы просто проверять положительность (что всю жизнь отлично работало), но хочется более общего.
--->
<cfif processingMode IS "save"> <!--- validation lookup --->
<cfloop array=#thistag.params# index="param">
<cfif !param.key>
<cfif param.warningState>
<cfif NOT warningState><!--- catch the first fault --->
<cfset warningMessage=param.warningMessage />
</cfif>
<cfset warningState="true" />
</cfif>
<cfif param.errorState>
<cfif NOT errorState><!--- catch the first fault --->
<cfset errorMessage=param.errorMessage />
</cfif>
<cfset errorState="true" />
<cfset validationOk="false"/>
</cfif>
</cfif>
<cfif errorState>
<!--- clear warning state --->
<cfset warningMessage="" />
<cfset warningState=false />
<!--- finish lookup --->
<cfbreak/>
</cfif>
</cfloop>
<cfif validationOk>
<!---<cfdump var=#param#/> --->
<cftry>
<cfif recordExists><!--- update. Наличие keyValue гарантировано (уверен) --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#" result="qSaveResult">
update #ATTRIBUTES.table# set
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<!--- не обновляем ключевые поля --->
<cfif NOT (StructFind(param, "key")
OR StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipUpdate")
)><cfif i++ GT 0>,</cfif>
#param.field#=<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#"/>
</cfloop>
</cfquery>
<!---<cfdump var=#qSaveResult#/>--->
<cfelse><!--- insert --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#">
insert into #ATTRIBUTES.table#
(
<cfset i=0 />
<!--- ключевые поля без автоинкремента попадают в insert! --->
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
#param.field#
</cfif>
</cfloop>
)
values
(
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
);
<!---
<cfif hasAutoIncrement>
select scope_identity() as id;
</cfif>
--->
<!---
*** PostgreSQL incompatible hack
--->
<cfif hasAutoIncrement>
select LASTVAL() as id;
</cfif>
</cfquery>
<cfif hasAutoIncrement>
<cfset keys[autoIncrementKeyIndex].value=qSave.id/>
</cfif>
</cfif>
<!--- recordExists --->
<cfset processingMode="read"/>
<cfcatch type="database">
<cfset errorState="true" />
<cfset errorMessage="Ошибка при записи в базу данных. #cfcatch.message# #cfcatch.detail#" />
<cfset processingMode="pass" />
</cfcatch>
</cftry>
<cfelse><!--- (not) validationOk --->
<cfset processingMode="pass"/>
</cfif><!--- validationOk --->
</cfif><!--- processingMode EQ "save" --->
<!--- экспортируем данные --->
<cfswitch expression=#processingMode#>
<cfcase value="read">
<cfquery name="qRead" datasource="#ATTRIBUTES.datasource#">
select
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfset i=i+1/>
#param.field#<cfif i LT ArrayLen(thistag.params)>,</cfif>
</cfloop>
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
/*#sqlType(key.type)#*/
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfloop array=#thistag.params# index="param"><!--- *** --->
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", structFind(qRead, #param.field#)) />
</cfloop>
</cfcase>
<cfcase value="pass"><!--- заполнить все поля. Если значения переданы в форме или урле, тег параметра обязан их разобрать и подставить, в противном случае подставить инит-значения. Инит-значение по умолчанию пустая строка, дефолт по умолчанию тоже пустая строка --->
<cfloop array=#thistag.params# index="param">
<!--- <cfdump var=#param#/>--->
<cfif param.hasInput>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.submittedValue) /><!---*** дефект: 03.12.2015, передаваемая строкой, при обработке dateFormat неправильно парсится --->
<cfelse>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.init) />
</cfif>
</cfloop>
</cfcase>
<cfdefaultcase>
</cfdefaultcase>
</cfswitch>
<cfif len(ATTRIBUTES.info)><!--- экспортируем дополнительные сведения--->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.submittedValue", #param.submittedValue#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorState", #param.errorState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorMessage", #param.errorMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningState", #param.warningState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningMessage", #param.warningMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.null", #param.null#) />
</cfloop>
</cfif>
<cfif len(ATTRIBUTES.meta)><!--- экспортируем метаданные параметра - для инвариантности вызовов --->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.param", #param.param#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.field", #param.field#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.type", #param.type#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.displayName", #param.displayName#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.default", #param.default#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.size", #param.size#) />
</cfloop>
</cfif>
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(errorState,errorMessage,initialProcessingMode))/>
</cfif><!--- thisTag.ExecutionMode is 'end'--->
<!--- quick and dirty --->
<cffunction name="sqlType">
<cfargument name="type"/>
<cfswitch expression=#type#>
<cfcase value="guid,uuid,idstamp"><cfreturn "CF_SQL_OTHER"/></cfcase><!--- hack for PostgreSQL uuid --->
<cfdefaultcase><cfreturn uCase("CF_SQL_#type#")/></cfdefaultcase>
</cfswitch>
</cffunction>
<cffunction name="checkDataFormat">
<cfargument name="type"/>
<cfargument name="value"/>
<cfswitch expression=#type#>
<cfcase value="integer"><cfreturn isValid("integer",value)/></cfcase>
<cfcase value="guid,uuid,idstamp"><cfreturn isValid("guid",value)/></cfcase>
<cfdefaultcase><cfreturn true/></cfdefaultcase>
</cfswitch>
</cffunction>
<!--- //quick and dirty
function sqlType(type) {
switch (type) {
case "guid,idstamp": return "CF_SQL_OTHER"; /*hack for PostgreSQL uuid*/ /*break not needed!*/
default: return uCase("CF_SQL_#type#");
}
}
function checkDataFormat(type,value) {
switch (type) {
case "integer": return isValid("integer",value); /*break not needed!*/
case "guid,uuid,idstamp": return isValid("guid",value); /*break not needed!*/ /*INCORRECT cfscript switch-case does not support lists*/
default: return true;
}
} --->
<cfscript>
//readonly может транслироваться в pass!
function translateMode(readonly) {
if (readonly) {
return "read";
} else {
return "";
}
}
</cfscript>
+398
View File
@@ -0,0 +1,398 @@
<!---
bean v0.95
msyu@mail.ru
2013-08-29 v0.1
2013-09-04 v0.2 tested with CF8 and Railo
2013-10-14 added meta attribute - can now export each parameter metadata
2014-12-26 POST-GET read-pass-save
2015-01-19 read-pass-save, добавлен formmarker, убрано определение режима по POST-GET
2015-01-19 убран formmarker, упразднен режим init (используется pass)
2015-07-16 добавлен passmarker для перерисовки формы с введенными значениями
2015-10-02 поддержка составных ключей
2015-10-09 v0.9 если задано value параметра, считается, что он hasInput (корректно работает в составе ключа)
2015-11-25 добавлен readmarker, mode (принудительная установка режима)
2015-11-26 добавлен mode=skip
2016-09-01 изменена трактовка processingMode. Теперь понимается как исходная команда, фиксируется до начала действий. Можно использовать для управления
2018-09-16 добавлена ограниченная поддержка нецелых первичных ключей (idstamp)
child tag: param
to save - should send parameter with name from list ATTRIBUTES.savemarker (value doesn't matter) in FORM, e.g. URL.save="trtrtr", while ATTRIBUTES.savemarker="save,saveAndClose"; for multiple forms on a page (and bean tags) different savemarkers should be used
2022-01-06 PostgreSQL (MSSQL incompatibility because of scope_identity)
2024-04-13 PostgreSQL GUID, autoincrement by RETURNING
--->
<!---
Автогенерируемое поле GUID можно заполнять несколькими способами
- как default или init bean/param, но это не очень удобно, потому что может потеряться удобный признак новой записи - инвалидный ключ, и сейчас init-default взаимодействуют некорректно, по крайней мере, неочевидно
- генерируемое в БД (например, как default). Для PostgreSQL значение возвращается через Returning, как это делать для других БД, непонятно.
- можно генерировать при сохранении в bean, но для этого нужно расширение синтаксиса, зато не зависит от БД (*** TODO)
--->
<cfif thisTag.ExecutionMode is 'end'>
<cfparam name="ATTRIBUTES.readmarker" type="string" default="read"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда перечитывания. Имеет приоритет перед savemarker, passmarker. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.savemarker" type="string" default="save,saveAndClose"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда сохранения. Обычно это имя кнопки. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.passmarker" type="string" default="pass"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда заполнить форму отправленными данными без перечитывания. В форме такое поле обычно есть. Команда сохранения имеет приоритет перед пробросом. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.datasource" type="string"/>
<cfparam name="ATTRIBUTES.table" type="string"/>
<cfparam name="ATTRIBUTES.output" type="string"/>
<cfparam name="ATTRIBUTES.info" type="string" default=""/>
<cfparam name="ATTRIBUTES.meta" type="string" default=""/>
<cfparam name="ATTRIBUTES.status" type="string"/>
<cfparam name="ATTRIBUTES.readonly" type="boolean" default="No"/>
<cfparam name="ATTRIBUTES.mode" type="string" default=""/> <!--- Принудительный режим read|pass|save|skip. Имеет приоритет перед маркерами --->
<cfif ATTRIBUTES.mode EQ "skip">
<!---<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorState", false) />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorMessage", "") />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.processingMode", "skip") />--->
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(false,"","skip"))/>
<cfexit method="exittag"/>
</cfif>
<cfset validationOk="true" />
<cfset errorState="false" />
<cfset errorMessage="" />
<cfset warningState="false" />
<cfset warningMessage="" />
<!---<cfset keyField=""/>
<cfset keyValue=""/>--->
<cfset hasAutoIncrement="false"/>
<cfset autoIncrementKeyIndex=0/><!--- сгенерированное значение присваивается первому полю, отмеченному как autoincrement --->
<cfset recordExists = "false"/>
<cfset keyInvalid = "false"/>
<!--- разбор метаданных - поиск ключа --->
<!--- поддерживаются только простые целочисленные ключи --->
<cfset keys=arrayNew(1)/>
<!--- *** почему где-то копируем поля param в key, а где-то прямо цикл по параметрам --->
<!--- коллекция thistag.params формируется вложенными тегами param --->
<cfloop array=#thistag.params# index="param">
<!---<cfdump var=#param#/>--->
<cfif structFind(param,"key")><!--- not just structKeyExists! Not exisis, OR exists, but FALSE! --->
<cfset key = structNew()/>
<cfset ArrayAppend(keys, key)/>
<cfset key.name = param.param />
<cfset key.field = param.field />
<cfset key.type = param.type />
<cfset key.value = param.value /><!--- должно уже быть присвоено --->
<cfset key.null = param.null />
<cfif param.errorState OR !param.hasInput>
<cfset keyInvalid="true"/>
<cfelse>
<cfset keyInvalid=!checkDataFormat(param.type, param.value)/>
</cfif>
<cfif !hasAutoIncrement><!--- take only first field with "autoincrement" attribute--->
<cfif structFind(param, "autoincrement")>
<cfset hasAutoIncrement = true/>
<cfset autoIncrementKeyIndex = arrayLen(keys)/>
</cfif>
</cfif>
</cfif>
</cfloop>
<!---<cfdump var=#keys#/>--->
<cfif !keyInvalid>
<!--- *** дублируется похожий cfqueryparam, перепутал один раз --->
<cfquery name="qCheckExistence" datasource="#ATTRIBUTES.datasource#">
select count(*) as cnt
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfset recordExists = (qCheckExistence.cnt GT 0)/>
<!--- <cfdump var=#qCheckExistence#/> --->
<cfelse>
<cfset recordExists = "false"/>
</cfif>
<cfif listFindNoCase("read,pass,save", ATTRIBUTES.mode)>
<cfset processingMode=ATTRIBUTES.mode/>
<cfelse>
<!--- ищем команду принудительного перечитывания --->
<cfset doRead = false/>
<cfloop list=#ATTRIBUTES.readmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doRead = true/>
<cfbreak/>
</cfif>
</cfloop>
<!--- ищем команду сохранения --->
<cfset doSave = false/>
<cfif !doRead AND !ATTRIBUTES.readonly>
<cfloop list=#ATTRIBUTES.savemarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doSave = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- ищем команду проброса --->
<cfset doPass = false/>
<cfif !doRead AND !doSave>
<cfloop list=#ATTRIBUTES.passmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doPass = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- определяем режим --->
<cfif doRead>
<cfset processingMode="read"/>
<cfelseif doSave>
<cfset processingMode="save"/>
<cfelse>
<cfif doPass OR !recordExists>
<cfset processingMode="pass"/>
<cfelse>
<cfset processingMode="read"/>
</cfif>
</cfif>
</cfif>
<cfset initialProcessingMode = processingMode/>
<!---debug <cfoutput>processingMode:#processingMode#</cfoutput>--->
<!--- ---------------------------------------------------------- --->
<!---*** Необходимость вставки (против апдейта) определяется по существованию записи. Это небезопасно, поскольку наличие записи с ключом -1 может прекратить создание новых записей. Конечно, можно добавить констрейнт на ключевое поле, но это лишняя зависимость.
Можно явно передавать команду вставки, а не заморачиваться с анализом ключа. Просто традиционно мы сигнализировали необходимость вставки, передавая невалидное значение ключа, обычно -1. Для целочисленных ключей можно было бы просто проверять положительность (что всю жизнь отлично работало), но хочется более общего.
--->
<cfif processingMode IS "save"> <!--- validation lookup --->
<cfloop array=#thistag.params# index="param">
<cfif !param.key>
<cfif param.warningState>
<cfif NOT warningState><!--- catch the first fault --->
<cfset warningMessage=param.warningMessage />
</cfif>
<cfset warningState="true" />
</cfif>
<cfif param.errorState>
<cfif NOT errorState><!--- catch the first fault --->
<cfset errorMessage=param.errorMessage />
</cfif>
<cfset errorState="true" />
<cfset validationOk="false"/>
</cfif>
</cfif>
<cfif errorState>
<!--- clear warning state --->
<cfset warningMessage="" />
<cfset warningState=false />
<!--- finish lookup --->
<cfbreak/>
</cfif>
</cfloop>
<cfif validationOk>
<!---<cfdump var=#param#/> --->
<cftry>
<cfif recordExists><!--- update. Наличие keyValue гарантировано (уверен) --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#" result="qSaveResult">
update #ATTRIBUTES.table# set
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<!--- не обновляем ключевые поля --->
<cfif NOT (StructFind(param, "key")
OR StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipUpdate")
)><cfif i++ GT 0>,</cfif>
#param.field#=<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#"/>
</cfloop>
</cfquery>
<!---<cfdump var=#qSaveResult#/>--->
<cfelse><!--- insert --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#">
insert into #ATTRIBUTES.table#
(
<cfset i=0 />
<!--- ключевые поля без автоинкремента попадают в insert! --->
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
#param.field#
</cfif>
</cfloop>
)
values
(
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
)
<!---
<cfif hasAutoIncrement>
select scope_identity() as id;
</cfif>
--->
<!---*** PostgreSQL incompatible hack follows--->
<cfif hasAutoIncrement>
returning #thistag.params[autoIncrementKeyIndex].field# as id;
</cfif>;
</cfquery>
<!--- <cfdump var=#qSave#/> --->
<cfif hasAutoIncrement>
<cfset keys[autoIncrementKeyIndex].value=qSave.id/>
</cfif>
</cfif>
<!--- recordExists --->
<cfset processingMode="read"/>
<cfcatch type="database">
<cfset errorState="true" />
<cfset errorMessage="Ошибка при записи в базу данных. #cfcatch.message# #cfcatch.detail#" />
<cfset processingMode="pass" />
</cfcatch>
</cftry>
<cfelse><!--- (not) validationOk --->
<cfset processingMode="pass"/>
</cfif><!--- validationOk --->
</cfif><!--- processingMode EQ "save" --->
<!--- экспортируем данные --->
<cfswitch expression=#processingMode#>
<cfcase value="read">
<cfquery name="qRead" datasource="#ATTRIBUTES.datasource#">
select
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfset i=i+1/>
#param.field#<cfif i LT ArrayLen(thistag.params)>,</cfif>
</cfloop>
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
/*#sqlType(key.type)#*/
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfloop array=#thistag.params# index="param"><!--- *** --->
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", structFind(qRead, #param.field#)) />
</cfloop>
</cfcase>
<cfcase value="pass"><!--- заполнить все поля. Если значения переданы в форме или урле, тег параметра обязан их разобрать и подставить, в противном случае подставить инит-значения. Инит-значение по умолчанию пустая строка, дефолт по умолчанию тоже пустая строка --->
<cfloop array=#thistag.params# index="param">
<!--- <cfdump var=#param#/>--->
<cfif param.hasInput>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.submittedValue) /><!---*** дефект: 03.12.2015, передаваемая строкой, при обработке dateFormat неправильно парсится --->
<cfelse>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.init) />
</cfif>
</cfloop>
</cfcase>
<cfdefaultcase>
</cfdefaultcase>
</cfswitch>
<cfif len(ATTRIBUTES.info)><!--- экспортируем дополнительные сведения--->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.submittedValue", #param.submittedValue#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorState", #param.errorState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorMessage", #param.errorMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningState", #param.warningState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningMessage", #param.warningMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.null", #param.null#) />
</cfloop>
</cfif>
<cfif len(ATTRIBUTES.meta)><!--- экспортируем метаданные параметра - для инвариантности вызовов --->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.param", #param.param#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.field", #param.field#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.type", #param.type#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.displayName", #param.displayName#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.default", #param.default#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.size", #param.size#) />
</cfloop>
</cfif>
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(errorState,errorMessage,initialProcessingMode))/>
</cfif><!--- thisTag.ExecutionMode is 'end'--->
<!--- quick and dirty --->
<cffunction name="sqlType">
<cfargument name="type"/>
<cfswitch expression=#type#>
<cfcase value="guid,uuid,idstamp"><cfreturn "CF_SQL_OTHER"/></cfcase><!--- hack for PostgreSQL uuid --->
<cfdefaultcase><cfreturn uCase("CF_SQL_#type#")/></cfdefaultcase>
</cfswitch>
</cffunction>
<cffunction name="checkDataFormat">
<cfargument name="type"/>
<cfargument name="value"/>
<cfswitch expression=#type#>
<cfcase value="integer"><cfreturn isValid("integer",value)/></cfcase>
<cfcase value="guid,uuid,idstamp"><cfreturn isValid("guid",value)/></cfcase>
<cfdefaultcase><cfreturn true/></cfdefaultcase>
</cfswitch>
</cffunction>
<!--- //quick and dirty
function sqlType(type) {
switch (type) {
case "guid,idstamp": return "CF_SQL_OTHER"; /*hack for PostgreSQL uuid*/ /*break not needed!*/
default: return uCase("CF_SQL_#type#");
}
}
function checkDataFormat(type,value) {
switch (type) {
case "integer": return isValid("integer",value); /*break not needed!*/
case "guid,uuid,idstamp": return isValid("guid",value); /*break not needed!*/ /*INCORRECT cfscript switch-case does not support lists*/
default: return true;
}
} --->
<cfscript>
//readonly может транслироваться в pass!
function translateMode(readonly) {
if (readonly) {
return "read";
} else {
return "";
}
}
</cfscript>
+398
View File
@@ -0,0 +1,398 @@
<!---
bean v0.95
msyu@mail.ru
2013-08-29 v0.1
2013-09-04 v0.2 tested with CF8 and Railo
2013-10-14 added meta attribute - can now export each parameter metadata
2014-12-26 POST-GET read-pass-save
2015-01-19 read-pass-save, добавлен formmarker, убрано определение режима по POST-GET
2015-01-19 убран formmarker, упразднен режим init (используется pass)
2015-07-16 добавлен passmarker для перерисовки формы с введенными значениями
2015-10-02 поддержка составных ключей
2015-10-09 v0.9 если задано value параметра, считается, что он hasInput (корректно работает в составе ключа)
2015-11-25 добавлен readmarker, mode (принудительная установка режима)
2015-11-26 добавлен mode=skip
2016-09-01 изменена трактовка processingMode. Теперь понимается как исходная команда, фиксируется до начала действий. Можно использовать для управления
2018-09-16 добавлена ограниченная поддержка нецелых первичных ключей (idstamp)
child tag: param
to save - should send parameter with name from list ATTRIBUTES.savemarker (value doesn't matter) in FORM, e.g. URL.save="trtrtr", while ATTRIBUTES.savemarker="save,saveAndClose"; for multiple forms on a page (and bean tags) different savemarkers should be used
2022-01-06 PostgreSQL (MSSQL incompatibility because of scope_identity)
2024-04-13 PostgreSQL GUID, autoincrement by RETURNING
--->
<!---
Автогенерируемое поле GUID можно заполнять несколькими способами
- как default или init bean/param, но это не очень удобно, потому что может потеряться удобный признак новой записи - инвалидный ключ, и сейчас init-default взаимодействуют некорректно, по крайней мере, неочевидно
- генерируемое в БД (например, как default). Для PostgreSQL значение возвращается через Returning, как это делать для других БД, непонятно.
- можно генерировать при сохранении в bean, но для этого нужно расширение синтаксиса, зато не зависит от БД (*** TODO)
--->
<cfif thisTag.ExecutionMode is 'end'>
<cfparam name="ATTRIBUTES.readmarker" type="string" default="read"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда перечитывания. Имеет приоритет перед savemarker, passmarker. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.savemarker" type="string" default="save,saveAndClose"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда сохранения. Обычно это имя кнопки. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.passmarker" type="string" default="pass"/><!--- наличие в FORM или URL поля с таким именем воспринимается как команда заполнить форму отправленными данными без перечитывания. В форме такое поле обычно есть. Команда сохранения имеет приоритет перед пробросом. Можно передавать несколько вариантов списком через запятую. --->
<cfparam name="ATTRIBUTES.datasource" type="string"/>
<cfparam name="ATTRIBUTES.table" type="string"/>
<cfparam name="ATTRIBUTES.output" type="string"/>
<cfparam name="ATTRIBUTES.info" type="string" default=""/>
<cfparam name="ATTRIBUTES.meta" type="string" default=""/>
<cfparam name="ATTRIBUTES.status" type="string"/>
<cfparam name="ATTRIBUTES.readonly" type="boolean" default="No"/>
<cfparam name="ATTRIBUTES.mode" type="string" default=""/> <!--- Принудительный режим read|pass|save|skip. Имеет приоритет перед маркерами --->
<cfif ATTRIBUTES.mode EQ "skip">
<!---<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorState", false) />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.errorMessage", "") />
<cfset SetVariable("CALLER.#ATTRIBUTES.status#.processingMode", "skip") />--->
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(false,"","skip"))/>
<cfexit method="exittag"/>
</cfif>
<cfset validationOk="true" />
<cfset errorState="false" />
<cfset errorMessage="" />
<cfset warningState="false" />
<cfset warningMessage="" />
<!---<cfset keyField=""/>
<cfset keyValue=""/>--->
<cfset hasAutoIncrement="false"/>
<cfset autoIncrementKeyIndex=0/><!--- сгенерированное значение присваивается первому полю, отмеченному как autoincrement --->
<cfset recordExists = "false"/>
<cfset keyInvalid = "false"/>
<!--- разбор метаданных - поиск ключа --->
<!--- поддерживаются только простые целочисленные ключи --->
<cfset keys=arrayNew(1)/>
<!--- *** почему где-то копируем поля param в key, а где-то прямо цикл по параметрам --->
<!--- коллекция thistag.params формируется вложенными тегами param --->
<cfloop array=#thistag.params# index="param">
<!---<cfdump var=#param#/>--->
<cfif structFind(param,"key")><!--- not just structKeyExists! Not exisis, OR exists, but FALSE! --->
<cfset key = structNew()/>
<cfset ArrayAppend(keys, key)/>
<cfset key.name = param.param />
<cfset key.field = param.field />
<cfset key.type = param.type />
<cfset key.value = param.value /><!--- должно уже быть присвоено --->
<cfset key.null = param.null />
<cfif param.errorState OR !param.hasInput>
<cfset keyInvalid="true"/>
<cfelse>
<cfset keyInvalid=!checkDataFormat(param.type, param.value)/>
</cfif>
<cfif !hasAutoIncrement><!--- take only first field with "autoincrement" attribute--->
<cfif structFind(param, "autoincrement")>
<cfset hasAutoIncrement = true/>
<cfset autoIncrementKeyIndex = arrayLen(keys)/>
</cfif>
</cfif>
</cfif>
</cfloop>
<!---<cfdump var=#keys#/>--->
<cfif !keyInvalid>
<!--- *** дублируется похожий cfqueryparam, перепутал один раз --->
<cfquery name="qCheckExistence" datasource="#ATTRIBUTES.datasource#">
select count(*) as cnt
from #ATTRIBUTES.table#
where 1=1
<!--- <cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop> --->
</cfquery>
<cfset recordExists = (qCheckExistence.cnt GT 0)/>
<!--- <cfdump var=#qCheckExistence#/> --->
<cfelse>
<cfset recordExists = "false"/>
</cfif>
<cfif listFindNoCase("read,pass,save", ATTRIBUTES.mode)>
<cfset processingMode=ATTRIBUTES.mode/>
<cfelse>
<!--- ищем команду принудительного перечитывания --->
<cfset doRead = false/>
<cfloop list=#ATTRIBUTES.readmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doRead = true/>
<cfbreak/>
</cfif>
</cfloop>
<!--- ищем команду сохранения --->
<cfset doSave = false/>
<cfif !doRead AND !ATTRIBUTES.readonly>
<cfloop list=#ATTRIBUTES.savemarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doSave = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- ищем команду проброса --->
<cfset doPass = false/>
<cfif !doRead AND !doSave>
<cfloop list=#ATTRIBUTES.passmarker# index="marker">
<cfif structKeyExists(FORM,"#marker#") OR structKeyExists(URL,"#marker#")>
<cfset doPass = true/>
<cfbreak/>
</cfif>
</cfloop>
</cfif>
<!--- определяем режим --->
<cfif doRead>
<cfset processingMode="read"/>
<cfelseif doSave>
<cfset processingMode="save"/>
<cfelse>
<cfif doPass OR !recordExists>
<cfset processingMode="pass"/>
<cfelse>
<cfset processingMode="read"/>
</cfif>
</cfif>
</cfif>
<cfset initialProcessingMode = processingMode/>
<!---debug <cfoutput>processingMode:#processingMode#</cfoutput>--->
<!--- ---------------------------------------------------------- --->
<!---*** Необходимость вставки (против апдейта) определяется по существованию записи. Это небезопасно, поскольку наличие записи с ключом -1 может прекратить создание новых записей. Конечно, можно добавить констрейнт на ключевое поле, но это лишняя зависимость.
Можно явно передавать команду вставки, а не заморачиваться с анализом ключа. Просто традиционно мы сигнализировали необходимость вставки, передавая невалидное значение ключа, обычно -1. Для целочисленных ключей можно было бы просто проверять положительность (что всю жизнь отлично работало), но хочется более общего.
--->
<cfif processingMode IS "save"> <!--- validation lookup --->
<cfloop array=#thistag.params# index="param">
<cfif !param.key>
<cfif param.warningState>
<cfif NOT warningState><!--- catch the first fault --->
<cfset warningMessage=param.warningMessage />
</cfif>
<cfset warningState="true" />
</cfif>
<cfif param.errorState>
<cfif NOT errorState><!--- catch the first fault --->
<cfset errorMessage=param.errorMessage />
</cfif>
<cfset errorState="true" />
<cfset validationOk="false"/>
</cfif>
</cfif>
<cfif errorState>
<!--- clear warning state --->
<cfset warningMessage="" />
<cfset warningState=false />
<!--- finish lookup --->
<cfbreak/>
</cfif>
</cfloop>
<cfif validationOk>
<!---<cfdump var=#param#/> --->
<cftry>
<cfif recordExists><!--- update. Наличие keyValue гарантировано (уверен) --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#" result="qSaveResult">
update #ATTRIBUTES.table# set
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<!--- не обновляем ключевые поля --->
<cfif NOT (StructFind(param, "key")
OR StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipUpdate")
)><cfif i++ GT 0>,</cfif>
#param.field#=<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
where 1=1
<cfloop array=#keys# index="key">
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#"/>
</cfloop>
</cfquery>
<!---<cfdump var=#qSaveResult#/>--->
<cfelse><!--- insert --->
<cfquery name="qSave" datasource="#ATTRIBUTES.datasource#">
insert into #ATTRIBUTES.table#
(
<cfset i=0 />
<!--- ключевые поля без автоинкремента попадают в insert! --->
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
#param.field#
</cfif>
</cfloop>
)
values
(
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfif NOT (StructFind(param, "autoincrement")
OR StructFind(param, "readonly")
OR StructFind(param, "skipInsert")
)><cfif i++ GT 0>,</cfif>
<cfqueryparam cfsqltype="#sqlType(param.type)#" value="#param.value#" null="#param.null#"/>
</cfif>
</cfloop>
)
<!---
<cfif hasAutoIncrement>
select scope_identity() as id;
</cfif>
--->
<!---*** PostgreSQL incompatible hack follows--->
<cfif hasAutoIncrement>
returning #thistag.params[autoIncrementKeyIndex].field# as id;
</cfif>;
</cfquery>
<!--- <cfdump var=#qSave#/> --->
<cfif hasAutoIncrement>
<cfset keys[autoIncrementKeyIndex].value=qSave.id/>
</cfif>
</cfif>
<!--- recordExists --->
<cfset processingMode="read"/>
<cfcatch type="database">
<cfset errorState="true" />
<cfset errorMessage="Ошибка при записи в базу данных. #cfcatch.message# #cfcatch.detail#" />
<cfset processingMode="pass" />
</cfcatch>
</cftry>
<cfelse><!--- (not) validationOk --->
<cfset processingMode="pass"/>
</cfif><!--- validationOk --->
</cfif><!--- processingMode EQ "save" --->
<!--- экспортируем данные --->
<cfswitch expression=#processingMode#>
<cfcase value="read">
<cfquery name="qRead" datasource="#ATTRIBUTES.datasource#">
select
<cfset i=0 />
<cfloop array=#thistag.params# index="param">
<cfset i=i+1/>
#param.field#<cfif i LT ArrayLen(thistag.params)>,</cfif>
</cfloop>
from #ATTRIBUTES.table#
where 1=1
<cfloop array=#keys# index="key">
/*#sqlType(key.type)#*/
AND #key.field#=<cfqueryparam cfsqltype="#sqlType(key.type)#" value="#key.value#" null="#key.null#"/>
</cfloop>
</cfquery>
<cfloop array=#thistag.params# index="param"><!--- *** --->
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", structFind(qRead, #param.field#)) />
</cfloop>
</cfcase>
<cfcase value="pass"><!--- заполнить все поля. Если значения переданы в форме или урле, тег параметра обязан их разобрать и подставить, в противном случае подставить инит-значения. Инит-значение по умолчанию пустая строка, дефолт по умолчанию тоже пустая строка --->
<cfloop array=#thistag.params# index="param">
<!--- <cfdump var=#param#/>--->
<cfif param.hasInput>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.submittedValue) /><!---*** дефект: 03.12.2015, передаваемая строкой, при обработке dateFormat неправильно парсится --->
<cfelse>
<cfset SetVariable("CALLER.#ATTRIBUTES.output#.#param.param#", param.init) />
</cfif>
</cfloop>
</cfcase>
<cfdefaultcase>
</cfdefaultcase>
</cfswitch>
<cfif len(ATTRIBUTES.info)><!--- экспортируем дополнительные сведения--->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.submittedValue", #param.submittedValue#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorState", #param.errorState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.errorMessage", #param.errorMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningState", #param.warningState#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.warningMessage", #param.warningMessage#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.info#.#param.param#.null", #param.null#) />
</cfloop>
</cfif>
<cfif len(ATTRIBUTES.meta)><!--- экспортируем метаданные параметра - для инвариантности вызовов --->
<cfloop array=#thistag.params# index="param">
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.param", #param.param#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.field", #param.field#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.type", #param.type#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.displayName", #param.displayName#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.default", #param.default#) />
<cfset SetVariable("CALLER.#ATTRIBUTES.meta#.#param.param#.size", #param.size#) />
</cfloop>
</cfif>
<cfset SetVariable("CALLER.#ATTRIBUTES.status#", CreateObject("component","status").init(errorState,errorMessage,initialProcessingMode))/>
</cfif><!--- thisTag.ExecutionMode is 'end'--->
<!--- quick and dirty --->
<cffunction name="sqlType">
<cfargument name="type"/>
<cfswitch expression=#type#>
<cfcase value="guid,uuid,idstamp"><cfreturn "CF_SQL_OTHER"/></cfcase><!--- hack for PostgreSQL uuid --->
<cfdefaultcase><cfreturn uCase("CF_SQL_#type#")/></cfdefaultcase>
</cfswitch>
</cffunction>
<cffunction name="checkDataFormat">
<cfargument name="type"/>
<cfargument name="value"/>
<cfswitch expression=#type#>
<cfcase value="integer"><cfreturn isValid("integer",value)/></cfcase>
<cfcase value="guid,uuid,idstamp"><cfreturn isValid("guid",value)/></cfcase>
<cfdefaultcase><cfreturn true/></cfdefaultcase>
</cfswitch>
</cffunction>
<!--- //quick and dirty
function sqlType(type) {
switch (type) {
case "guid,idstamp": return "CF_SQL_OTHER"; /*hack for PostgreSQL uuid*/ /*break not needed!*/
default: return uCase("CF_SQL_#type#");
}
}
function checkDataFormat(type,value) {
switch (type) {
case "integer": return isValid("integer",value); /*break not needed!*/
case "guid,uuid,idstamp": return isValid("guid",value); /*break not needed!*/ /*INCORRECT cfscript switch-case does not support lists*/
default: return true;
}
} --->
<cfscript>
//readonly может транслироваться в pass!
function translateMode(readonly) {
if (readonly) {
return "read";
} else {
return "";
}
}
</cfscript>
+24
View File
@@ -0,0 +1,24 @@
<cfsilent>
<!--- 20181209 v0.3 --->
<!---v0.3 добавлен атрибут cfSqlType--->
<cfif thisTag.executionMode IS "end" OR !thisTag.hasEndTag>
<cfassociate basetag="cf_field_set" datacollection="fieldsArray"/>
<cfparam name="ATTRIBUTES.expression" default=""/>
<cfparam name="ATTRIBUTES.title" default=""/>
<cfparam name="ATTRIBUTES.name" default=""/>
<cfparam name="ATTRIBUTES.cfSqlType" default="CF_SQL_VARCHAR"/>
<cfif ATTRIBUTES.expression IS "">
<cfset ATTRIBUTES.expression=thisTag.generatedContent/>
</cfif>
<cfif ATTRIBUTES.name IS "">
<cfset regex="([[:word:]]+)[[:space:]]*$"/>
<cfset matches=REFindNoCase(regex, ATTRIBUTES.expression, 1, true)/>
<cfif arrayLen(matches.pos) GT 1>
<cfset ATTRIBUTES.name=mid(ATTRIBUTES.expression, matches.pos[2], matches.len[2])/>
</cfif>
</cfif>
</cfif>
</cfsilent>

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