diff --git a/modules/distribution/src/assembly/bin.xml b/modules/distribution/src/assembly/bin.xml index d9293494..ea7fd4b7 100644 --- a/modules/distribution/src/assembly/bin.xml +++ b/modules/distribution/src/assembly/bin.xml @@ -59,7 +59,6 @@ **/axis2services/sample01.aar **/axis2services/echo/** **/axis2services/version/** - **/version.txt **/master-datasources.xml **/carbon.xml @@ -184,13 +183,6 @@ 755 - - - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/modules @@ -241,16 +233,6 @@ authenticators.xml - - src/repository/conf/datasources ${pom.artifactId}-${pom.version}/repository/conf/datasources @@ -606,7 +588,6 @@ **/analytics-config.xml **/rdbms-config.xml - **/analytics-data-config.xml **/analytics-eventsink-config.xml @@ -673,25 +654,21 @@ - - - - + - src/repository/patches + src/repository/jaggeryapps/portal/store/carbon.super/gadget - ${pom.artifactId}-${pom.version}/repository/components/patches + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/store/carbon.super/gadget **/* - - + + - - ${pom.artifactId}-${pom.version}/lib/endorsed @@ -710,7 +687,6 @@ - src/repository/bin/wso2server.sh ${pom.artifactId}-${pom.version}/bin @@ -721,7 +697,6 @@ ${pom.artifactId}-${pom.version}/bin 755 - src/repository/jaggeryapps/api-store/jagg.jag @@ -735,7 +710,26 @@ 755 - + + + src/repository/jaggeryapps/portal/controllers/apis/analytics.jag + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/controllers/apis + + 755 + + + src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/js + + 755 + + + src/repository/jaggeryapps/portal/templates/gadgets/igviz/js/outputAdapterUiLibrary.js + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/templates/gadgets/igviz/js + + 755 + + ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/deployment/server/webapps/mdm-android-agent.war @@ -796,22 +790,6 @@ true 644 - src/repository/conf/tomcat/context.xml ${pom.artifactId}-${pom.version}/repository/conf/tomcat @@ -861,7 +839,6 @@ true 644 - @@ -871,7 +848,6 @@ true 644 - src/repository/conf/event-broker.xml @@ -885,7 +861,6 @@ true 644 - @@ -905,8 +880,6 @@ true 644 - - @@ -936,7 +909,6 @@ 644 - @@ -945,7 +917,6 @@ ${pom.artifactId}-${pom.version}/repository/conf 644 - src/repository/conf/api-manager.xml @@ -961,7 +932,6 @@ true 644 - @@ -971,8 +941,6 @@ true 644 - - @@ -982,8 +950,6 @@ true 644 - - @@ -993,7 +959,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/metrics.properties @@ -1030,7 +995,6 @@ ${pom.artifactId}-${pom.version}/repository/conf/etc/ 644 - @@ -1040,7 +1004,6 @@ true 644 - @@ -1050,7 +1013,6 @@ true 644 - @@ -1060,7 +1022,6 @@ true 644 - @@ -1070,7 +1031,6 @@ true 644 - @@ -1080,7 +1040,6 @@ true 644 - @@ -1101,7 +1060,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/claim-config.xml @@ -1111,8 +1069,6 @@ true 644 - - @@ -1122,7 +1078,6 @@ WSO2AM_DB.h2.db 644 - @@ -1132,8 +1087,6 @@ WSO2DM_DB.h2.db 644 - - @@ -1143,8 +1096,6 @@ AndroidSenseDM_DB.h2.db 644 - - @@ -1154,8 +1105,6 @@ ArduinoDM_DB.h2.db 644 - - @@ -1165,8 +1114,6 @@ DigitalDisplayDM_DB.h2.db 644 - - @@ -1176,8 +1123,6 @@ DroneAnalyzerDM_DB.h2.db 644 - - @@ -1187,7 +1132,6 @@ RaspberryPiDM_DB.h2.db 644 - @@ -1197,8 +1141,6 @@ VirtualFireAlarmDM_DB.h2.db 644 - - @@ -1208,7 +1150,6 @@ WSO2MobileAndroid_DB.h2.db 644 - @@ -1218,28 +1159,12 @@ WSO2MobileWindows_DB.h2.db 644 - src/repository/conf/carbon.xml ${pom.artifactId}-${pom.version}/repository/conf/ true - - - - - - - @@ -1250,7 +1175,6 @@ true 644 - src/repository/conf/axis2/axis2.xml @@ -1259,8 +1183,6 @@ true 644 - - src/repository/conf/etc/launch.ini ${pom.artifactId}-${pom.version}/repository/conf/etc/ @@ -1268,16 +1190,6 @@ true 644 - - - - - - - - - - @@ -1288,7 +1200,6 @@ true 644 - @@ -1311,7 +1222,6 @@ ${pom.artifactId}-${pom.version}/lib 644 - @@ -1321,7 +1231,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/cep/storm/storm.yaml @@ -1330,8 +1239,6 @@ true - - @@ -1341,7 +1248,6 @@ true - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/output-event-adapters.xml @@ -1351,7 +1257,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/input-event-adapters.xml @@ -1361,7 +1266,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/data-bridge/data-bridge-config.xml @@ -1392,7 +1296,6 @@ 755 - @@ -1402,7 +1305,6 @@ 755 - @@ -1412,7 +1314,6 @@ 755 - @@ -1422,7 +1323,6 @@ 755 - @@ -1431,43 +1331,6 @@ ${pom.artifactId}-${pom.version}/repository/deployment/server/webapps 644 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicemgt-config.xml @@ -1476,7 +1339,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicemgt-config.xsd @@ -1485,7 +1347,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicetype-config.xml @@ -1494,7 +1355,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicetype-config.xsd @@ -1503,15 +1363,5 @@ true 644 - - - - - - - - - - diff --git a/modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag b/modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag new file mode 100644 index 00000000..d1e90465 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag @@ -0,0 +1,380 @@ +<% +(function () { + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var TIME_FROM = "timeFrom"; + var TIME_TO = "timeTo"; + var START = "start"; + var COUNT = "count"; + var FILTER = "filter"; + var QUERY = "query"; + var SORT_SCORE_VALUE = "scoreFunc"; + var RECORDSTORE_NAME = "recordStore"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var USERNAME = "username"; + var WAIT_TIME = "waitTime"; + var LOCALHOST = "localhost"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var HTTP_INTERNAL_ERROR = 500; + var MILLISECONDS_PER_SECOND = 1000; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + var ZERO_INDEX = "0"; + var LAST_INDEX = "5000"; //Set the max value to 5000. This is to prevent accidental loading of millions of records. + var DEFAULT_COUNT = 20; + + var TYPE_CLEAR_INDEX_DATA = 1; +// var TYPE_CREATE_TABLE = 2; +// var TYPE_DELETE_BY_ID = 3; +// var TYPE_DELETE_BY_RANGE = 4; +// var TYPE_DELETE_TABLE = 5; + var TYPE_GET_RECORD_COUNT = 6; + var TYPE_GET_BY_ID = 7; + var TYPE_GET_BY_RANGE = 8; + var TYPE_LIST_TABLES = 9; + var TYPE_GET_SCHEMA = 10; +// var TYPE_PUT_RECORDS = 11; +// var TYPE_PUT_RECORDS_TO_TABLE = 12; + var TYPE_SEARCH = 13; + var TYPE_SEARCH_COUNT = 14; + var TYPE_SET_SCHEMA = 15; + var TYPE_TABLE_EXISTS = 16; + var TYPE_WAIT_FOR_INDEXING = 17; + var TYPE_PAGINATION_SUPPORTED = 18; + var TYPE_DRILLDOWN_CATEGORIES = 19; + var TYPE_DRILLDOWN_SEARCH = 20; + var TYPE_DRILLDOWN_SEARCH_COUNT = 21; + var TYPE_ADD_STREAM_DEFINITION = 22; + var TYPE_GET_STREAM_DEFINITION = 23; + var TYPE_PUBLISH_EVENTS = 24; + var TYPE_GET_WITH_KEY_VALUES = 25; + var TYPE_GET_RECORDSTORES = 26; + var TYPE_GET_RECORDSTORE_BY_TABLE = 27; + var TYPE_WAIT_FOR_INDEXING_FOR_TABLE = 28; + var TYPE_SEARCH_WITH_AGGREGATES = 29; + var TYPE_REINDEX = 30; + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if(configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if(configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + + var connector = new AnalyticsCachedJSServiceConnector(cache); + + var type = 0; + var typeParam = request.getParameter(TYPE); + if (typeParam != null) { + type = parseInt(typeParam); + } + + if (type == 0) { + log.error("operation type is not specified!"); + response.status = HTTP_INTERNAL_ERROR; + print('{ "status": "Failed", "message": "Operation type is not specified" }'); + return; + } + + var tableName = request.getParameter(TABLE_NAME); + if (type != TYPE_LIST_TABLES && + // type != TYPE_PUT_RECORDS && + type != TYPE_PAGINATION_SUPPORTED && + type != TYPE_ADD_STREAM_DEFINITION && + type != TYPE_GET_STREAM_DEFINITION && + type != TYPE_PUBLISH_EVENTS && + type != TYPE_WAIT_FOR_INDEXING && + type != TYPE_GET_RECORDSTORES) { + if (tableName == null) { + log.error("tableName is not provided!"); + response.status = HTTP_INTERNAL_ERROR; + print('{ "status": "Failed", "message": "Table name param is empty" }'); + return; + } + } + + var content = request.getContent(); + var contentAsString = null; + if (content != '' && content != null) { + contentAsString = stringify(content); + if (log.isDebugEnabled()) { + log.debug("value of content: " + contentAsString); + } + } + if (connector != null && loggedInUser != null) { + var result = null; + switch (type) { + case TYPE_LIST_TABLES: + { + result = connector.getTableList(loggedInUser); + break; + } + /*case TYPE_CREATE_TABLE: + { + print(connector.createTable(tableName)); + break; + } + case TYPE_DELETE_TABLE: + { + print(connector.deleteTable(tableName)); + break; + } */ + case TYPE_TABLE_EXISTS: + { + result = connector.tableExists(loggedInUser, tableName); + break; + } + case TYPE_GET_BY_RANGE: + { + var from = request.getParameter(TIME_FROM); + if (from == 'undefined') from = JS_MIN_VALUE; + var to = request.getParameter(TIME_TO); + if (to == 'undefined') to = JS_MAX_VALUE; + var start = request.getParameter(START); + var intStart = ZERO_INDEX; + if (start != 'undefined' && start != null) { + intStart = parseInt(start, 10); + } + var count = request.getParameter(COUNT); + var intCount = LAST_INDEX; + if (count != 'undefined' && count != null) { + intCount = parseInt(count, 10); + } + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, intStart, intCount, contentAsString); + break; + } + case TYPE_GET_WITH_KEY_VALUES: + { + result = connector.getWithKeyValues(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_GET_BY_ID: + { + result = connector.getRecordsByIds(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_GET_RECORD_COUNT: + { + result = connector.getRecordCount(loggedInUser, tableName); + break; + } + /*case TYPE_DELETE_BY_RANGE: + { + var timeFrom = Long.parseLong(request.getParameter(TIME_FROM)); + var timeTo = Long.parseLong(request.getParameter(TIME_TO)); + print(connector.deleteRecordsByRange(tableName, timeFrom, timeTo)); + break; + } + case TYPE_DELETE_BY_ID: + { + print(connector.deleteRecordsByIds(tableName, contentAsString)); + break; + }*/ + case TYPE_CLEAR_INDEX_DATA: + { + result = connector.clearIndexData(loggedInUser, tableName); + break; + } + /*case TYPE_PUT_RECORDS: + { + print(connector.insertRecords(contentAsString)); + break; + }*/ + case TYPE_SEARCH_COUNT: + { + var queryString = request.getParameter(QUERY); + if (queryString == 'undefined' || queryString == null || queryString == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request" }'; + break; + }; + + contentAsString = "{query: " + queryString + "}"; + result = connector.searchCount(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_SEARCH: + { + var queryString = request.getParameter(QUERY); + if (queryString == 'undefined' || queryString == null || queryString == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request" }'; + break; + }; + + var count = request.getParameter(COUNT); + if (count == 'undefined' || count == null || count == '') { + count = DEFAULT_COUNT; + } + + contentAsString = "{query: " + queryString + ", count:" + count + "}"; + result = connector.search(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_SET_SCHEMA: + { + print(connector.setTableSchema(loggedInUser, tableName, contentAsString)); + break; + } + case TYPE_GET_SCHEMA: + { + result = connector.getTableSchema(loggedInUser, tableName); + break; + } + case TYPE_PAGINATION_SUPPORTED: + { + var recordStore = request.getParameter(RECORDSTORE_NAME) + result = connector.isPaginationSupported(recordStore); + break; + } + case TYPE_WAIT_FOR_INDEXING: + { + var waitTimeAsString = request.getParameter(WAIT_TIME); + var waitTime = -1; + if (waitTimeAsString != null) { + waitTime = parseInt(waitTimeAsString); + } + result = connector.waitForIndexing(waitTime * MILLISECONDS_PER_SECOND); + break; + } + case TYPE_WAIT_FOR_INDEXING_FOR_TABLE: + { + var waitTimeAsString = request.getParameter(WAIT_TIME); + var waitTime = -1; + if (waitTimeAsString != null) { + waitTime = parseInt(waitTimeAsString); + } + result = connector.waitForIndexing(tableName, waitTime * MILLISECONDS_PER_SECOND); + break; + } + case TYPE_DRILLDOWN_CATEGORIES: + { + result = connector.drillDownCategories(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_DRILLDOWN_SEARCH: + { + var queryString = request.getParameter(QUERY); + if (queryString == 'undefined' || queryString == null || queryString == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request. Query string not found." }'; + break; + }; + + var scoreFunction = request.getParameter(SORT_SCORE_VALUE); + if (scoreFunction == 'undefined' || scoreFunction == null || scoreFunction == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request. Score function not found." }'; + break; + }; + + var count = request.getParameter(COUNT); + if (count == 'undefined' || count == null || count == '') { + count = DEFAULT_COUNT; + } + + contentAsString = "{query: " + queryString + ", recordCount:"+ count +", scoreFunction:'"+ scoreFunction +"', categories: []}"; + result = connector.drillDownSearch(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_DRILLDOWN_SEARCH_COUNT: + { + result = connector.drillDownSearchCount(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_ADD_STREAM_DEFINITION: + { + result = connector.addStreamDefinition(contentAsString); + break; + } + case TYPE_GET_STREAM_DEFINITION: + { + result = connector.getStreamDefinition(contentAsString); + break; + } + case TYPE_PUBLISH_EVENTS: + { + result = connector.publishEvent(contentAsString); + break; + } + case TYPE_GET_RECORDSTORES: + { + result = connector.getRecordStoreList(); + break; + } + case TYPE_GET_RECORDSTORE_BY_TABLE: + { + result = connector.getRecordStoreByTable(loggedInUser, tableName); + break; + } + case TYPE_SEARCH_WITH_AGGREGATES: + { + result = connector.searchWithAggregates(loggedInUser, contentAsString); + break; + } + case TYPE_REINDEX: + { + var from = request.getParameter(TIME_FROM); + if (from == 'undefined') from = JS_MIN_VALUE; + var to = request.getParameter(TIME_TO); + if (to == 'undefined') to = JS_MAX_VALUE; + result = connector.reIndex(loggedInUser, tableName, from, to); + break; + } + default: + result = '{ "status": "Failed", "statusCode": "500", "message": "Unidentified operation" }'; + } + if (result != null) { + if (log.isDebugEnabled()) { + log.debug("value of result: " + result); + log.debug("status code: " + result.getstatusCode()) + } + + var statusCode = result.getStatusCode(); + var status = result.getStatus(); + var message = result.getMessage(); + response.status = statusCode; + var finalResult = { + status: status, + message: message + }; + print(finalResult); + } + } else { + print('{ "status": "Failed", "statusCode": "500", "message": "AnalyticsCachedWebServiceConnector is unavailable" }'); + } + +}()); +%> diff --git a/modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js b/modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js new file mode 100644 index 00000000..50f07a80 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js @@ -0,0 +1,286 @@ +/* + * + * + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +var CONSTANTS = { + webAppName: 'outputui', + urlSeperator: '/', + urlGetParameter : '?lastUpdatedTime=', + urlQueryStringBegin : '?', + tenantUrlAttribute: 't', + urlUnsecureTransportHttp : 'http://', + urlUnsecureTransportWebsocket : 'ws://', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultUserDomain : 'carbon.super', + defaultHostName : 'localhost', + defaultNonsecurePortNumber : '9763', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + domain : 'carbon.super', + numThousand : 1000, + websocketTimeAppender : 400, + secureMode : 'SECURED' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var userDomainUrl = ""; +var terminateWebsocketInstance = false; +var pollingContinue = true; +var transportToBeUsedHttp; +var transportToBeUsedWebsocket; + +function subscribe(streamName,version,intervalTime,domain, + listeningFuncSuccessData,listeningFuncErrorData, + cepHost,cepPort,mode,secureMode, queryParams){ + + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(secureMode == CONSTANTS.secureMode){ + transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket; + } else { + transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket; + } + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(domain == null || domain == ""){ + domain = CONSTANTS.defaultUserDomain; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + if(secureMode == CONSTANTS.secureMode){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = CONSTANTS.defaultNonsecurePortNumber; + } + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + if(domain != CONSTANTS.domain){ + userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator; + + } + + if (queryParams == null) { + queryParams = ""; + } else if (queryParams != "") { + queryParams = CONSTANTS.urlQueryStringBegin + queryParams; + } + + webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream + + CONSTANTS.urlSeperator + streamVersion + queryParams; + + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + // alert("Successfully connected to "+webSocketUrl); + //onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n"); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator + + CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator + + streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime; + + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;} +.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;} +input,textarea,.uneditable-input{margin-left:0;} +.controls-row [class*="span"]+[class*="span"]{margin-left:20px;} +input.span12, textarea.span12, .uneditable-input.span12{width:926px;} +input.span11, textarea.span11, .uneditable-input.span11{width:846px;} +input.span10, textarea.span10, .uneditable-input.span10{width:766px;} +input.span9, textarea.span9, .uneditable-input.span9{width:686px;} +input.span8, textarea.span8, .uneditable-input.span8{width:606px;} +input.span7, textarea.span7, .uneditable-input.span7{width:526px;} +input.span6, textarea.span6, .uneditable-input.span6{width:446px;} +input.span5, textarea.span5, .uneditable-input.span5{width:366px;} +input.span4, textarea.span4, .uneditable-input.span4{width:286px;} +input.span3, textarea.span3, .uneditable-input.span3{width:206px;} +input.span2, textarea.span2, .uneditable-input.span2{width:126px;} +input.span1, textarea.span1, .uneditable-input.span1{width:46px;} +.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;} +.controls-row:after{clear:both;} +.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;} +.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;} +input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;} +.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;} +.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;} +.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;} +.form-actions:after{clear:both;} +.help-block,.help-inline{color:#595959;} +.help-block{display:block;margin-bottom:10px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px;} +.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;} +.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;} +.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;} +.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .btn-group:first-child{margin-left:0;} +input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;} +.control-group{margin-bottom:10px;} +legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;} +.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;} +.form-horizontal .help-block{margin-bottom:0;} +.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;} +.form-horizontal .form-actions{padding-left:180px;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:2px;} +.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;} +.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.btn-block+.btn-block{margin-top:5px;} +input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn{border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);} +.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;} +.btn-primary:active,.btn-primary.active{background-color:#003399 \9;} +.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;} +.btn-link[disabled]:hover{color:#333333;text-decoration:none;} +.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px;} +.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group>.btn+.btn{margin-left:-1px;} +.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px;} +.btn-group>.btn-mini{font-size:11px;} +.btn-group>.btn-small{font-size:12px;} +.btn-group>.btn-large{font-size:16px;} +.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;} +.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;} +.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;} +.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;} +.btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;} +.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;} +.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;} +.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;} +.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;} +.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;} +.btn .caret{margin-top:8px;margin-left:0;} +.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px;} +.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;} +.dropup .btn-large .caret{border-bottom-width:5px;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;} +.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group-vertical .btn+.btn{margin-left:0;margin-top:-1px;} +.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;} +.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav{margin-left:0;margin-bottom:20px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav>.pull-right{float:right;} +.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px;} +.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .dropdown-toggle .caret{margin-top:8px;} +.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;} +.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.nav>.dropdown.active>a:hover{cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0;} +.tabbable:after{clear:both;} +.tab-content{overflow:auto;} +.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below>.nav-tabs{border-top:1px solid #ddd;} +.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;} +.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left>.nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right>.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.nav>.disabled>a{color:#999999;} +.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;} +.navbar{overflow:visible;margin-bottom:20px;color:#777777;*position:relative;*z-index:2;} +.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;} +.navbar-inner:after{clear:both;} +.navbar .container{width:auto;} +.nav-collapse.collapse{height:auto;overflow:visible;} +.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover{text-decoration:none;} +.navbar-text{margin-bottom:0;line-height:40px;} +.navbar-link{color:#777777;}.navbar-link:hover{color:#333333;} +.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;} +.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);} +.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;margin-right:0;} +.navbar .nav>li{float:left;} +.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;} +.navbar .nav .dropdown-toggle .caret{margin-top:8px;} +.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;} +.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);} +.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;} +.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;} +.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;} +.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;} +.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;} +.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.navbar-inverse{color:#999999;}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;} +.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#ffffff;} +.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;} +.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;} +.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;} +.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;} +.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;} +.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;} +.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#ccc;} +.breadcrumb .active{color:#999999;} +.pagination{margin:20px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination ul>li{display:inline;} +.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;} +.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;} +.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;} +.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px;} +.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;} +.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;} +.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px;} +.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:1px 6px;font-size:10.5px;} +.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager li>a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next>a,.pager .next>span{float:right;} +.pager .previous>a,.pager .previous>span{float:left;} +.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;} +.thumbnails:after{clear:both;} +.row-fluid .thumbnails{margin-left:0;} +.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;} +.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;color:#555555;} +.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert h4{margin:0;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);} +.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);} +.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);} +.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);} +.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit li{line-height:30px;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-3px;} +.tooltip.right{margin-left:3px;} +.tooltip.bottom{margin-top:3px;} +.tooltip.left{margin-left:-3px;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);}.popover.top{margin-top:-10px;} +.popover.right{margin-left:10px;} +.popover.bottom{margin-top:10px;} +.popover.left{margin-left:-10px;} +.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;} +.popover-content{padding:9px 14px;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid;} +.popover .arrow:after{content:"";z-index:-1;} +.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-width:10px 10px 0;border-top-color:#ffffff;}.popover.top .arrow:after{border-width:11px 11px 0;border-top-color:rgba(0, 0, 0, 0.25);bottom:-1px;left:-11px;} +.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-width:10px 10px 10px 0;border-right-color:#ffffff;}.popover.right .arrow:after{border-width:11px 11px 11px 0;border-right-color:rgba(0, 0, 0, 0.25);bottom:-11px;left:-1px;} +.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-width:0 10px 10px;border-bottom-color:#ffffff;}.popover.bottom .arrow:after{border-width:0 11px 11px;border-bottom-color:rgba(0, 0, 0, 0.25);top:-1px;left:-11px;} +.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-width:10px 0 10px 10px;border-left-color:#ffffff;}.popover.left .arrow:after{border-width:11px 0 11px 11px;border-left-color:rgba(0, 0, 0, 0.25);bottom:-11px;right:-1px;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-header h3{margin:0;line-height:30px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.modal-footer .btn-block+.btn-block{margin-left:0;} +.dropup,.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#ffffff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#333333;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999999;} +.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;cursor:default;} +.open{*z-index:1000;}.open >.dropdown-menu{display:block;} +.pull-right>.dropdown-menu{right:0;left:auto;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.dropdown-submenu{position:relative;} +.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;} +.dropdown-submenu:hover>.dropdown-menu{display:block;} +.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;} +.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;} +.dropdown-submenu:hover>a:after{border-left-color:#ffffff;} +.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion{margin-bottom:20px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-toggle{cursor:pointer;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:20px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;} +.carousel-caption h4{margin:0 0 5px;} +.carousel-caption p{margin-bottom:0;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);} +button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} +.affix{position:fixed;} +.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;} +.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;} +.hidden{display:none;visibility:hidden;} +.visible-phone{display:none !important;} +.visible-tablet{display:none !important;} +.hidden-desktop{display:none !important;} +.visible-desktop{display:inherit !important;} +@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*="offset"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12, textarea.span12, .uneditable-input.span12{width:710px;} input.span11, textarea.span11, .uneditable-input.span11{width:648px;} input.span10, textarea.span10, .uneditable-input.span10{width:586px;} input.span9, textarea.span9, .uneditable-input.span9{width:524px;} input.span8, textarea.span8, .uneditable-input.span8{width:462px;} input.span7, textarea.span7, .uneditable-input.span7{width:400px;} input.span6, textarea.span6, .uneditable-input.span6{width:338px;} input.span5, textarea.span5, .uneditable-input.span5{width:276px;} input.span4, textarea.span4, .uneditable-input.span4{width:214px;} input.span3, textarea.span3, .uneditable-input.span3{width:152px;} input.span2, textarea.span2, .uneditable-input.span2{width:90px;} input.span1, textarea.span1, .uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12, textarea.span12, .uneditable-input.span12{width:1156px;} input.span11, textarea.span11, .uneditable-input.span11{width:1056px;} input.span10, textarea.span10, .uneditable-input.span10{width:956px;} input.span9, textarea.span9, .uneditable-input.span9{width:856px;} input.span8, textarea.span8, .uneditable-input.span8{width:756px;} input.span7, textarea.span7, .uneditable-input.span7{width:656px;} input.span6, textarea.span6, .uneditable-input.span6{width:556px;} input.span5, textarea.span5, .uneditable-input.span5{width:456px;} input.span4, textarea.span4, .uneditable-input.span4{width:356px;} input.span3, textarea.span3, .uneditable-input.span3{width:256px;} input.span2, textarea.span2, .uneditable-input.span2{width:156px;} input.span1, textarea.span1, .uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}} diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css new file mode 100644 index 00000000..ff005b50 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css @@ -0,0 +1,29 @@ +/*! + * d3.geomap + * https://github.com/yaph/d3-geomap/blob/master/LICENSE + * MIT licensed + * Copyright (C) 2015 by Ramiro Gómez (http://ramiro.org/) + */ +text { + fill: #333; + font-size: 12px; } + +.background { + fill: none; + pointer-events: all; } + +.unit { + cursor: pointer; + fill: #ccc; + stroke: #000; + stroke-width: 0.4px; } + +.legend-bg { + fill: #fff; + fill-opacity: 0.8; } + +.legend-bar { + stroke: #333; + stroke-width: 1px; } + +/*# sourceMappingURL=geomap.css.map */ diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css new file mode 100644 index 00000000..0fa42f15 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css @@ -0,0 +1,80 @@ +#rect { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 2; +} + +#rectCurve { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 0.5; +} + +.axis path, +.axis line { + fill: none; + shape-rendering: crispEdges; + stroke: grey; + stroke-width: 2; +} + +.line { + fill: none; + stroke: steelblue; + stroke-width: 1.5px; +} + + +.label{ + font-size: 16.844px !important; +} + +/* arc tween shit*/ +.background { + fill: #FFFFFF; + fill-opacity: 0.01; +} + +.component { + fill: #e1e1e1; +} + +.component .label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.arc { + stroke-weight:0.1; + fill: #4e8fff; +} + + +.arc2 { + stroke-weight:0.1; + fill: #3660b0; +} + + +.label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; +} + +.labelArc { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.tooltipClass { + background-color: #e5f2ff; + padding: 4px 8px; + +} +.tooltipClass p{ + margin: 0; + padding: 0; + +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json new file mode 100644 index 00000000..3a0dea46 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json @@ -0,0 +1 @@ +{"id":"IoTServerTemperatureStats","title":"IoTServerTemperatureStats","type":"gadget","thumbnail":"local://images/gadgetIcon.png","data":{"url":"local://store/carbon.super/gadget/IoTServerTemperatureStats/index.xml"}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml new file mode 100644 index 00000000..9cc11d51 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + Bar Chart + + + + + + + + + + + + + + + + + +
+ + + + ]]> +
+
+ + diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js new file mode 100644 index 00000000..b7d10b77 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License./ + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function getPieMark(a,b){var c;if("donut"==a.mode)var c=a.width/5;else var c=0;var d={type:"arc",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},startAngle:{field:"layout_start"},endAngle:{field:"layout_end"},innerRadius:{value:c},outerRadius:{value:.4*a.width},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.8}}}};return d}function getPieText(a,b){var c={type:"text",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:.5*a.width},theta:{field:"layout_mid"},fill:{value:"#000"},align:{value:"center"},baseline:{value:"middle"},text:{field:b.names[a.x],mult:.5}}}};return c}function getAreaMark(a,b){var c={type:"area",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},strokeWidth:{value:2},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getBarMark(a,b){var c={type:"rect",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:"steelblue"},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getStackBarMark(a,b){var c={type:"rect",from:{data:"table",transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:"layout_start"},y2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getLineMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"line",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"line",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{value:a.markColor},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}}function getTopoJson(a,b){var c,d=a.width,e=a.height,f=a.charts[0].mapType,g="mercator";"usa"==f?(d=a.width-160,e=a.height-130,c=a.height+270,g="albersUsa"):"europe"==f?(d=(a.width/2+100)/2,e=a.height+150,c=a.height+50):(c=a.width/640*120,d=a.width/2+10,e=a.height/2+40);var h=a.geoCodesUrl,i={name:"geoData",url:h,format:{type:"topojson",feature:"units"},transform:[{type:"geopath",value:"data",scale:c,translate:[d,e],projection:g},{type:"lookup",keys:["id"],on:a.title,onKey:b.names[a.x],as:["zipped"],"default":{v:null,country:"No data"}}]};return i}function getMapMark(a,b){var c=[{name:"map",type:"path",from:{data:"geoData"},properties:{enter:{path:{field:"layout_path"}},update:{fill:{rule:[{predicate:{name:"isNotNull",id:{field:"zipped.v"}},scale:"color",field:"zipped.v"},{value:"grey"}]}},hover:{fill:{value:"#989898"}}}},{type:"group",from:{data:a.title,transform:[{type:"filter",test:"datum."+b.names[a.x]+" == tooltipSignal.datum."+b.names[a.x]}]},properties:{update:{x:{signal:"tooltipSignal.x",offset:-5},y:{signal:"tooltipSignal.y",offset:20},width:{value:a.toolTip.width},height:{value:a.toolTip.height},fill:{value:a.toolTip.color}}},marks:[{type:"text",properties:{update:{x:{value:6},y:{value:14},text:{template:"{{tooltipSignal.datum.unitName}} {{tooltipSignal.datum.v}}"},fill:{value:"black"}}}}]}];return c}function getMapSignals(){var a=[{name:"tooltipSignal",init:{expr:"{x: 0, y: 0, datum: {} }"},streams:[{type:"@map:mouseover",expr:"{x: eventX(), y: eventY(), datum: eventItem().datum.zipped}"},{type:"@map:mouseout",expr:"{x: 0, y: 0, datum: {} }"}]}];return a}function getMapPredicates(){var a={name:"isNotNull",type:"!=",operands:[{value:null},{arg:"id"}]};return a}function getMapLegends(a,b){var c={fill:"color",title:b.names[a.y],properties:{gradient:{stroke:{value:"transparent"}},title:{fontSize:{value:14}},legend:{x:{value:0},y:{value:a.height-40}}}};return c}function loadGeoMapCodes(a){var b,c=new XMLHttpRequest;return c.overrideMimeType("application/json"),c.open("GET",a,!1),c.onreadystatechange=function(){4==c.readyState&&"200"==c.status&&(b=JSON.parse(c.responseText))},c.send(null),b}function getMapCode(a,b,c){if("world"==b||"europe"==b)for(d=0;d"),$("#wrapper").append("
"),$tip=$("#tip"),$tip.empty();var i=g.datum,j="";for(var k in i)if(i.hasOwnProperty(k))if(void 0!=f){for(var l=0;l"+f[l]+" ("+k+"):"+i[k]+"

";break}}else e.names[d.x]==k&&(j+="

X ("+k+"):"+i[k]+"

"),e.names[d.y]==k&&(j+="

Y ("+k+"):"+i[k]+"

");$tip.append(j);var n=h.width,o=h.height,p=$('.marks[style*="width"]');p.length>0&&(n=parseFloat($(".marks")[0].style.width),o=parseFloat($(".marks")[0].style.height));var q,r=$tip.width(),s=$tip.height(),t=g.bounds.x2+d.padding.left+r,u=o-g.bounds.y2-d.padding.top+s,v=g.bounds.y2+d.padding.top-s;q=t>n?g.bounds.x2+d.padding.left-r:g.bounds.x2+d.padding.left,u>o&&(v=g.bounds.y2+d.padding.top),$tip.css({left:q,top:v}).show()}else $("#wrapper #tip").length&&$tip.remove(),$(a).closest("#wrapper").length&&$(a).unwrap()})}var arc=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title,a[0].transform=[{type:"pie",field:this.metadata.names[b.x]}];var d=[];null==b.colorDomain&&(b.colorDomain={data:b.title,field:this.metadata.names[b.color]});var e={name:"color",type:"ordinal",domain:b.colorDomain,range:b.colorScale};d.push(e),c.push(getPieMark(b,this.metadata)),c.push(getPieText(b,this.metadata));var f="Legend";"table"!=b.title&&(f=b.title);var g=[{fill:"color",title:"Legend",offset:20,properties:{symbols:{fillOpacity:{value:.5},stroke:{value:"transparent"}}}}];this.spec.legends=g,this.spec.width=b.width,this.spec.height=b.height,this.spec.data=a,this.spec.scales=d,this.spec.padding=b.padding,this.spec.marks=c};arc.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;i=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h

"+c+"

";document.getElementById(a).innerHTML=d,this.view=b},number.prototype.insert=function(a){document.getElementById(this.view).innerHTML=a[a.length-1][this.metadata.names[this.config.x]]};var scatter=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title;var d={name:"x",type:this.metadata.types[b.x],range:"width",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.x]}},e={name:"y",type:this.metadata.types[b.y],range:"height",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.y]}},f={name:"size",type:"linear",range:[0,576],domain:{data:b.title,field:this.metadata.names[b.size]}},g={name:"color",type:"linear",range:[b.minColor,b.maxColor],domain:{data:b.title,field:this.metadata.names[b.color]}},h=[d,e,f,g],i=[{type:"x",scale:"x",grid:b.grid,title:b.xTitle},{type:"y",scale:"y",grid:b.grid,title:b.yTitle}];c.push(getScatterMark(b,this.metadata)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=i,this.spec.data=a,this.spec.scales=h,this.spec.padding=b.padding,this.spec.marks=c};scatter.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),0!=this.config.tooltip&&bindTooltip(a,"symbol",this.view,this.config,this.metadata,["x","y","size"]),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(j=!0,g.splice(k,1)),j||g.splice(g.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var l,m=function(a){return a[b]==l};for(i=0;ib.maxLength){var k=d3.select("tbody").selectAll("tr").data().slice(d3.select("tbody").selectAll("tr").data().length-b.maxLength,b.maxLength);d3.select("tbody").selectAll("tr").data(k,function(a){return a}).remove()}}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/d3.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/d3.min.js new file mode 100644 index 00000000..e3ee0f91 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null===n?0/0:+n}function e(n){return!isNaN(n)}function r(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===da||n[0]===ma?ma+n:n}function l(n){return(n+="")[0]===ma?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=ya.length;r>e;++e){var u=ya[e]+t;if(u in n)return u}}function y(){}function M(){}function x(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function O(n){return xa(n,Aa),n}function Y(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var l=Ca.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++qa,t="click"+n,e=ta.select(oa).on("touchmove"+n,b).on("dragstart"+n,b).on("selectstart"+n,b);if(za){var r=ia.style,u=r[za];r[za]="none"}return function(i){if(e.on(n,null),za&&(r[za]=u),i){var o=function(){e.on(t,null)};e.on(t,function(){b(),o()},!0),setTimeout(o,0)}}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>La&&(oa.scrollX||oa.scrollY)){e=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();La=!(u.f||u.e),e.remove()}return La?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function B(){return ta.event.changedTouches[0].identifier}function W(){return ta.event.target}function J(){return oa}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Da:Math.acos(n)}function nt(n){return n>1?ja:-1>n?-ja:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):xt(""+n,bt,ot):new ot(n,t,e)}function at(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=_t((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=Fa)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):_t((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ja,r=gt(r)*Ga,i=gt(i)*Ka,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ha,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):xt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function Mt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function xt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(St(u[0]),St(u[1]),St(u[2]))}return(i=tc.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function bt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new ot(r,u,c)}function _t(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ja),u=pt((.2126729*n+.7151522*t+.072175*e)/Ga),i=pt((.0193339*n+.119192*t+.9503041*e)/Ka);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!oa.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(ic),ic=setTimeout(qt,t)),uc=0):(uc=1,ac(qt))}function Lt(){var n=Date.now();for(oc=ec;oc;)n>=oc.t&&(oc.f=oc.c(n-oc.t)),oc=oc.n;return n}function Tt(){for(var n,t=ec,e=1/0;t;)t.f?t=n?n.n=t.n:ec=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=lc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=sc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new hc(e-1)),1),e}function i(n,e){return t(n=new hc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{hc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{hc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{hc=jt;var r=new jt;return r._=t,n(r,e)._}finally{hc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in pc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{hc=jt;var t=new hc;return t._=n,r(t)}finally{hc=Date}}var r=t(n);return e.parse=function(n){try{hc=jt;var t=r.parse(n);return t&&t._}finally{hc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=It(v),b=Zt(v),_=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+fc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(fc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(fc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function It(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|va(t)/60,u=va(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){dc.lastIndex=0;var r=dc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);_c.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;wc.point=function(o,a){wc.point=n,r=(t=o)*Fa,u=Math.cos(a=(e=a)*Fa/2+Da/4),i=Math.sin(a)},wc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function be(n,t){return va(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-ja-Ta:ja-n[1])-((t=t.x)[0]<0?t[1]-ja-Ta:ja-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Da:-Da,c=va(i-e);va(c-Da)0?ja:-ja),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Da&&(va(e-u)Ta?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*ja,r.point(-Da,u),r.point(0,u),r.point(Da,u),r.point(Da,0),r.point(Da,-u),r.point(0,-u),r.point(-Da,-u),r.point(-Da,0),r.point(-Da,u);else if(va(n[0]-t[0])>Ta){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Da/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Da/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>Da,k=p*M;if(_c.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Pa:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*nt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ta>i||Ta>i&&0>_c)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Da:-Da),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ta,p[1]+=Ta,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=va(A-Da)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(va(b[0]-w)Da^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:Da-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=va(i)>Ta,c=gr(n,6*Fa);return Le(t,e,c,o?[0,-n]:[-Da,n-Da])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ye(n,t,e,r){function u(r,u){return va(r[0]-n)0?0:3:va(r[0]-e)0?2:1:va(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Uc,Math.min(Uc,n)),t=Math.max(-Uc,Math.min(Uc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ie(n){var t=0,e=Da/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Da/180,e=n[1]*Da/180):[180*(t/Da),180*(e/Da)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Fc+=u*n-r*t,r=n,u=t}var t,e,r,u;Zc.point=function(i,o){Zc.point=n,t=r=i,e=u=o},Zc.lineEnd=function(){n(t,e)}}function Xe(n,t){Hc>n&&(Hc=n),n>Yc&&(Yc=n),Oc>t&&(Oc=t),t>Ic&&(Ic=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){Ec+=n,Ac+=t,++Nc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Cc+=o*(t+n)/2,zc+=o*(e+r)/2,qc+=o,We(t=n,e=r)}var t,e;Xc.point=function(r,u){Xc.point=n,We(t=r,e=u)}}function Ge(){Xc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Cc+=o*(r+n)/2,zc+=o*(u+t)/2,qc+=o,o=u*n-r*t,Lc+=o*(r+n),Tc+=o*(u+t),Rc+=3*o,We(r=n,u=t)}var t,e,r,u;Xc.point=function(i,o){Xc.point=n,We(t=r=i,e=u=o)},Xc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Pa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=va(va(w)-1)i||va((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Fa),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ha,e*Ha])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Fa,n[1]*Fa),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ha,n[1]*Ha]}function r(){a=Ae(o=lr(m,y,M),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,M=0,x=Pc,b=Et,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(x(o,f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Pc):He((_=+n)*Fa),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?Ye(n[0][0],n[0][1],n[1][0],n[1][1]):Et,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Fa,d=n[1]%360*Fa,r()):[v*Ha,d*Ha]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Fa,y=n[1]%360*Fa,M=n.length>2?n[2]%360*Fa:0,r()):[m*Ha,y*Ha,M*Ha]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Fa,e*Fa)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Da?n-Pa:-Da>n?n+Pa:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Da?t-Pa:-Da>t?t+Pa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Pa)):(u=n+o*Pa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ta)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ha,Math.atan2(o,Math.sqrt(r*r+u*u))*Ha]}:function(){return[n*Ha,t*Ha]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Fa),o=Math.cos(u),a=va((n*=Fa)-t),c=Math.cos(a);$c+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Bc.point=function(u,i){t=u*Fa,e=Math.sin(i*=Fa),r=Math.cos(i),Bc.point=n},Bc.lineEnd=function(){Bc.point=Bc.lineEnd=y}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-ja+Ta>t&&(t=-ja+Ta):t>ja-Ta&&(t=ja-Ta);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Da/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-ja]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return va(u)u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=ol.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),rl.remove(n),ol.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&va(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=rl._;a;)if(r=Fr(a,o)-i,r>Ta)a=a.L;else{if(u=i-Hr(a,o),!(u>Ta)){r>-Ta?(t=a.P,e=a):u>-Ta?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(rl.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),rl.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=el,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(va(r-t)>Ta||va(u-e)>Ta)&&(a.splice(o,0,new Qr(Gr(i.site,s,va(r-f)Ta?{x:f,y:va(t-f)Ta?{x:va(e-p)Ta?{x:h,y:va(t-h)Ta?{x:va(e-g)=-Ra)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=al.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=il._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi||f>o||r>h||u>g)){if(p=n.point){var p,v=t-p[0],d=e-p[1],m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+Mt(Math.round(e+i*n))+Mt(Math.round(r+o*n))+Mt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=ll.lastIndex=sl.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=ll.exec(n))&&(r=sl.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=sl.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*ja)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Pa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Pa/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return at(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ft(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:bl}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Yu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Yi(n,t,e,r)},u()}function Ii(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=lc.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(va(r[0]),va(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in _l?Math.abs(e-Bi(Math.max(va(t[0]),va(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:Sl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return wl;arguments.length<2?t=wl:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Ii(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Ii(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++on?[0/0,0/0]:[n>0?a[n-1]:r[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,c)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=oc,v=[];return p.t=g+c,u>=g?a(u-g):(p.c=a,void 0)},0,c)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Wl,u);return i==Wl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Wl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Ii(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.3"};Date.now||(Date.now=function(){return+new Date});var ea=[].slice,ra=function(n){return ea.call(n)},ua=document,ia=ua.documentElement,oa=window;try{ra(ia.childNodes)[0].nodeType}catch(aa){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{ua.createElement("div").style.setProperty("opacity",0,"")}catch(ca){var la=oa.Element.prototype,sa=la.setAttribute,fa=la.setAttributeNS,ha=oa.CSSStyleDeclaration.prototype,ga=ha.setProperty;la.setAttribute=function(n,t){sa.call(this,n,t+"")},la.setAttributeNS=function(n,t,e){fa.call(this,n,t,e+"")},ha.setProperty=function(n,t,e){ga.call(this,n,t+"",e)}}ta.ascending=n,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var pa=r(n);ta.bisectLeft=pa.left,ta.bisect=ta.bisectRight=pa.right,ta.bisector=function(t){return r(1===t.length?function(e,r){return n(t(e),r)}:t)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=0|Math.random()*i--,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,u),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var va=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,u=[],o=i(va(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(Ma,"\\$&")};var Ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,xa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ba=function(n,t){return t.querySelector(n)},_a=function(n,t){return t.querySelectorAll(n)},wa=ia.matches||ia[m(ia,"matchesSelector")],Sa=function(n,t){return wa.call(n,t)};"function"==typeof Sizzle&&(ba=function(n,t){return Sizzle(n,t)[0]||null},_a=Sizzle,Sa=Sizzle.matchesSelector),ta.selection=function(){return Na};var ka=ta.selection.prototype=[];ka.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),Ea.hasOwnProperty(e)?{space:Ea[e],local:n}:n}},ka.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ka.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(T(e,n[e],t));return this}if(2>r)return oa.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(T(n,t,e))},ka.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ka.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},ka.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},ka.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ka.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ka.remove=function(){return this.each(P)},ka.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++rr;++r)p[r]=U(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return S(u)},ka.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},ka.sort=function(n){n=F.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},ka.size=function(){var n=0;return H(this,function(){++n}),n};var Aa=[];ta.selection.enter=O,ta.selection.enter.prototype=Aa,Aa.append=ka.append,Aa.empty=ka.empty,Aa.node=ka.node,Aa.call=ka.call,Aa.size=ka.size,Aa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var Ca=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ca.forEach(function(n){"on"+n in ua&&Ca.remove(n)});var za="onselectstart"in ua?null:m(ia.style,"userSelect"),qa=0;ta.mouse=function(n){return $(n,_())};var La=/WebKit/.test(oa.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=_().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(u()).on(i+d,a).on(o+d,c),y=X(),M=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,ta.mouse,J,"mousemove","mouseup"),i=t(B,ta.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},ta.rebind(n,e,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=_().touches),t?ra(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ta=1e-6,Ra=Ta*Ta,Da=Math.PI,Pa=2*Da,Ua=Pa-Ta,ja=Da/2,Fa=Da/180,Ha=180/Da,Oa=Math.SQRT2,Ya=2,Ia=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ya*h)*(e*rt(Oa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(Oa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Oa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Ia*f)/(2*i*Ya*h),p=(c*c-i*i-Ia*f)/(2*c*Ya*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Oa;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(z,s).on(Xa+".zoom",h).on("dblclick.zoom",g).on(T,f)}function t(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function e(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function r(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=e(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function i(t,e,i,o){t.__chart__={x:k.x,y:k.y,k:k.k},r(Math.pow(2,o)),u(v=e,i),t=ta.select(t),N>0&&(t=t.transition().duration(N)),t.call(n.event)}function o(){x&&x.domain(M.range().map(function(n){return(n-k.x)/k.k}).map(M.invert)),S&&S.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function a(n){C++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function l(n){--C||n({type:"zoomend"}),v=null}function s(){function n(){s=1,u(ta.mouse(r),h),c(o)}function e(){f.on(q,null).on(L,null),g(s&&ta.event.target===i),l(o)}var r=this,i=ta.event.target,o=R.of(r,arguments),s=0,f=ta.select(oa).on(q,n).on(L,e),h=t(ta.mouse(r)),g=X();Fl.call(r),a(o)}function f(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=t(n))}),n}function e(){var t=ta.event.target;ta.select(t).on(x,o).on(_,h),w.push(t);for(var e=ta.event.changedTouches,r=0,u=e.length;u>r;++r)d[e[r].identifier]=null;var a=n(),c=Date.now();if(1===a.length){if(500>c-y){var l=a[0];i(p,l,d[l.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),b()}y=c}else if(a.length>1){var l=a[0],s=a[1],f=l[0]-s[0],g=l[1]-s[1];m=f*f+g*g}}function o(){var n,t,e,i,o=ta.touches(p);Fl.call(p);for(var a=0,l=o.length;l>a;++a,i=null)if(e=o[a],i=d[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}y=null,u(n,t),c(v)}function h(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(w).on(M,null),S.on(z,s).on(T,f),E(),l(v)}var g,p=this,v=R.of(p,arguments),d={},m=0,M=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+M,_="touchend"+M,w=[],S=ta.select(p),E=X();e(),a(v),S.on(z,null).on(T,e)}function h(){var n=R.of(this,arguments);m?clearTimeout(m):(p=t(v=d||ta.mouse(this)),Fl.call(this),a(n)),m=setTimeout(function(){m=null,l(n)},50),b(),r(Math.pow(2,.002*Za())*k.k),u(v,p),c(n)}function g(){var n=ta.mouse(this),e=Math.log(k.k)/Math.LN2;i(this,n,t(n),ta.event.shiftKey?Math.ceil(e)-1:Math.floor(e)+1)}var p,v,d,m,y,M,x,_,S,k={x:0,y:0,k:1},E=[960,500],A=Va,N=250,C=0,z="mousedown.zoom",q="mousemove.zoom",L="mouseup.zoom",T="touchstart.zoom",R=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=R.of(this,arguments),t=k;Ul?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},a(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=v?v[0]:e/2,i=v?v[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){l(n)}).each("end.zoom",function(){l(n)}):(this.__chart__=k,a(n),c(n),l(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Va:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(d=t&&[+t[0],+t[1]],n):d},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(N=+t,n):N},n.x=function(t){return arguments.length?(x=t,M=t.copy(),k={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(S=t,_=t.copy(),k={x:0,y:0,k:1},n):S},ta.rebind(n,R,"on")};var Za,Va=[0,1/0],Xa="onwheel"in ua?(Za=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Za=function(){return ta.event.wheelDelta},"mousewheel"):(Za=function(){return-ta.event.detail},"MozMousePixelScroll");ta.color=it,it.prototype.toString=function(){return this.rgb()+""},ta.hsl=ot;var $a=ot.prototype=new it;$a.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},$a.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},$a.rgb=function(){return at(this.h,this.s,this.l)},ta.hcl=ct;var Ba=ct.prototype=new it;Ba.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Wa*(arguments.length?n:1)))},Ba.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Wa*(arguments.length?n:1)))},Ba.rgb=function(){return lt(this.h,this.c,this.l).rgb()},ta.lab=st;var Wa=18,Ja=.95047,Ga=1,Ka=1.08883,Qa=st.prototype=new it;Qa.brighter=function(n){return new st(Math.min(100,this.l+Wa*(arguments.length?n:1)),this.a,this.b)},Qa.darker=function(n){return new st(Math.max(0,this.l-Wa*(arguments.length?n:1)),this.a,this.b)},Qa.rgb=function(){return ft(this.l,this.a,this.b)},ta.rgb=dt;var nc=dt.prototype=new it;nc.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},nc.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},nc.hsl=function(){return bt(this.r,this.g,this.b)},nc.toString=function(){return"#"+Mt(this.r)+Mt(this.g)+Mt(this.b)};var tc=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});tc.forEach(function(n,t){tc.set(n,mt(t))}),ta.functor=kt,ta.xhr=At(Et),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new v,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var ec,rc,uc,ic,oc,ac=oa[m(oa,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};rc?rc.n=i:ec=i,rc=i,uc||(ic=clearTimeout(ic),uc=1,ac(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var cc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),cc[8+e/3]};var lc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,sc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),fc=ta.time={},hc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){gc.setUTCDate.apply(this._,arguments)},setDay:function(){gc.setUTCDay.apply(this._,arguments)},setFullYear:function(){gc.setUTCFullYear.apply(this._,arguments)},setHours:function(){gc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){gc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){gc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){gc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){gc.setUTCSeconds.apply(this._,arguments)},setTime:function(){gc.setTime.apply(this._,arguments)}};var gc=Date.prototype;fc.year=Ft(function(n){return n=fc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),fc.years=fc.year.range,fc.years.utc=fc.year.utc.range,fc.day=Ft(function(n){var t=new hc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),fc.days=fc.day.range,fc.days.utc=fc.day.utc.range,fc.dayOfYear=function(n){var t=fc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=fc[n]=Ft(function(n){return(n=fc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});fc[n+"s"]=e.range,fc[n+"s"].utc=e.utc.range,fc[n+"OfYear"]=function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)}}),fc.week=fc.sunday,fc.weeks=fc.sunday.range,fc.weeks.utc=fc.sunday.utc.range,fc.weekOfYear=fc.sundayOfYear;var pc={"-":"",_:" ",0:"0"},vc=/^\s*\d+/,dc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var mc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=mc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,yc),le(yc.s,this.s,this),this.s?this.t+=yc.t:this.s=yc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var yc=new ce;ta.geo.stream=function(n,t){n&&Mc.hasOwnProperty(n.type)?Mc[n.type](n,t):se(n,t)};var Mc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Da+n:n,wc.lineStart=wc.lineEnd=wc.point=y}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Fa,e*Fa]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ha*l,d=va(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ha;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ha;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=va(r)>180?r+(r>0?360:-360):r}else v=n,d=e;wc.point(n,e),t(n,e)}function i(){wc.lineStart()}function o(){u(v,d),wc.lineEnd(),va(y)>Ta&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n_c?(s=-(h=180),f=-(g=90)):y>Ta?g=90:-Ta>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){Sc=kc=Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,Dc);var t=Lc,e=Tc,r=Rc,u=t*t+e*e+r*r;return Ra>u&&(t=Cc,e=zc,r=qc,Ta>kc&&(t=Ec,e=Ac,r=Nc),u=t*t+e*e+r*r,Ra>u)?[0/0,0/0]:[Math.atan2(e,t)*Ha,nt(r/Math.sqrt(u))*Ha]};var Sc,kc,Ec,Ac,Nc,Cc,zc,qc,Lc,Tc,Rc,Dc={sphere:y,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){Dc.lineStart=Ee},polygonEnd:function(){Dc.lineStart=Se}},Pc=Le(Ne,Pe,je,[-Da,-Da/2]),Uc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ye(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ta,f+.12*l+Ta],[s-.214*l-Ta,f+.234*l-Ta]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ta,f+.166*l+Ta],[s-.115*l-Ta,f+.234*l-Ta]]).stream(c).point,n},n.scale(1070)};var jc,Fc,Hc,Oc,Yc,Ic,Zc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Fc=0,Zc.lineStart=Ve},polygonEnd:function(){Zc.lineStart=Zc.lineEnd=Zc.point=y,jc+=va(Fc/2)}},Vc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},Xc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Xc.lineStart=Ke},polygonEnd:function(){Xc.point=We,Xc.lineStart=Je,Xc.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return jc=0,ta.geo.stream(n,u(Zc)),jc},n.centroid=function(n){return Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,u(Xc)),Rc?[Lc/Rc,Tc/Rc]:qc?[Cc/qc,zc/qc]:Nc?[Ec/Nc,Ac/Nc]:[0/0,0/0]},n.bounds=function(n){return Yc=Ic=-(Hc=Oc=1/0),ta.geo.stream(n,u(Vc)),[[Hc,Oc],[Yc,Ic]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t}return n=lr(n[0]%360*Fa,n[1]*Fa,n.length>2?n[2]*Fa:0),t.invert=function(t){return t=n.invert(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Fa,-n[1]*Fa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ha,n[1]*=Ha}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Fa,u*Fa),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Fa,(u=+r)*Fa),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Fa,u=n[1]*Fa,i=t[1]*Fa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return va(n%d)>Ta}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return va(n%m)>Ta}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ta],[180,90-Ta]]).minorExtent([[-180,-80-Ta],[180,80+Ta]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Fa,n[1]*Fa,t[0]*Fa,t[1]*Fa)},ta.geo.length=function(n){return $c=0,ta.geo.stream(n,Bc),$c};var $c,Bc={sphere:y,point:y,lineStart:xr,lineEnd:y,polygonStart:y,polygonEnd:y},Wc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Wc)}).raw=Wc;var Jc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(ta.geo.azimuthalEquidistant=function(){return ur(Jc)}).raw=Jc,(ta.geo.conicConformal=function(){return Ie(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Gc=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur(Gc)}).raw=Gc,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-ja]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Kc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Kc)}).raw=Kc;var Qc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Qc)}).raw=Qc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-ja]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ta)*Ta,y:Math.round(o(n,t)/Ta)*Ta,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=cl;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=kt(a),x=kt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=hl.get(e)||fl,r=gl.get(r)||Et,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:pl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var pl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=vl,h=dl,g=-30,p=ml,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,M,x,b=m.length,_=y.length;for(e=0;_>e;++e)a=y[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(p=M*M+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,M*=p,x*=p,h.x-=M*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=M*(d=1-d),f.y+=x*d);if((d=r*v)&&(M=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;l>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(Et).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?(this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e),void 0):e},ta.rebind(a,c,"on")};var vl=20,dl=1,ml=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===yl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=yl,r=0,u=Pa,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var yl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Ml.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:xl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var Ml=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),xl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var bl={floor:Et,ceil:Et};ta.scale.linear=function(){return Yi([0,1],[0,1],mu,!1)};var _l={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var wl=ta.format(".0e"),Sl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(kl)},ta.scale.category20=function(){return ta.scale.ordinal().range(El)},ta.scale.category20b=function(){return ta.scale.ordinal().range(Al)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Nl)};var kl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),El=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),Al=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Nl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-ja,f=a.apply(this,arguments)-ja,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ua)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===Cl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=nt(d/l*Math.sin(m))),n&&(E=nt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=Da?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=Da?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),Y=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],Y[1][0],Y[1][1]),",",g," ",Y[1],"A",H,",",H," 0 0,",v," ",Y[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",Y[0])}else N.push("M",y,",",M);if(null!=S){var I=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-I,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-I,g);p===I?N.push("L",V[0],"A",I,",",I," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",I,",",I," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",I,",",I," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=Cl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.outerRadius=function(t){return arguments.length?(r=kt(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=kt(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==Cl?Cl:kt(t),n):i},n.startAngle=function(t){return arguments.length?(o=kt(t),n):o},n.endAngle=function(t){return arguments.length?(a=kt(t),n):a},n.padAngle=function(t){return arguments.length?(c=kt(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-ja;return[Math.cos(t)*n,Math.sin(t)*n]},n};var Cl="auto";ta.svg.line=function(){return ho(Et)};var zl=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});zl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var ql=[0,2/3,1/3,0],Ll=[0,1/3,2/3,0],Tl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(Et)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-ja,s=l.call(n,u,r)-ja;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Da)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(Rl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Rl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Pl)),e=t*Pl;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=Rl.keys();var Dl=Math.sqrt(3),Pl=Math.tan(30*Fa);ka.transition=function(n){for(var t,e,r=Ul||++Ol,u=Xo(n),i=[],o=jl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Io(u,this.namespace,this.id)},Hl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):H(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Hl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Hl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Hl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=oa.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=mu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Zo(this,"style."+n,t,u)},Hl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,oa.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Hl.text=function(n){return Zo(this,"text",n,Vo)},Hl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Hl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),H(this,function(r){r[e][t].ease=n}))},Hl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:H(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Hl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:H(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Hl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=jl,i=Ul;try{Ul=e,H(this,function(t,u,i){jl=t[r][e],n.call(t,t.__data__,u,i)})}finally{jl=u,Ul=i}}else H(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Hl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ol,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Io(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ta),d=ta.transition(p.exit()).style("opacity",Ta).remove(),m=ta.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,M=Ui(f),x=l.selectAll(".domain").data([0]),b=(x.enter().append("path").attr("class","domain"),ta.transition(x));v.append("line"),v.append("text");var _,w,S,k,E=v.select("line"),A=m.select("line"),N=p.select("text").text(g),C=v.select("text"),z=m.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,_="x",S="y",w="x2",k="y2",N.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),b.attr("d","M"+M[0]+","+q*i+"V0H"+M[1]+"V"+q*i)):(n=Wo,_="y",S="x",w="y2",k="x2",N.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),b.attr("d","M"+q*i+","+M[0]+"H0V"+M[1]+"H"+q*i)),E.attr(k,q*u),C.attr(S,q*y),A.attr(w,0).attr(k,q*u),z.attr(_,0).attr(S,q*y),f.rangeBand){var L=f,T=L.rangeBand()/2;s=f=function(n){return L(n)+T}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=Yl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Il?t+"":Yl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Yl="bottom",Il={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(i){i.each(function(){var i=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Zl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=ta.transition(i),h=ta.transition(o);c&&(s=Ui(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Ui(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==ta.event.keyCode&&(N||(y=null,z[0]-=s[1],z[1]-=f[1],N=2),b())}function p(){32==ta.event.keyCode&&2==N&&(z[0]+=s[1],z[1]+=f[1],N=0,b())}function v(){var n=ta.mouse(x),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),N||(ta.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),C(),w({type:"brushend"})}var y,M,x=this,_=ta.select(ta.event.target),w=a.of(x,arguments),S=ta.select(x),k=_.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,N=_.classed("extent"),C=X(),z=ta.mouse(x),q=ta.select(oa).on("keydown.brush",u).on("keyup.brush",p);if(ta.event.changedTouches?q.on("touchmove.brush",v).on("touchend.brush",m):q.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),N)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var L=+/w$/.test(k),T=+/^n/.test(k);M=[s[1-L]-z[0],f[1-T]-z[1]],z[0]=s[L],z[1]=f[T]}else ta.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Vl[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ul?ta.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(s,t.x),r=yu(f,t.y);return i=o=null,function(u){s=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Vl[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Vl[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},ta.rebind(n,a,"on")};var Zl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Vl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Xl=fc.format=mc.timeFormat,$l=Xl.utc,Bl=$l("%Y-%m-%dT%H:%M:%S.%LZ");Xl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Bl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Bl.toString,fc.second=Ft(function(n){return new hc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),fc.seconds=fc.second.range,fc.seconds.utc=fc.second.utc.range,fc.minute=Ft(function(n){return new hc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),fc.minutes=fc.minute.range,fc.minutes.utc=fc.minute.utc.range,fc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new hc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),fc.hours=fc.hour.range,fc.hours.utc=fc.hour.utc.range,fc.month=Ft(function(n){return n=fc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),fc.months=fc.month.range,fc.months.utc=fc.month.utc.range;var Wl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Jl=[[fc.second,1],[fc.second,5],[fc.second,15],[fc.second,30],[fc.minute,1],[fc.minute,5],[fc.minute,15],[fc.minute,30],[fc.hour,1],[fc.hour,3],[fc.hour,6],[fc.hour,12],[fc.day,1],[fc.day,2],[fc.week,1],[fc.month,1],[fc.month,3],[fc.year,1]],Gl=Xl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Kl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:Et,ceil:Et};Jl.year=fc.year,fc.scale=function(){return Go(ta.scale.linear(),Jl,Gl)};var Ql=Jl.map(function(n){return[n[0].utc,n[1]]}),ns=$l.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Ql.year=fc.year.utc,fc.scale.utc=function(){return Go(ta.scale.linear(),Ql,ns)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js new file mode 100644 index 00000000..2a5250fb --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js @@ -0,0 +1,48 @@ +if(navigator.appVersion.indexOf("MSIE")!=-1&&parseFloat(navigator.appVersion.split("MSIE")[1])<=8&&!document.createElement("canvas").getContext)(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var abs=m.abs;var sqrt=m.sqrt;var Z=10;var Z2=Z/2;var IE_VERSION=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function getContext(){return this.context_||(this.context_=new CanvasRenderingContext2D_(this))}var slice=Array.prototype.slice;function bind(f,obj,var_args){var a=slice.call(arguments, +2);return function(){return f.apply(obj,a.concat(slice.call(arguments)))}}function encodeHtmlAttribute(s){return String(s).replace(/&/g,"&").replace(/"/g,""")}function addNamespace(doc,prefix,urn){if(!doc.namespaces[prefix])doc.namespaces.add(prefix,urn,"#default#VML")}function addNamespacesAndStylesheet(doc){addNamespace(doc,"g_vml_","urn:schemas-microsoft-com:vml");addNamespace(doc,"g_o_","urn:schemas-microsoft-com:office:office");if(!doc.styleSheets["ex_canvas_"]){var ss=doc.createStyleSheet(); +ss.owningElement.id="ex_canvas_";ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"}}addNamespacesAndStylesheet(document);var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;doc.createElement("canvas");doc.attachEvent("onreadystatechange",bind(this.init_,this,doc))},init_:function(doc){var els=doc.getElementsByTagName("canvas");for(var i=0;i1)h--;if(6*h<1)return m1+(m2-m1)*6*h;else if(2*h<1)return m2;else if(3*h<2)return m1+(m2-m1)*(2/3-h)*6;else return m1}var processStyleCache={};function processStyle(styleString){if(styleString in processStyleCache)return processStyleCache[styleString];var str,alpha=1;styleString=String(styleString);if(styleString.charAt(0)=="#")str=styleString;else if(/^rgb/.test(styleString)){var parts= +getRgbHslContent(styleString);var str="#",n;for(var i=0;i<3;i++){if(parts[i].indexOf("%")!=-1)n=Math.floor(percent(parts[i])*255);else n=+parts[i];str+=decToHex[clamp(n,0,255)]}alpha=+parts[3]}else if(/^hsl/.test(styleString)){var parts=getRgbHslContent(styleString);str=hslToRgb(parts);alpha=parts[3]}else str=colorData[styleString]||styleString;return processStyleCache[styleString]={color:str,alpha:alpha}}var DEFAULT_STYLE={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"}; +var fontStyleCache={};function processFontStyle(styleString){if(fontStyleCache[styleString])return fontStyleCache[styleString];var el=document.createElement("div");var style=el.style;try{style.font=styleString}catch(ex){}return fontStyleCache[styleString]={style:style.fontStyle||DEFAULT_STYLE.style,variant:style.fontVariant||DEFAULT_STYLE.variant,weight:style.fontWeight||DEFAULT_STYLE.weight,size:style.fontSize||DEFAULT_STYLE.size,family:style.fontFamily||DEFAULT_STYLE.family}}function getComputedStyle(style, +element){var computedStyle={};for(var p in style)computedStyle[p]=style[p];var canvasFontSize=parseFloat(element.currentStyle.fontSize),fontSize=parseFloat(style.size);if(typeof style.size=="number")computedStyle.size=style.size;else if(style.size.indexOf("px")!=-1)computedStyle.size=fontSize;else if(style.size.indexOf("em")!=-1)computedStyle.size=canvasFontSize*fontSize;else if(style.size.indexOf("%")!=-1)computedStyle.size=canvasFontSize/100*fontSize;else if(style.size.indexOf("pt")!=-1)computedStyle.size= +fontSize/0.75;else computedStyle.size=canvasFontSize;computedStyle.size*=0.981;return computedStyle}function buildStyle(style){return style.style+" "+style.variant+" "+style.weight+" "+style.size+"px "+style.family}var lineCapMap={"butt":"flat","round":"round"};function processLineCap(lineCap){return lineCapMap[lineCap]||"square"}function CanvasRenderingContext2D_(canvasElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle= +"#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=canvasElement;var cssText="width:"+canvasElement.clientWidth+"px;height:"+canvasElement.clientHeight+"px;overflow:hidden;position:absolute";var el=canvasElement.ownerDocument.createElement("div");el.style.cssText=cssText;canvasElement.appendChild(el);var overlayEl=el.cloneNode(false);overlayEl.style.backgroundColor= +"red";overlayEl.style.filter="alpha(opacity=0)";canvasElement.appendChild(overlayEl);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"moveTo", +x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.lineTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"lineTo",x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){var p=getCoords(this,aX,aY);var cp1=getCoords(this,aCP1x,aCP1y);var cp2=getCoords(this,aCP2x,aCP2y);bezierCurveTo(this,cp1,cp2,p)};function bezierCurveTo(self,cp1,cp2,p){self.currentPath_.push({type:"bezierCurveTo",cp1x:cp1.x, +cp1y:cp1.y,cp2x:cp2.x,cp2y:cp2.y,x:p.x,y:p.y});self.currentX_=p.x;self.currentY_=p.y}contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp=getCoords(this,aCPx,aCPy);var p=getCoords(this,aX,aY);var cp1={x:this.currentX_+2/3*(cp.x-this.currentX_),y:this.currentY_+2/3*(cp.y-this.currentY_)};var cp2={x:cp1.x+(p.x-this.currentX_)/3,y:cp1.y+(p.y-this.currentY_)/3};bezierCurveTo(this,cp1,cp2,p)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType= +aClockwise?"at":"wa";var xStart=aX+mc(aStartAngle)*aRadius-Z2;var yStart=aY+ms(aStartAngle)*aRadius-Z2;var xEnd=aX+mc(aEndAngle)*aRadius-Z2;var yEnd=aY+ms(aEndAngle)*aRadius-Z2;if(xStart==xEnd&&!aClockwise)xStart+=0.125;var p=getCoords(this,aX,aY);var pStart=getCoords(this,xStart,yStart);var pEnd=getCoords(this,xEnd,yEnd);this.currentPath_.push({type:arcType,x:p.x,y:p.y,radius:aRadius,xStart:pStart.x,yStart:pStart.y,xEnd:pEnd.x,yEnd:pEnd.y})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX, +aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke();this.currentPath_=oldPath};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY); +this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill();this.currentPath_=oldPath};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");gradient.x0_=aX0;gradient.y0_=aY0;gradient.x1_=aX1;gradient.y1_=aY1;return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.x0_=aX0;gradient.y0_=aY0;gradient.r0_= +aR0;gradient.x1_=aX1;gradient.y1_=aY1;gradient.r1_=aR1;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width="auto";image.runtimeStyle.height="auto";var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w; +sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else throw Error("Invalid number of arguments");var d=getCoords(this,dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var W= +10;var H=10;var chunkSize=5E3;var min={x:null,y:null};var max={x:null,y:null};for(var j=0;jmax.x)max.x=p.x;if(min.y==null||p.ymax.y)max.y=p.y}}lineStr.push(' ">');if(!aFill)appendStroke(this,lineStr);else appendFill(this,lineStr,min,max);lineStr.push("");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))}};function appendStroke(ctx, +lineStr){var a=processStyle(ctx.strokeStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;var lineWidth=ctx.lineScale_*ctx.lineWidth;if(lineWidth<1)opacity*=lineWidth;lineStr.push("')}function appendFill(ctx,lineStr,min,max){var fillStyle=ctx.fillStyle;var arcScaleX=ctx.arcScaleX_;var arcScaleY= +ctx.arcScaleY_;var width=max.x-min.x;var height=max.y-min.y;if(fillStyle instanceof CanvasGradient_){var angle=0;var focus={x:0,y:0};var shift=0;var expansion=1;if(fillStyle.type_=="gradient"){var x0=fillStyle.x0_/arcScaleX;var y0=fillStyle.y0_/arcScaleY;var x1=fillStyle.x1_/arcScaleX;var y1=fillStyle.y1_/arcScaleY;var p0=getCoords(ctx,x0,y0);var p1=getCoords(ctx,x1,y1);var dx=p1.x-p0.x;var dy=p1.y-p0.y;angle=Math.atan2(dx,dy)*180/Math.PI;if(angle<0)angle+=360;if(angle<1E-6)angle=0}else{var p0=getCoords(ctx, +fillStyle.x0_,fillStyle.y0_);focus={x:(p0.x-min.x)/width,y:(p0.y-min.y)/height};width/=arcScaleX*Z;height/=arcScaleY*Z;var dimension=m.max(width,height);shift=2*fillStyle.r0_/dimension;expansion=2*fillStyle.r1_/dimension-shift}var stops=fillStyle.colors_;stops.sort(function(cs1,cs2){return cs1.offset-cs2.offset});var length=stops.length;var color1=stops[0].color;var color2=stops[length-1].color;var opacity1=stops[0].alpha*ctx.globalAlpha;var opacity2=stops[length-1].alpha*ctx.globalAlpha;var colors= +[];for(var i=0;i')}else if(fillStyle instanceof CanvasPattern_){if(width&&height){var deltaLeft=-min.x;var deltaTop=-min.y;lineStr.push("')}}else{var a=processStyle(ctx.fillStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;lineStr.push('')}}contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};function getCoords(ctx,aX,aY){var m=ctx.m_;return{x:Z*(aX*m[0][0]+ +aY*m[1][0]+m[2][0])-Z2,y:Z*(aX*m[0][1]+aY*m[1][1]+m[2][1])-Z2}}contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){if(this.aStack_.length){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function matrixIsFinite(m){return isFinite(m[0][0])&&isFinite(m[0][1])&&isFinite(m[1][0])&&isFinite(m[1][1])&&isFinite(m[2][0])&&isFinite(m[2][1])}function setM(ctx, +m,updateLineScale){if(!matrixIsFinite(m))return;ctx.m_=m;if(updateLineScale){var det=m[0][0]*m[1][1]-m[0][1]*m[1][0];ctx.lineScale_=sqrt(abs(det))}}contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1= +[[aX,0,0],[0,aY,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.transform=function(m11,m12,m21,m22,dx,dy){var m1=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.setTransform=function(m11,m12,m21,m22,dx,dy){var m=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,m,true)};contextPrototype.drawText_=function(text,x,y,maxWidth,stroke){var m=this.m_,delta=1E3,left=0,right=delta,offset={x:0,y:0},lineStr=[];var fontStyle=getComputedStyle(processFontStyle(this.font), +this.element_);var fontStyleString=buildStyle(fontStyle);var elementStyle=this.element_.currentStyle;var textAlign=this.textAlign.toLowerCase();switch(textAlign){case "left":case "center":case "right":break;case "end":textAlign=elementStyle.direction=="ltr"?"right":"left";break;case "start":textAlign=elementStyle.direction=="rtl"?"right":"left";break;default:textAlign="left"}switch(this.textBaseline){case "hanging":case "top":offset.y=fontStyle.size/1.75;break;case "middle":break;default:case null:case "alphabetic":case "ideographic":case "bottom":offset.y= +-fontStyle.size/2.25;break}switch(textAlign){case "right":left=delta;right=0.05;break;case "center":left=right=delta/2;break}var d=getCoords(this,x+offset.x,y+offset.y);lineStr.push('');if(stroke)appendStroke(this,lineStr);else appendFill(this,lineStr,{x:-left,y:0},{x:right,y:fontStyle.size});var skewM=m[0][0].toFixed(3)+ +","+m[1][0].toFixed(3)+","+m[0][1].toFixed(3)+","+m[1][1].toFixed(3)+",0,0";var skewOffset=mr(d.x/Z)+","+mr(d.y/Z);lineStr.push('','','');this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fillText= +function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,false)};contextPrototype.strokeText=function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,true)};contextPrototype.measureText=function(text){if(!this.textMeasureEl_){var s='';this.element_.insertAdjacentHTML("beforeEnd",s);this.textMeasureEl_=this.element_.lastChild}var doc=this.element_.ownerDocument;this.textMeasureEl_.innerHTML= +"";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(doc.createTextNode(text));return{width:this.textMeasureEl_.offsetWidth}};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(image,repetition){return new CanvasPattern_(image,repetition)};function CanvasGradient_(aType){this.type_=aType;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}CanvasGradient_.prototype.addColorStop=function(aOffset, +aColor){aColor=processStyle(aColor);this.colors_.push({offset:aOffset,color:aColor.color,alpha:aColor.alpha})};function CanvasPattern_(image,repetition){assertImageIsValid(image);switch(repetition){case "repeat":case null:case "":this.repetition_="repeat";break;case "repeat-x":case "repeat-y":case "no-repeat":this.repetition_=repetition;break;default:throwException("SYNTAX_ERR")}this.src_=image.src;this.width_=image.width;this.height_=image.height}function throwException(s){throw new DOMException_(s); +}function assertImageIsValid(img){if(!img||img.nodeType!=1||img.tagName!="IMG")throwException("TYPE_MISMATCH_ERR");if(img.readyState!="complete")throwException("INVALID_STATE_ERR")}function DOMException_(s){this.code=this[s];this.message=s+": DOM Exception "+this.code}var p=DOMException_.prototype=new Error;p.INDEX_SIZE_ERR=1;p.DOMSTRING_SIZE_ERR=2;p.HIERARCHY_REQUEST_ERR=3;p.WRONG_DOCUMENT_ERR=4;p.INVALID_CHARACTER_ERR=5;p.NO_DATA_ALLOWED_ERR=6;p.NO_MODIFICATION_ALLOWED_ERR=7;p.NOT_FOUND_ERR=8;p.NOT_SUPPORTED_ERR= +9;p.INUSE_ATTRIBUTE_ERR=10;p.INVALID_STATE_ERR=11;p.SYNTAX_ERR=12;p.INVALID_MODIFICATION_ERR=13;p.NAMESPACE_ERR=14;p.INVALID_ACCESS_ERR=15;p.VALIDATION_ERR=16;p.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_;DOMException=DOMException_})(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js new file mode 100644 index 00000000..d06ad45b --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js @@ -0,0 +1,24 @@ +var gadgetConfig = { + "id": "IoTServerTemperatureStats", + "title": "IoTServerTemperatureStats", + "datasource": "ORG_WSO2_IOT_DEVICES_TEMPERATURE", + "type": "batch", + "columns": [ + {"name": "TIMESTAMP", "type": "time"}, + {"name": "owner", "type": "string"}, + {"name": "deviceType", "type": "string"}, + {"name": "deviceId", "type": "string"}, + {"name": "time", "type": "long"}, + {"name": "temperature", "type": "float"} + ], + "chartConfig": { + "x": "time", + "maxLength": "10", + "padding": {"top": 30, "left": 45, "bottom": 38, "right": 55}, + "charts": [{"type": "line", "y": "temperature"}] + }, + "domain": "carbon.super", + /* timeFrom and timeTo need not be mentioned here since they will be automatically fetched + if found in the QueryString of the URL */ + "params": ["owner", "deviceId"] +}; diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js new file mode 100644 index 00000000..14ba6362 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js @@ -0,0 +1,9472 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + return jQuery.merge( this, selector ); + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.8.3", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ), + "slice", core_slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && core_rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, + ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + input.setAttribute( "checked", "checked" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea|)$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + if ( (value && typeof value === "string") || value === undefined ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( className ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + 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( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = value + "" ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + 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( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.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( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

"; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, l, length, n, r, ret, + self = this; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
", "
" ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( e ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js new file mode 100644 index 00000000..153a6c8e --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js @@ -0,0 +1,568 @@ +var datasource, type, columns, filter, maxUpdateValue, paramsToFilterBy; + +var REFRESH_INTERVAL = 5000; + +//this needs to be loaded from an autogenerated +datasource = gadgetConfig.datasource; +filter = gadgetConfig.filter; +type = gadgetConfig.type; +maxUpdateValue = gadgetConfig.maxUpdateValue; +columns = gadgetConfig.columns; +paramsToFilterBy = gadgetConfig.params; + +var counter = 0; +var TYPE_GET_BY_RANGE = 8; +var TYPE_SEARCH = 13; +var TYPE_SEARCH_COUNT = 14; + +var TIME_FROM_STRING = "timeFrom"; +var TIME_TO_STRING = "timeTo"; +var UNIX_TIME_MAX_VALUE = "9007199254740992"; +var UNIX_TIME_MIN_VALUE = "-9007199254740992"; +var META_TAG = "meta_"; +var initialConfig, urlQueryParams, queryParamValPair, queryString; +var dataTable, chart; + +executeDataFetchForGadget(); + +/** + * The main execution logic of the gadget is implemented in this function. + */ +function executeDataFetchForGadget() { + var urlQueryString; + + // fetch all queryParams from the URL. + urlQueryParams = getAllQueryParamsFromURL(); + + // check if params config exists in the gadgetConf. + if (typeof paramsToFilterBy != "undefined" && paramsToFilterBy.length != 0) { + + if (urlQueryParams != null) { + // get the values corresponding to the query "params" given in the gadgetConf + queryParamValPair = getValuesOfQueryFilter(); + + // if at-least one of the given params in the conf are missing from the URL params then returns null. + if (queryParamValPair == null) { + console.log("Incomplete set of Query Params were found in the URL."); + return; + } + + // construct the Lucene query string based on the params given in the gadget-conf + // and the values parsed from the URL Query String. + queryString = constructQueryString(); + + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe( + datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, + location.hostname, location.port, 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataOnQuery(fetchDataWithCount); + // then start periodic polling + setInterval(function () { + fetchDataOnQuery(fetchDataWithCount); + }, REFRESH_INTERVAL); + break; + } + + } else { + // if there are NO queryParams in the URL then exit. + console.log("No Query Params were found in the URL to match the given filter-parameters."); + } + } else { + // if no params to filter by are given in the gadget-conf, then fetch all info available + // based on date range(if given). + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe(datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, location.hostname, location.port, + 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataWithoutQuery(drawBatchChart); + + // then start periodic polling + setInterval(function () { + fetchDataWithoutQuery(drawBatchChart); + }, REFRESH_INTERVAL); + break; + } + } +} + +/** + * Reads the page's URL Query-Params and returns them as an associative array. + * @returns {*} an associative array containing the URL QueryParams and corresponding values. + * If no such Query-Params exists then returns null. + */ +function getAllQueryParamsFromURL() { + var queryParamList = [], qParam; + var urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + if (urlQueryString) { + var queryStringPairs = urlQueryString.split('&'); + for (var i = 0; i < queryStringPairs.length; i++) { + qParam = queryStringPairs[i].split('='); + queryParamList[qParam[0]] = qParam[1]; + } + return queryParamList; + } else { + return null; + } +} + +/** + * Retrieves the values from the URL-QueryString corresponding to the given QueryParams in the gadget-conf file. + * The parameters "timeTo" & "timeFrom" (if found in the query string) are added to the returned object regardless + * of whether they are listed in the gadget-conf. + * @returns {*} an associative array of the given params in the conf and corresponding value fetched from the + * URL string. + */ +function getValuesOfQueryFilter() { + var queryValues = []; + + if (TIME_FROM_STRING in urlQueryParams) { + queryValues[TIME_FROM_STRING] = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + queryValues[TIME_TO_STRING] = urlQueryParams[TIME_TO_STRING]; + } + + for (var i = 0; i < paramsToFilterBy.length; i++) { + var queryV = urlQueryParams[paramsToFilterBy[i]]; + + // if atleast one of the queryParams given in the gadgetConf is missing then return "null". + if (typeof queryV != "undefined" && queryV != null && queryV != "") { + queryValues[paramsToFilterBy[i]] = queryV; + } else { + return null; + } + } + return queryValues; +} + +/** + * Constructs the Lucene Query String to be sent to DAS API. + * @returns {string} a fully constructed query string from the params given in gadget-conf and + * the query string of the URL. + */ +function constructQueryString() { + var queryString = "'"; + for (var a = 0; a < paramsToFilterBy.length; a++) { + if (queryString.length == 1) { + queryString += META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } else { + queryString += " AND " + META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } + } + + if (TIME_FROM_STRING in queryParamValPair && TIME_TO_STRING in queryParamValPair) { + // both ends of the time-range (From What Date - To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + + } else if (TIME_FROM_STRING in queryParamValPair && !(TIME_TO_STRING in queryParamValPair)) { + // Only the start of the time-range (From What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + UNIX_TIME_MAX_VALUE + "]"; + + } else if (!(TIME_FROM_STRING in queryParamValPair) && TIME_TO_STRING in queryParamValPair) { + // Only the end of the time-range (To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + UNIX_TIME_MIN_VALUE + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + } + //queryString += " AND meta_time:[1456467843079 TO 1456468494817]'"; + queryString += "'"; + return queryString; +} + +/** + * Utility method to fetch columns of the datasource provided for a Batch-Type Gadget. + * @param table the name of the datasource table whose columns needs to be extracted. + */ +function getColumns(table) { + console.log("Fetching table schema for table: " + table); + var url = "/portal/apis/analytics?type=10&tableName=" + table; + $.getJSON(url, function (data) { + if (data) { + columns = parseColumns(JSON.parse(data.message)); + } + + }); +} + +/** Constructs an associative array containing the columns and the corresponding data-type ("String", "Long", etc) + * from the returned object as a result of the "getColumns" method above. + * @param data the response object returned from the "getColumns(table)" call to the DAS API. + * @returns {Array|*} an array containing the column names as keys and their type as values. + */ +function parseColumns(data) { + if (data.columns) { + var keys = Object.getOwnPropertyNames(data.columns); + columns = keys.map(function (key, i) { + return column = { + name: key, + type: data.columns[key].type + }; + }); + return columns; + } +} + +/** + * Makes the initial call to the DAS APIs to get the count of all matching indexes based on a given query. + * Upon receiving a response (count), a subsequent method is called to fetch the given "count" amount of data from + * DAS that matches the query. + * @param callback the subsequent method to be called using the "count" response value received from the API call. + */ +function fetchDataOnQuery(callback) { + var request = { + type: TYPE_SEARCH_COUNT, // DAS API type corresponding to fetching data-count for "query" + tableName: datasource, + query: queryString + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(drawBatchChart, data.message); + } + } + }); +} + +/** + * Makes an API call to the DAS to fetch the "count" number of data matching the queryString constructed from the + * query-string and the param-list provided in the gadget-conf. The fetched data are passed into the provided + * "callback" method which further processes and draws the chart against this data. + * @param callback the method to which the fetched data are to be passed in for further processing. + * @param totalCount the count of all matching data available against the queryString. + */ +function fetchDataWithCount(callback, totalCount) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + var request = { + type: TYPE_SEARCH, // DAS API type corresponding to fetching data for "query" + tableName: datasource, + filter: filter, + query: queryString, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0, + count: totalCount + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + var sortedData = sortData(data.message); + callback(makeRows(sortedData)); + } + } + }); +} + +/** + * Retrieves all data available in a datasource irrespective of any query filters. However, the API call incorporates + * a data range to be submitted whilst fetching this info. If such date range related query strings + * ("timeFrom" or "timeTo") are found in the URL, then they are used. + * @param callback the method to which the fetched data are to be passed in for further processing. + */ +function fetchDataWithoutQuery(callback) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + + if (urlQueryParams != null) { + if (TIME_FROM_STRING in urlQueryParams) { + timeFrom = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + timeTo = urlQueryParams[TIME_TO_STRING]; + } + } + + var request = { + type: TYPE_GET_BY_RANGE, // DAS API type corresponding to fetching data by date range. + tableName: datasource, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0 + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(makeRows(JSON.parse(data.message))); + } + } + }); +} + +/** + * This is a utility method to convert Unix-Timestamp values to Epoch Time + * @param unix_timestamp the unix time to be converted + * @returns {string} the formatted epoch-time of the given unix-timestamp + */ +function convertToEpoch(unix_timestamp) { + // Create a new JavaScript Date object based on the timestamp + // multiplied by 1000 so that the argument is in milliseconds, not seconds. + var date = new Date(unix_timestamp * 1000); + // Hours part from the timestamp + var hours = date.getHours(); + // Minutes part from the timestamp + var minutes = "0" + date.getMinutes(); + // Seconds part from the timestamp + var seconds = "0" + date.getSeconds(); + + var thisDate = date.getDate(); + var thisMonth = date.getMonth(); + var thisYear = date.getUTCFullYear(); + + var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2); + + // Will display time in 10:30:23 format + return (formattedTime); +} + +/** + * Sorts the given data array according to the values of its "timestamp" key. + * @param payload a JSON string with multiple data-arrays having a "timestamp" key-value pair. + * @returns {*} JSON Object with multiple sorted by "timestamp" + */ +function sortData(payload) { + var dataFromDAS = JSON.parse(payload); + sortedData = dataFromDAS.sort(function (a, b) { + return a.timestamp - b.timestamp; + }); + return sortedData; +} + +/** + * Fetches the values corresponding to the keys in the "columns" (either provided in the gadget-conf or fetched via the + * "getColumns(table)" method) array from the data object passed in. + * @param data a JSON Object containing multiple data values fetched from the datasource with column-name:value pairs. + * @returns {Array} an array with objects that contain the columns from the fetched "columns" and their corresponding + * values. + */ +function makeRows(data) { + var rows = []; + for (var i = 0; i < data.length; i++) { + var record = data[i]; + var keys = Object.getOwnPropertyNames(record.values); + keys.push(); + + var row = columns.map(function (column, i) { + var colName = column.name; + var recordVal = record.values[colName]; + + if (typeof recordVal == 'undefined') { + if (column.name.toUpperCase() === "TIMESTAMP" && (record.timestamp || record.TIMESTAMP)) { + recordVal = record.timestamp; + } else { + recordVal = record.values[META_TAG + colName]; + } + } + return recordVal; + }); + rows.push(row); + } + return rows; +} + +function makeDataTable(data) { + var dataTable = new igviz.DataTable(); + if (columns.length > 0) { + columns.forEach(function (column, i) { + var type = "N"; + if (column.type == "STRING" || column.type == "string") { + type = "C"; + } else if (column.type == "TIME" || column.type == "time") { + type = "T"; + } + dataTable.addColumn(column.name, type); + }); + } + data.forEach(function (row, index) { + for (var i = 0; i < row.length; i++) { + if (dataTable.metadata.types[i] == "N") { + data[index][i] = parseInt(data[index][i]); + } + } + }); + dataTable.addRows(data); + return dataTable; +} + +function drawChart(data) { + var dataTable = makeDataTable(data); + gadgetConfig.chartConfig.width = $("#placeholder").width(); + gadgetConfig.chartConfig.height = $("#placeholder").height() - 65; + var chartType = gadgetConfig.chartConfig.chartType; + var xAxis = gadgetConfig.chartConfig.xAxis; + jQuery("#noChart").html(""); + if (chartType === "bar" && dataTable.metadata.types[xAxis] === "N") { + dataTable.metadata.types[xAxis] = "C"; + } + + if (gadgetConfig.chartConfig.chartType === "table" || gadgetConfig.chartConfig.chartType === "singleNumber") { + gadgetConfig.chartConfig.height = $("#placeholder").height(); + chart = igviz.draw("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.plot(dataTable.data); + + } else { + chart = igviz.setUp("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.setXAxis({ + "labelAngle": -35, + "labelAlign": "right", + "labelDy": 0, + "labelDx": 0, + "titleDy": 25 + }) + .setYAxis({ + "titleDy": -30 + }); + chart.plot(dataTable.data); + } +} + + +//stuff required for realtime charting +function onRealTimeEventSuccessRecieval(streamId, data) { + drawRealtimeChart(data); +} + +function onRealTimeEventErrorRecieval(dataError) { + console.log("Error occurred " + dataError); +} + +/** + * Draws the real-time chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawRealtimeChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); + } else { + chart.insert(convertData(data)); + } +} + +/** + * Draws the batch-chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawBatchChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + + } else { + gadgetConfig.chartConfig = initialConfig; + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); +} + + +function convertData(data) { + for (var i = 0; i < data.length; i++) { + for (var x = 0; x < data[i].length; x++) { + var type = gadgetConfig.columns[x]["type"].toUpperCase(); + if (type != "STRING" && type != "BOOLEAN") { + data[i][x] = parseFloat(data[i][x]); + } + } + } + return data; +} + +function createDataTable(data) { + var names = []; + var types = []; + + for (var i = 0; i < gadgetConfig.columns.length; i++) { + var name = gadgetConfig.columns[i]["name"]; + names.push(name); + var type = columns[i]["type"].toUpperCase(); + + if (type === "INT" || type === "INTEGER" || type === "FLOAT" || type === "DOUBLE") { + type = "linear"; + } else if (gadgetConfig.columns[i]["type"].toUpperCase() == "TIME" || name.toUpperCase() == "TIME") { + type = "time"; + } else { + type = "ordinal"; + } + types.push(type); + } + + datatable = [ + { + "metadata": { + "names": names, + "types": types + }, + "data": data + } + ]; + return datatable; +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js new file mode 100755 index 00000000..caaf8b3c --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js @@ -0,0 +1,7 @@ +//! moment.js +//! version : 2.11.2 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return Uc.apply(null,arguments)}function b(a){Uc=a}function c(a){return"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c0)for(c in Wc)d=Wc[c],e=b[d],m(e)||(a[d]=e);return a}function o(b){n(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),Xc===!1&&(Xc=!0,a.updateOffset(this),Xc=!1)}function p(a){return a instanceof o||null!=a&&null!=a._isAMomentObject}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=q(b)),c}function s(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&r(a[d])!==r(b[d]))&&g++;return g+f}function t(){}function u(a){return a?a.toLowerCase().replace("_","-"):a}function v(a){for(var b,c,d,e,f=0;f0;){if(d=w(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&s(e,c,!0)>=b-1)break;b--}f++}return null}function w(a){var b=null;if(!Yc[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Vc._abbr,require("./locale/"+a),x(b)}catch(c){}return Yc[a]}function x(a,b){var c;return a&&(c=m(b)?z(a):y(a,b),c&&(Vc=c)),Vc._abbr}function y(a,b){return null!==b?(b.abbr=a,Yc[a]=Yc[a]||new t,Yc[a].set(b),x(a),Yc[a]):(delete Yc[a],null)}function z(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Vc;if(!c(a)){if(b=w(a))return b;a=[a]}return v(a)}function A(a,b){var c=a.toLowerCase();Zc[c]=Zc[c+"s"]=Zc[b]=a}function B(a){return"string"==typeof a?Zc[a]||Zc[a.toLowerCase()]:void 0}function C(a){var b,c,d={};for(c in a)f(a,c)&&(b=B(c),b&&(d[b]=a[c]));return d}function D(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function E(b,c){return function(d){return null!=d?(G(this,b,d),a.updateOffset(this,c),this):F(this,b)}}function F(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function G(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function H(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=B(a),D(this[a]))return this[a](b);return this}function I(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function J(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(bd[a]=e),b&&(bd[b[0]]=function(){return I(e.apply(this,arguments),b[1],b[2])}),c&&(bd[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function K(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function L(a){var b,c,d=a.match($c);for(b=0,c=d.length;c>b;b++)bd[d[b]]?d[b]=bd[d[b]]:d[b]=K(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function M(a,b){return a.isValid()?(b=N(b,a.localeData()),ad[b]=ad[b]||L(b),ad[b](a)):a.localeData().invalidDate()}function N(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(_c.lastIndex=0;d>=0&&_c.test(a);)a=a.replace(_c,c),_c.lastIndex=0,d-=1;return a}function O(a,b,c){td[a]=D(b)?b:function(a,d){return a&&c?c:b}}function P(a,b){return f(td,a)?td[a](b._strict,b._locale):new RegExp(Q(a))}function Q(a){return R(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function R(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function S(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=r(a)}),c=0;cd;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function Z(a,b){var c;return a.isValid()?"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),V(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a):a}function $(b){return null!=b?(Z(this,b),a.updateOffset(this,!0),this):F(this,"Month")}function _(){return V(this.year(),this.month())}function aa(a){return this._monthsParseExact?(f(this,"_monthsRegex")||ca.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex}function ba(a){return this._monthsParseExact?(f(this,"_monthsRegex")||ca.call(this),a?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex}function ca(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=h([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=R(d[b]),e[b]=R(e[b]),f[b]=R(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")$","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")$","i")}function da(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[wd]<0||c[wd]>11?wd:c[xd]<1||c[xd]>V(c[vd],c[wd])?xd:c[yd]<0||c[yd]>24||24===c[yd]&&(0!==c[zd]||0!==c[Ad]||0!==c[Bd])?yd:c[zd]<0||c[zd]>59?zd:c[Ad]<0||c[Ad]>59?Ad:c[Bd]<0||c[Bd]>999?Bd:-1,j(a)._overflowDayOfYear&&(vd>b||b>xd)&&(b=xd),j(a)._overflowWeeks&&-1===b&&(b=Cd),j(a)._overflowWeekday&&-1===b&&(b=Dd),j(a).overflow=b),a}function ea(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function fa(a,b){var c=!0;return g(function(){return c&&(ea(a+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),c=!1),b.apply(this,arguments)},b)}function ga(a,b){Jd[a]||(ea(b),Jd[a]=!0)}function ha(a){var b,c,d,e,f,g,h=a._i,i=Kd.exec(h)||Ld.exec(h);if(i){for(j(a).iso=!0,b=0,c=Nd.length;c>b;b++)if(Nd[b][1].exec(i[1])){e=Nd[b][0],d=Nd[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Od.length;c>b;b++)if(Od[b][1].exec(i[3])){f=(i[2]||" ")+Od[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!Md.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),wa(a)}else a._isValid=!1}function ia(b){var c=Pd.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(ha(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function ja(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function ka(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function la(a){return ma(a)?366:365}function ma(a){return a%4===0&&a%100!==0||a%400===0}function na(){return ma(this.year())}function oa(a,b,c){var d=7+b-c,e=(7+ka(a,0,d).getUTCDay()-b)%7;return-e+d-1}function pa(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=oa(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=la(f)+j):j>la(a)?(f=a+1,g=j-la(a)):(f=a,g=j),{year:f,dayOfYear:g}}function qa(a,b,c){var d,e,f=oa(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+ra(e,b,c)):g>ra(a.year(),b,c)?(d=g-ra(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function ra(a,b,c){var d=oa(a,b,c),e=oa(a+1,b,c);return(la(a)-d+e)/7}function sa(a,b,c){return null!=a?a:null!=b?b:c}function ta(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function ua(a){var b,c,d,e,f=[];if(!a._d){for(d=ta(a),a._w&&null==a._a[xd]&&null==a._a[wd]&&va(a),a._dayOfYear&&(e=sa(a._a[vd],d[vd]),a._dayOfYear>la(e)&&(j(a)._overflowDayOfYear=!0),c=ka(e,0,a._dayOfYear),a._a[wd]=c.getUTCMonth(),a._a[xd]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[yd]&&0===a._a[zd]&&0===a._a[Ad]&&0===a._a[Bd]&&(a._nextDay=!0,a._a[yd]=0),a._d=(a._useUTC?ka:ja).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[yd]=24)}}function va(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=sa(b.GG,a._a[vd],qa(Ea(),1,4).year),d=sa(b.W,1),e=sa(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=sa(b.gg,a._a[vd],qa(Ea(),f,g).year),d=sa(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>ra(c,f,g)?j(a)._overflowWeeks=!0:null!=i?j(a)._overflowWeekday=!0:(h=pa(c,d,e,f,g),a._a[vd]=h.year,a._dayOfYear=h.dayOfYear)}function wa(b){if(b._f===a.ISO_8601)return void ha(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=N(b._f,b._locale).match($c)||[],c=0;c0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),bd[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),U(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[yd]<=12&&b._a[yd]>0&&(j(b).bigHour=void 0),b._a[yd]=xa(b._locale,b._a[yd],b._meridiem),ua(b),da(b)}function xa(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function ya(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;ef)&&(d=f,c=b));g(a,c||b)}function za(a){if(!a._d){var b=C(a._i);a._a=e([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),ua(a)}}function Aa(a){var b=new o(da(Ba(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Ba(a){var b=a._i,e=a._f;return a._locale=a._locale||z(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),p(b)?new o(da(b)):(c(e)?ya(a):e?wa(a):d(b)?a._d=b:Ca(a),k(a)||(a._d=null),a))}function Ca(b){var f=b._i;void 0===f?b._d=new Date(a.now()):d(f)?b._d=new Date(+f):"string"==typeof f?ia(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),ua(b)):"object"==typeof f?za(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Da(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,Aa(f)}function Ea(a,b,c,d){return Da(a,b,c,d,!1)}function Fa(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Ea();for(d=b[0],e=1;ea&&(a=-a,c="-"),c+I(~~(a/60),2)+b+I(~~a%60,2)})}function La(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(Ud)||["-",0,0],f=+(60*e[1])+r(e[2]);return"+"===e[0]?f:-f}function Ma(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(p(b)||d(b)?+b:+Ea(b))-+e,e._d.setTime(+e._d+f),a.updateOffset(e,!1),e):Ea(b).local()}function Na(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Oa(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=La(qd,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Na(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?cb(this,Za(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Na(this):null!=b?this:NaN}function Pa(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Qa(a){return this.utcOffset(0,a)}function Ra(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Na(this),"m")),this}function Sa(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(La(pd,this._i)),this}function Ta(a){return this.isValid()?(a=a?Ea(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function Ua(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Va(){if(!m(this._isDSTShifted))return this._isDSTShifted;var a={};if(n(a,this),a=Ba(a),a._a){var b=a._isUTC?h(a._a):Ea(a._a);this._isDSTShifted=this.isValid()&&s(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Wa(){return this.isValid()?!this._isUTC:!1}function Xa(){return this.isValid()?this._isUTC:!1}function Ya(){return this.isValid()?this._isUTC&&0===this._offset:!1}function Za(a,b){var c,d,e,g=a,h=null;return Ja(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=Vd.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:r(h[xd])*c,h:r(h[yd])*c,m:r(h[zd])*c,s:r(h[Ad])*c,ms:r(h[Bd])*c}):(h=Wd.exec(a))?(c="-"===h[1]?-1:1,g={y:$a(h[2],c),M:$a(h[3],c),d:$a(h[4],c),h:$a(h[5],c),m:$a(h[6],c),s:$a(h[7],c),w:$a(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=ab(Ea(g.from),Ea(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Ia(g),Ja(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function $a(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function _a(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function ab(a,b){var c;return a.isValid()&&b.isValid()?(b=Ma(b,a),a.isBefore(b)?c=_a(a,b):(c=_a(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function bb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(ga(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Za(c,d),cb(this,e,a),this}}function cb(b,c,d,e){var f=c._milliseconds,g=c._days,h=c._months;b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(+b._d+f*d),g&&G(b,"Date",F(b,"Date")+g*d),h&&Z(b,F(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function db(a,b){var c=a||Ea(),d=Ma(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse",g=b&&(D(b[f])?b[f]():b[f]);return this.format(g||this.localeData().calendar(f,this,Ea(c)))}function eb(){return new o(this)}function fb(a,b){var c=p(a)?a:Ea(a);return this.isValid()&&c.isValid()?(b=B(m(b)?"millisecond":b),"millisecond"===b?+this>+c:+c<+this.clone().startOf(b)):!1}function gb(a,b){var c=p(a)?a:Ea(a);return this.isValid()&&c.isValid()?(b=B(m(b)?"millisecond":b),"millisecond"===b?+c>+this:+this.clone().endOf(b)<+c):!1}function hb(a,b,c){return this.isAfter(a,c)&&this.isBefore(b,c)}function ib(a,b){var c,d=p(a)?a:Ea(a);return this.isValid()&&d.isValid()?(b=B(b||"millisecond"),"millisecond"===b?+this===+d:(c=+d,+this.clone().startOf(b)<=c&&c<=+this.clone().endOf(b))):!1}function jb(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function kb(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function lb(a,b,c){var d,e,f,g;return this.isValid()?(d=Ma(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=B(b),"year"===b||"month"===b||"quarter"===b?(g=mb(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:q(g)):NaN):NaN}function mb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function nb(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ob(){var a=this.clone().utc();return 0f&&(b=f),Ob.call(this,a,b,c,d,e))}function Ob(a,b,c,d,e){var f=pa(a,b,c,d,e),g=ka(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Pb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Qb(a){return qa(a,this._week.dow,this._week.doy).week}function Rb(){return this._week.dow}function Sb(){return this._week.doy}function Tb(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ub(a){var b=qa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Vb(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Wb(a,b){return c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]}function Xb(a){return this._weekdaysShort[a.day()]}function Yb(a){return this._weekdaysMin[a.day()]}function Zb(a,b,c){var d,e,f;for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=Ea([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function $b(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Vb(a,this.localeData()),this.add(a-b,"d")):b}function _b(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function ac(a){return this.isValid()?null==a?this.day()||7:this.day(this.day()%7?a:a-7):null!=a?this:NaN}function bc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function cc(){return this.hours()%12||12}function dc(a,b){J(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function ec(a,b){return b._meridiemParse}function fc(a){return"p"===(a+"").toLowerCase().charAt(0)}function gc(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function hc(a,b){b[Bd]=r(1e3*("0."+a))}function ic(){return this._isUTC?"UTC":""}function jc(){return this._isUTC?"Coordinated Universal Time":""}function kc(a){return Ea(1e3*a)}function lc(){return Ea.apply(null,arguments).parseZone()}function mc(a,b,c){var d=this._calendar[a];return D(d)?d.call(b,c):d}function nc(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function oc(){return this._invalidDate}function pc(a){return this._ordinal.replace("%d",a)}function qc(a){return a}function rc(a,b,c,d){var e=this._relativeTime[c];return D(e)?e(a,b,c,d):e.replace(/%d/i,a)}function sc(a,b){var c=this._relativeTime[a>0?"future":"past"];return D(c)?c(b):c.replace(/%s/i,b)}function tc(a){var b,c;for(c in a)b=a[c],D(b)?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function uc(a,b,c,d){var e=z(),f=h().set(d,b);return e[c](f,a)}function vc(a,b,c,d,e){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return uc(a,b,c,e);var f,g=[];for(f=0;d>f;f++)g[f]=uc(a,f,c,e);return g}function wc(a,b){return vc(a,b,"months",12,"month")}function xc(a,b){return vc(a,b,"monthsShort",12,"month")}function yc(a,b){return vc(a,b,"weekdays",7,"day")}function zc(a,b){return vc(a,b,"weekdaysShort",7,"day")}function Ac(a,b){return vc(a,b,"weekdaysMin",7,"day")}function Bc(){var a=this._data;return this._milliseconds=se(this._milliseconds),this._days=se(this._days),this._months=se(this._months),a.milliseconds=se(a.milliseconds),a.seconds=se(a.seconds),a.minutes=se(a.minutes),a.hours=se(a.hours),a.months=se(a.months),a.years=se(a.years),this}function Cc(a,b,c,d){var e=Za(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Dc(a,b){return Cc(this,a,b,1)}function Ec(a,b){return Cc(this,a,b,-1)}function Fc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Gc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Fc(Ic(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=q(f/1e3),i.seconds=a%60,b=q(a/60),i.minutes=b%60,c=q(b/60),i.hours=c%24,g+=q(c/24),e=q(Hc(g)),h+=e,g-=Fc(Ic(e)),d=q(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function Hc(a){return 4800*a/146097}function Ic(a){return 146097*a/4800}function Jc(a){var b,c,d=this._milliseconds;if(a=B(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+Hc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(Ic(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function Kc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*r(this._months/12)}function Lc(a){return function(){return this.as(a)}}function Mc(a){return a=B(a),this[a+"s"]()}function Nc(a){return function(){return this._data[a]}}function Oc(){return q(this.days()/7)}function Pc(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Qc(a,b,c){var d=Za(a).abs(),e=Ie(d.as("s")),f=Ie(d.as("m")),g=Ie(d.as("h")),h=Ie(d.as("d")),i=Ie(d.as("M")),j=Ie(d.as("y")),k=e=f&&["m"]||f=g&&["h"]||g=h&&["d"]||h=i&&["M"]||i=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,Pc.apply(null,k)}function Rc(a,b){return void 0===Je[a]?!1:void 0===b?Je[a]:(Je[a]=b,!0)}function Sc(a){var b=this.localeData(),c=Qc(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function Tc(){var a,b,c,d=Ke(this._milliseconds)/1e3,e=Ke(this._days),f=Ke(this._months);a=q(d/60),b=q(a/60),d%=60,a%=60,c=q(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var Uc,Vc,Wc=a.momentProperties=[],Xc=!1,Yc={},Zc={},$c=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,_c=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,ad={},bd={},cd=/\d/,dd=/\d\d/,ed=/\d{3}/,fd=/\d{4}/,gd=/[+-]?\d{6}/,hd=/\d\d?/,id=/\d\d\d\d?/,jd=/\d\d\d\d\d\d?/,kd=/\d{1,3}/,ld=/\d{1,4}/,md=/[+-]?\d{1,6}/,nd=/\d+/,od=/[+-]?\d+/,pd=/Z|[+-]\d\d:?\d\d/gi,qd=/Z|[+-]\d\d(?::?\d\d)?/gi,rd=/[+-]?\d+(\.\d{1,3})?/,sd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,td={},ud={},vd=0,wd=1,xd=2,yd=3,zd=4,Ad=5,Bd=6,Cd=7,Dd=8;J("M",["MM",2],"Mo",function(){return this.month()+1}),J("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),J("MMMM",0,0,function(a){return this.localeData().months(this,a)}),A("month","M"),O("M",hd),O("MM",hd,dd),O("MMM",function(a,b){return b.monthsShortRegex(a)}),O("MMMM",function(a,b){return b.monthsRegex(a)}),S(["M","MM"],function(a,b){b[wd]=r(a)-1}),S(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[wd]=e:j(c).invalidMonth=a});var Ed=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Fd="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Gd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Hd=sd,Id=sd,Jd={};a.suppressDeprecationWarnings=!1;var Kd=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Ld=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Md=/Z|[+-]\d\d(?::?\d\d)?/,Nd=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Od=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Pd=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=fa("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),J("Y",0,0,function(){var a=this.year();return 9999>=a?""+a:"+"+a}),J(0,["YY",2],0,function(){return this.year()%100}),J(0,["YYYY",4],0,"year"),J(0,["YYYYY",5],0,"year"),J(0,["YYYYYY",6,!0],0,"year"),A("year","y"),O("Y",od),O("YY",hd,dd),O("YYYY",ld,fd),O("YYYYY",md,gd),O("YYYYYY",md,gd),S(["YYYYY","YYYYYY"],vd),S("YYYY",function(b,c){c[vd]=2===b.length?a.parseTwoDigitYear(b):r(b)}),S("YY",function(b,c){c[vd]=a.parseTwoDigitYear(b)}),S("Y",function(a,b){b[vd]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return r(a)+(r(a)>68?1900:2e3)};var Qd=E("FullYear",!1);a.ISO_8601=function(){};var Rd=fa("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Ea.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:l()}),Sd=fa("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Ea.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:l()}),Td=function(){return Date.now?Date.now():+new Date};Ka("Z",":"),Ka("ZZ",""),O("Z",qd),O("ZZ",qd),S(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=La(qd,a)});var Ud=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var Vd=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,Wd=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/; +Za.fn=Ia.prototype;var Xd=bb(1,"add"),Yd=bb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var Zd=fa("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});J(0,["gg",2],0,function(){return this.weekYear()%100}),J(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Ib("gggg","weekYear"),Ib("ggggg","weekYear"),Ib("GGGG","isoWeekYear"),Ib("GGGGG","isoWeekYear"),A("weekYear","gg"),A("isoWeekYear","GG"),O("G",od),O("g",od),O("GG",hd,dd),O("gg",hd,dd),O("GGGG",ld,fd),O("gggg",ld,fd),O("GGGGG",md,gd),O("ggggg",md,gd),T(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=r(a)}),T(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),J("Q",0,"Qo","quarter"),A("quarter","Q"),O("Q",cd),S("Q",function(a,b){b[wd]=3*(r(a)-1)}),J("w",["ww",2],"wo","week"),J("W",["WW",2],"Wo","isoWeek"),A("week","w"),A("isoWeek","W"),O("w",hd),O("ww",hd,dd),O("W",hd),O("WW",hd,dd),T(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=r(a)});var $d={dow:0,doy:6};J("D",["DD",2],"Do","date"),A("date","D"),O("D",hd),O("DD",hd,dd),O("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),S(["D","DD"],xd),S("Do",function(a,b){b[xd]=r(a.match(hd)[0],10)});var _d=E("Date",!0);J("d",0,"do","day"),J("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),J("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),J("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),J("e",0,0,"weekday"),J("E",0,0,"isoWeekday"),A("day","d"),A("weekday","e"),A("isoWeekday","E"),O("d",hd),O("e",hd),O("E",hd),O("dd",sd),O("ddd",sd),O("dddd",sd),T(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:j(c).invalidWeekday=a}),T(["d","e","E"],function(a,b,c,d){b[d]=r(a)});var ae="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),ce="Su_Mo_Tu_We_Th_Fr_Sa".split("_");J("DDD",["DDDD",3],"DDDo","dayOfYear"),A("dayOfYear","DDD"),O("DDD",kd),O("DDDD",ed),S(["DDD","DDDD"],function(a,b,c){c._dayOfYear=r(a)}),J("H",["HH",2],0,"hour"),J("h",["hh",2],0,cc),J("hmm",0,0,function(){return""+cc.apply(this)+I(this.minutes(),2)}),J("hmmss",0,0,function(){return""+cc.apply(this)+I(this.minutes(),2)+I(this.seconds(),2)}),J("Hmm",0,0,function(){return""+this.hours()+I(this.minutes(),2)}),J("Hmmss",0,0,function(){return""+this.hours()+I(this.minutes(),2)+I(this.seconds(),2)}),dc("a",!0),dc("A",!1),A("hour","h"),O("a",ec),O("A",ec),O("H",hd),O("h",hd),O("HH",hd,dd),O("hh",hd,dd),O("hmm",id),O("hmmss",jd),O("Hmm",id),O("Hmmss",jd),S(["H","HH"],yd),S(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),S(["h","hh"],function(a,b,c){b[yd]=r(a),j(c).bigHour=!0}),S("hmm",function(a,b,c){var d=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d)),j(c).bigHour=!0}),S("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d,2)),b[Ad]=r(a.substr(e)),j(c).bigHour=!0}),S("Hmm",function(a,b,c){var d=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d))}),S("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d,2)),b[Ad]=r(a.substr(e))});var de=/[ap]\.?m?\.?/i,ee=E("Hours",!0);J("m",["mm",2],0,"minute"),A("minute","m"),O("m",hd),O("mm",hd,dd),S(["m","mm"],zd);var fe=E("Minutes",!1);J("s",["ss",2],0,"second"),A("second","s"),O("s",hd),O("ss",hd,dd),S(["s","ss"],Ad);var ge=E("Seconds",!1);J("S",0,0,function(){return~~(this.millisecond()/100)}),J(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),J(0,["SSS",3],0,"millisecond"),J(0,["SSSS",4],0,function(){return 10*this.millisecond()}),J(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),J(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),J(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),J(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),J(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),A("millisecond","ms"),O("S",kd,cd),O("SS",kd,dd),O("SSS",kd,ed);var he;for(he="SSSS";he.length<=9;he+="S")O(he,nd);for(he="S";he.length<=9;he+="S")S(he,hc);var ie=E("Milliseconds",!1);J("z",0,0,"zoneAbbr"),J("zz",0,0,"zoneName");var je=o.prototype;je.add=Xd,je.calendar=db,je.clone=eb,je.diff=lb,je.endOf=xb,je.format=pb,je.from=qb,je.fromNow=rb,je.to=sb,je.toNow=tb,je.get=H,je.invalidAt=Gb,je.isAfter=fb,je.isBefore=gb,je.isBetween=hb,je.isSame=ib,je.isSameOrAfter=jb,je.isSameOrBefore=kb,je.isValid=Eb,je.lang=Zd,je.locale=ub,je.localeData=vb,je.max=Sd,je.min=Rd,je.parsingFlags=Fb,je.set=H,je.startOf=wb,je.subtract=Yd,je.toArray=Bb,je.toObject=Cb,je.toDate=Ab,je.toISOString=ob,je.toJSON=Db,je.toString=nb,je.unix=zb,je.valueOf=yb,je.creationData=Hb,je.year=Qd,je.isLeapYear=na,je.weekYear=Jb,je.isoWeekYear=Kb,je.quarter=je.quarters=Pb,je.month=$,je.daysInMonth=_,je.week=je.weeks=Tb,je.isoWeek=je.isoWeeks=Ub,je.weeksInYear=Mb,je.isoWeeksInYear=Lb,je.date=_d,je.day=je.days=$b,je.weekday=_b,je.isoWeekday=ac,je.dayOfYear=bc,je.hour=je.hours=ee,je.minute=je.minutes=fe,je.second=je.seconds=ge,je.millisecond=je.milliseconds=ie,je.utcOffset=Oa,je.utc=Qa,je.local=Ra,je.parseZone=Sa,je.hasAlignedHourOffset=Ta,je.isDST=Ua,je.isDSTShifted=Va,je.isLocal=Wa,je.isUtcOffset=Xa,je.isUtc=Ya,je.isUTC=Ya,je.zoneAbbr=ic,je.zoneName=jc,je.dates=fa("dates accessor is deprecated. Use date instead.",_d),je.months=fa("months accessor is deprecated. Use month instead",$),je.years=fa("years accessor is deprecated. Use year instead",Qd),je.zone=fa("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Pa);var ke=je,le={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},me={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},ne="Invalid date",oe="%d",pe=/\d{1,2}/,qe={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},re=t.prototype;re._calendar=le,re.calendar=mc,re._longDateFormat=me,re.longDateFormat=nc,re._invalidDate=ne,re.invalidDate=oc,re._ordinal=oe,re.ordinal=pc,re._ordinalParse=pe,re.preparse=qc,re.postformat=qc,re._relativeTime=qe,re.relativeTime=rc,re.pastFuture=sc,re.set=tc,re.months=W,re._months=Fd,re.monthsShort=X,re._monthsShort=Gd,re.monthsParse=Y,re._monthsRegex=Id,re.monthsRegex=ba,re._monthsShortRegex=Hd,re.monthsShortRegex=aa,re.week=Qb,re._week=$d,re.firstDayOfYear=Sb,re.firstDayOfWeek=Rb,re.weekdays=Wb,re._weekdays=ae,re.weekdaysMin=Yb,re._weekdaysMin=ce,re.weekdaysShort=Xb,re._weekdaysShort=be,re.weekdaysParse=Zb,re.isPM=fc,re._meridiemParse=de,re.meridiem=gc,x("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===r(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=fa("moment.lang is deprecated. Use moment.locale instead.",x),a.langData=fa("moment.langData is deprecated. Use moment.localeData instead.",z);var se=Math.abs,te=Lc("ms"),ue=Lc("s"),ve=Lc("m"),we=Lc("h"),xe=Lc("d"),ye=Lc("w"),ze=Lc("M"),Ae=Lc("y"),Be=Nc("milliseconds"),Ce=Nc("seconds"),De=Nc("minutes"),Ee=Nc("hours"),Fe=Nc("days"),Ge=Nc("months"),He=Nc("years"),Ie=Math.round,Je={s:45,m:45,h:22,d:26,M:11},Ke=Math.abs,Le=Ia.prototype;Le.abs=Bc,Le.add=Dc,Le.subtract=Ec,Le.as=Jc,Le.asMilliseconds=te,Le.asSeconds=ue,Le.asMinutes=ve,Le.asHours=we,Le.asDays=xe,Le.asWeeks=ye,Le.asMonths=ze,Le.asYears=Ae,Le.valueOf=Kc,Le._bubble=Gc,Le.get=Mc,Le.milliseconds=Be,Le.seconds=Ce,Le.minutes=De,Le.hours=Ee,Le.days=Fe,Le.weeks=Oc,Le.months=Ge,Le.years=He,Le.humanize=Sc,Le.toISOString=Tc,Le.toString=Tc,Le.toJSON=Tc,Le.locale=ub,Le.localeData=vb,Le.toIsoString=fa("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Tc),Le.lang=Zd,J("X",0,0,"unix"),J("x",0,0,"valueOf"),O("x",od),O("X",rd),S("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),S("x",function(a,b,c){c._d=new Date(r(a))}),a.version="2.11.2",b(Ea),a.fn=ke,a.min=Ga,a.max=Ha,a.now=Td,a.utc=h,a.unix=kc,a.months=wc,a.isDate=d,a.locale=x,a.invalid=l,a.duration=Za,a.isMoment=p,a.weekdays=yc,a.parseZone=lc,a.localeData=z,a.isDuration=Ja,a.monthsShort=xc,a.weekdaysMin=Ac,a.defineLocale=y,a.weekdaysShort=zc,a.normalizeUnits=B,a.relativeTimeThreshold=Rc,a.prototype=ke;var Me=a;return Me}); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js new file mode 100644 index 00000000..50f07a80 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js @@ -0,0 +1,286 @@ +/* + * + * + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +var CONSTANTS = { + webAppName: 'outputui', + urlSeperator: '/', + urlGetParameter : '?lastUpdatedTime=', + urlQueryStringBegin : '?', + tenantUrlAttribute: 't', + urlUnsecureTransportHttp : 'http://', + urlUnsecureTransportWebsocket : 'ws://', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultUserDomain : 'carbon.super', + defaultHostName : 'localhost', + defaultNonsecurePortNumber : '9763', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + domain : 'carbon.super', + numThousand : 1000, + websocketTimeAppender : 400, + secureMode : 'SECURED' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var userDomainUrl = ""; +var terminateWebsocketInstance = false; +var pollingContinue = true; +var transportToBeUsedHttp; +var transportToBeUsedWebsocket; + +function subscribe(streamName,version,intervalTime,domain, + listeningFuncSuccessData,listeningFuncErrorData, + cepHost,cepPort,mode,secureMode, queryParams){ + + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(secureMode == CONSTANTS.secureMode){ + transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket; + } else { + transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket; + } + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(domain == null || domain == ""){ + domain = CONSTANTS.defaultUserDomain; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + if(secureMode == CONSTANTS.secureMode){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = CONSTANTS.defaultNonsecurePortNumber; + } + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + if(domain != CONSTANTS.domain){ + userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator; + + } + + if (queryParams == null) { + queryParams = ""; + } else if (queryParams != "") { + queryParams = CONSTANTS.urlQueryStringBegin + queryParams; + } + + webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream + + CONSTANTS.urlSeperator + streamVersion + queryParams; + + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + // alert("Successfully connected to "+webSocketUrl); + //onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n"); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator + + CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator + + streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime; + + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i 1) { + var geomsByArc = [], + geom; + + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } + + function line(arcs) { + arcs.forEach(arc); + } + + function polygon(arcs) { + arcs.forEach(line); + } + + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs) { arcs.forEach(polygon); } + }; + + geometry(o); + + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + } + + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } + + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; + + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); + + function register(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); + }); + }); + polygons.push(polygon); + } + + function exterior(ring) { + return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? + } + + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); + + polygons.forEach(function(polygon) { + delete polygon._; + }); + + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = []; + + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); + + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // this exterior ring has the same winding order + // as any exterior ring in the original polygons. + if ((n = arcs.length) > 1) { + var sgn = exterior(polygons[0][0]); + for (var i = 0, t; i < n; ++i) { + if (sgn === exterior(arcs[i])) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; + break; + } + } + } + + return arcs; + }) + }; + } + + function featureOrCollection(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature(topology, o); }) + } : feature(topology, o); + } + + function feature(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } + + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; + + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); + } + + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; + } + + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; + } + + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; + } + + function polygon(arcs) { + return arcs.map(ring); + } + + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; + } + + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; + + return geometry(o); + } + + function reverse(array, n) { + var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } + + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); + + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } + + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } + + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; + + objects.forEach(geometry); + + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); + } + } + } + + return neighbors; + } + + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); + + if (!triangleArea) triangleArea = cartesianTriangleArea; + + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle; + + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (var i = 0, n = arc.length, p; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } + + for (var i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); + triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); + heap.push(triangle); + } + + for (var i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } + + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; + + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; + + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); + } + + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } + + arc.forEach(relative); + }); + + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); + } + + return topology; + }; + + function cartesianRingArea(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; + + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; + } + + return area * .5; + } + + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } + + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } + + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; + + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; + + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; + }; + + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; + + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } + + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } + } + + return heap; + } + + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; + }; + } + + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = (point[0] - dx) / kx | 0, + y1 = (point[1] - dy) / ky | 0; + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } + + function noop() {} + + if (typeof define === "function" && define.amd) define(topojson); + else if (typeof module === "object" && module.exports) module.exports = topojson; + else this.topojson = topojson; +}(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js new file mode 100644 index 00000000..c6b8b0af --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js @@ -0,0 +1,20654 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vg = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 5, + ch = 1 << 11; + + module.exports = function() { + var size = [256, 256], + text = cloudText, + font = cloudFont, + fontSize = cloudFontSize, + fontStyle = cloudFontNormal, + fontWeight = cloudFontNormal, + rotate = cloudRotate, + padding = cloudPadding, + spiral = archimedeanSpiral, + words = [], + timeInterval = Infinity, + event = dispatch("word", "end"), + timer = null, + random = Math.random, + cloud = {}, + canvas = cloudCanvas; + + cloud.canvas = function(_) { + return arguments.length ? (canvas = functor(_), cloud) : canvas; + }; + + cloud.start = function() { + var contextAndRatio = getContext(canvas()), + board = zeroArray((size[0] >> 5) * size[1]), + bounds = null, + n = words.length, + i = -1, + tags = [], + data = words.map(function(d, i) { + d.text = text.call(this, d, i); + d.font = font.call(this, d, i); + d.style = fontStyle.call(this, d, i); + d.weight = fontWeight.call(this, d, i); + d.rotate = rotate.call(this, d, i); + d.size = ~~fontSize.call(this, d, i); + d.padding = padding.call(this, d, i); + return d; + }).sort(function(a, b) { return b.size - a.size; }); + + if (timer) clearInterval(timer); + timer = setInterval(step, 0); + step(); + + return cloud; + + function step() { + var start = Date.now(); + while (Date.now() - start < timeInterval && ++i < n && timer) { + var d = data[i]; + d.x = (size[0] * (random() + .5)) >> 1; + d.y = (size[1] * (random() + .5)) >> 1; + cloudSprite(contextAndRatio, d, data, i); + if (d.hasText && place(board, d, bounds)) { + tags.push(d); + event.word(d); + if (bounds) cloudBounds(bounds, d); + else bounds = [{x: d.x + d.x0, y: d.y + d.y0}, {x: d.x + d.x1, y: d.y + d.y1}]; + // Temporary hack + d.x -= size[0] >> 1; + d.y -= size[1] >> 1; + } + } + if (i >= n) { + cloud.stop(); + event.end(tags, bounds); + } + } + } + + cloud.stop = function() { + if (timer) { + clearInterval(timer); + timer = null; + } + return cloud; + }; + + function getContext(canvas) { + canvas.width = canvas.height = 1; + var ratio = Math.sqrt(canvas.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2); + canvas.width = (cw << 5) / ratio; + canvas.height = ch / ratio; + + var context = canvas.getContext("2d"); + context.fillStyle = context.strokeStyle = "red"; + context.textAlign = "center"; + + return {context: context, ratio: ratio}; + } + + function place(board, tag, bounds) { + var perimeter = [{x: 0, y: 0}, {x: size[0], y: size[1]}], + startX = tag.x, + startY = tag.y, + maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]), + s = spiral(size), + dt = random() < .5 ? 1 : -1, + t = -dt, + dxdy, + dx, + dy; + + while (dxdy = s(t += dt)) { + dx = ~~dxdy[0]; + dy = ~~dxdy[1]; + + if (Math.min(Math.abs(dx), Math.abs(dy)) >= maxDelta) break; + + tag.x = startX + dx; + tag.y = startY + dy; + + if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 || + tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue; + // TODO only check for collisions within current bounds. + if (!bounds || !cloudCollide(tag, board, size[0])) { + if (!bounds || collideRects(tag, bounds)) { + var sprite = tag.sprite, + w = tag.width >> 5, + sw = size[0] >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0); + } + x += sw; + } + delete tag.sprite; + return true; + } + } + } + return false; + } + + cloud.timeInterval = function(_) { + return arguments.length ? (timeInterval = _ == null ? Infinity : _, cloud) : timeInterval; + }; + + cloud.words = function(_) { + return arguments.length ? (words = _, cloud) : words; + }; + + cloud.size = function(_) { + return arguments.length ? (size = [+_[0], +_[1]], cloud) : size; + }; + + cloud.font = function(_) { + return arguments.length ? (font = functor(_), cloud) : font; + }; + + cloud.fontStyle = function(_) { + return arguments.length ? (fontStyle = functor(_), cloud) : fontStyle; + }; + + cloud.fontWeight = function(_) { + return arguments.length ? (fontWeight = functor(_), cloud) : fontWeight; + }; + + cloud.rotate = function(_) { + return arguments.length ? (rotate = functor(_), cloud) : rotate; + }; + + cloud.text = function(_) { + return arguments.length ? (text = functor(_), cloud) : text; + }; + + cloud.spiral = function(_) { + return arguments.length ? (spiral = spirals[_] || _, cloud) : spiral; + }; + + cloud.fontSize = function(_) { + return arguments.length ? (fontSize = functor(_), cloud) : fontSize; + }; + + cloud.padding = function(_) { + return arguments.length ? (padding = functor(_), cloud) : padding; + }; + + cloud.random = function(_) { + return arguments.length ? (random = _, cloud) : random; + }; + + cloud.on = function() { + var value = event.on.apply(event, arguments); + return value === event ? cloud : value; + }; + + return cloud; + }; + + function cloudText(d) { + return d.text; + } + + function cloudFont() { + return "serif"; + } + + function cloudFontNormal() { + return "normal"; + } + + function cloudFontSize(d) { + return Math.sqrt(d.value); + } + + function cloudRotate() { + return (~~(Math.random() * 6) - 3) * 30; + } + + function cloudPadding() { + return 1; + } + +// Fetches a monochrome sprite bitmap for the specified text. +// Load in batches for speed. + function cloudSprite(contextAndRatio, d, data, di) { + if (d.sprite) return; + var c = contextAndRatio.context, + ratio = contextAndRatio.ratio; + + c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio); + var x = 0, + y = 0, + maxh = 0, + n = data.length; + --di; + while (++di < n) { + d = data[di]; + c.save(); + c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font; + var w = c.measureText(d.text + "m").width * ratio, + h = d.size << 1; + if (d.rotate) { + var sr = Math.sin(d.rotate * cloudRadians), + cr = Math.cos(d.rotate * cloudRadians), + wcr = w * cr, + wsr = w * sr, + hcr = h * cr, + hsr = h * sr; + w = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5; + h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr)); + } else { + w = (w + 0x1f) >> 5 << 5; + } + if (h > maxh) maxh = h; + if (x + w >= (cw << 5)) { + x = 0; + y += maxh; + maxh = 0; + } + if (y + h >= ch) break; + c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio); + if (d.rotate) c.rotate(d.rotate * cloudRadians); + c.fillText(d.text, 0, 0); + if (d.padding) c.lineWidth = 2 * d.padding, c.strokeText(d.text, 0, 0); + c.restore(); + d.width = w; + d.height = h; + d.xoff = x; + d.yoff = y; + d.x1 = w >> 1; + d.y1 = h >> 1; + d.x0 = -d.x1; + d.y0 = -d.y1; + d.hasText = true; + x += w; + } + var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data, + sprite = []; + while (--di >= 0) { + d = data[di]; + if (!d.hasText) continue; + var w = d.width, + w32 = w >> 5, + h = d.y1 - d.y0; + // Zero the buffer + for (var i = 0; i < h * w32; i++) sprite[i] = 0; + x = d.xoff; + if (x == null) return; + y = d.yoff; + var seen = 0, + seenRow = -1; + for (var j = 0; j < h; j++) { + for (var i = 0; i < w; i++) { + var k = w32 * j + (i >> 5), + m = pixels[((y + j) * (cw << 5) + (x + i)) << 2] ? 1 << (31 - (i % 32)) : 0; + sprite[k] |= m; + seen |= m; + } + if (seen) seenRow = j; + else { + d.y0++; + h--; + j--; + y++; + } + } + d.y1 = d.y0 + seenRow; + d.sprite = sprite.slice(0, (d.y1 - d.y0) * w32); + } + } + +// Use mask-based collision detection. + function cloudCollide(tag, board, sw) { + sw >>= 5; + var sprite = tag.sprite, + w = tag.width >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + if (((last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0)) + & board[x + i]) return true; + } + x += sw; + } + return false; + } + + function cloudBounds(bounds, d) { + var b0 = bounds[0], + b1 = bounds[1]; + if (d.x + d.x0 < b0.x) b0.x = d.x + d.x0; + if (d.y + d.y0 < b0.y) b0.y = d.y + d.y0; + if (d.x + d.x1 > b1.x) b1.x = d.x + d.x1; + if (d.y + d.y1 > b1.y) b1.y = d.y + d.y1; + } + + function collideRects(a, b) { + return a.x + a.x1 > b[0].x && a.x + a.x0 < b[1].x && a.y + a.y1 > b[0].y && a.y + a.y0 < b[1].y; + } + + function archimedeanSpiral(size) { + var e = size[0] / size[1]; + return function(t) { + return [e * (t *= .1) * Math.cos(t), t * Math.sin(t)]; + }; + } + + function rectangularSpiral(size) { + var dy = 4, + dx = dy * size[0] / size[1], + x = 0, + y = 0; + return function(t) { + var sign = t < 0 ? -1 : 1; + // See triangular numbers: T_n = n * (n + 1) / 2. + switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3) { + case 0: x += dx; break; + case 1: y += dy; break; + case 2: x -= dx; break; + default: y -= dy; break; + } + return [x, y]; + }; + } + +// TODO reuse arrays? + function zeroArray(n) { + var a = [], + i = -1; + while (++i < n) a[i] = 0; + return a; + } + + function cloudCanvas() { + return document.createElement("canvas"); + } + + function functor(d) { + return typeof d === "function" ? d : function() { return d; }; + } + + var spirals = { + archimedean: archimedeanSpiral, + rectangular: rectangularSpiral + }; + +},{"d3-dispatch":4}],4:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dispatch', ['exports'], factory) : + factory((global.d3_dispatch = {})); + }(this, function (exports) { 'use strict'; + + function dispatch() { + return new Dispatch(arguments); + } + + function Dispatch(types) { + var i = -1, + n = types.length, + callbacksByType = {}, + callbackByName = {}, + type, + that = this; + + that.on = function(type, callback) { + type = parseType(type); + + // Return the current callback, if any. + if (arguments.length < 2) { + return (callback = callbackByName[type.name]) && callback.value; + } + + // If a type was specified… + if (type.type) { + var callbacks = callbacksByType[type.type], + callback0 = callbackByName[type.name], + i; + + // Remove the current callback, if any, using copy-on-remove. + if (callback0) { + callback0.value = null; + i = callbacks.indexOf(callback0); + callbacksByType[type.type] = callbacks = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[type.name]; + } + + // Add the new callback, if any. + if (callback) { + callback = {value: callback}; + callbackByName[type.name] = callback; + callbacks.push(callback); + } + } + + // Otherwise, if a null callback was specified, remove all callbacks with the given name. + else if (callback == null) { + for (var otherType in callbacksByType) { + if (callback = callbackByName[otherType + type.name]) { + callback.value = null; + var callbacks = callbacksByType[otherType], i = callbacks.indexOf(callback); + callbacksByType[otherType] = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[callback.name]; + } + } + } + + return that; + }; + + while (++i < n) { + type = types[i] + ""; + if (!type || (type in that)) throw new Error("illegal or duplicate type: " + type); + callbacksByType[type] = []; + that[type] = applier(type); + } + + function parseType(type) { + var i = (type += "").indexOf("."), name = type; + if (i >= 0) type = type.slice(0, i); else name += "."; + if (type && !callbacksByType.hasOwnProperty(type)) throw new Error("unknown type: " + type); + return {type: type, name: name}; + } + + function applier(type) { + return function() { + var callbacks = callbacksByType[type], // Defensive reference; copy-on-remove. + callback, + callbackValue, + i = -1, + n = callbacks.length; + + while (++i < n) { + if (callbackValue = (callback = callbacks[i]).value) { + callbackValue.apply(this, arguments); + } + } + + return that; + }; + } + } + + dispatch.prototype = Dispatch.prototype; + + var version = "0.2.4"; + + exports.version = version; + exports.dispatch = dispatch; + + })); +},{}],5:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dsv', ['exports'], factory) : + factory((global.d3_dsv = {})); + }(this, function (exports) { 'use strict'; + + function dsv(delimiter) { + return new Dsv(delimiter); + } + + function Dsv(delimiter) { + var reFormat = new RegExp("[\"" + delimiter + "\n]"), + delimiterCode = delimiter.charCodeAt(0); + + this.parse = function(text, f) { + var o; + return this.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { return f(a(row), i); } : a; + }); + }; + + this.parseRows = function(text, f) { + var EOL = {}, // sentinel value for end-of-line + EOF = {}, // sentinel value for end-of-file + rows = [], // output rows + N = text.length, + I = 0, // current character index + n = 0, // the current line number + t, // the current token + eol; // is the current token followed by EOL? + + function token() { + if (I >= N) return EOF; // special case: end of file + if (eol) return eol = false, EOL; // special case: end of line + + // special case: quotes + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.slice(j + 1, i).replace(/""/g, "\""); + } + + // common case: find next delimiter or newline + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; // \n + else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n + else if (c !== delimiterCode) continue; + return text.slice(j, I - k); + } + + // special case: last token before EOF + return text.slice(j); + } + + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && (a = f(a, n++)) == null) continue; + rows.push(a); + } + + return rows; + } + + this.format = function(rows) { + if (Array.isArray(rows[0])) return this.formatRows(rows); // deprecated; use formatRows + var fieldSet = Object.create(null), fields = []; + + // Compute unique fields in order of discovery. + rows.forEach(function(row) { + for (var field in row) { + if (!((field += "") in fieldSet)) { + fields.push(fieldSet[field] = field); + } + } + }); + + return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + + this.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + + function formatValue(text) { + return reFormat.test(text) ? "\"" + text.replace(/\"/g, "\"\"") + "\"" : text; + } + }; + + dsv.prototype = Dsv.prototype; + + var csv = dsv(","); + var tsv = dsv("\t"); + + var version = "0.1.9"; + + exports.version = version; + exports.dsv = dsv; + exports.csv = csv; + exports.tsv = tsv; + + })); +},{}],6:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-format', ['exports'], factory) : + factory((global.d3_format = {})); + }(this, function (exports) { 'use strict'; + + var zhCn = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["¥", ""] + }; + + var svSe = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "SEK"] + }; + + var ruRu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0руб."] + }; + + var ptBr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["R$", ""] + }; + + var plPl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "zł"] + }; + + var nlNl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€\xa0", ""] + }; + + var mkMk = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0ден."] + }; + + var koKr = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₩", ""] + }; + + var jaJp = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["", "円"] + }; + + var itIt = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€", ""] + }; + + var huHu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0Ft"] + }; + + var heIl = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₪", ""] + }; + + var frFr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var frCa = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "$"] + }; + + var fiFi = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var esEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var enUs = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var enGb = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["£", ""] + }; + + var enCa = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var deDe = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var deCh = { + decimal: ",", + thousands: "'", + grouping: [3], + currency: ["", "\xa0CHF"] + }; + + var caEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + // Computes the decimal coefficient and exponent of the specified number x with + // significant digits p, where x is positive and p is in [1, 21] or undefined. + // For example, formatDecimal(1.23) returns ["123", 0]. + function formatDecimal(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); + + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; + }; + + function exponent(x) { + return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; + }; + + function formatGroup(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; + + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } + + return t.reverse().join(thousands); + }; + }; + + var prefixExponent; + + function formatPrefixAuto(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! + }; + + function formatRounded(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); + }; + + function formatDefault(x, p) { + x = x.toPrecision(p); + + out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (x[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + case "e": break out; + default: if (i0 > 0) i0 = 0; break; + } + } + + return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; + }; + + var formatTypes = { + "": formatDefault, + "%": function(x, p) { return (x * 100).toFixed(p); }, + "b": function(x) { return Math.round(x).toString(2); }, + "c": function(x) { return x + ""; }, + "d": function(x) { return Math.round(x).toString(10); }, + "e": function(x, p) { return x.toExponential(p); }, + "f": function(x, p) { return x.toFixed(p); }, + "g": function(x, p) { return x.toPrecision(p); }, + "o": function(x) { return Math.round(x).toString(8); }, + "p": function(x, p) { return formatRounded(x * 100, p); }, + "r": formatRounded, + "s": formatPrefixAuto, + "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, + "x": function(x) { return Math.round(x).toString(16); } + }; + + // [[fill]align][sign][symbol][0][width][,][.precision][type] + var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; + + function formatSpecifier(specifier) { + return new FormatSpecifier(specifier); + }; + + function FormatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + + var match, + fill = match[1] || " ", + align = match[2] || ">", + sign = match[3] || "-", + symbol = match[4] || "", + zero = !!match[5], + width = match[6] && +match[6], + comma = !!match[7], + precision = match[8] && +match[8].slice(1), + type = match[9] || ""; + + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; + + // Map invalid types to the default format. + else if (!formatTypes[type]) type = ""; + + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + + this.fill = fill; + this.align = align; + this.sign = sign; + this.symbol = symbol; + this.zero = zero; + this.width = width; + this.comma = comma; + this.precision = precision; + this.type = type; + } + + FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width == null ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + + this.type; + }; + + var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; + + function identity(x) { + return x; + } + + function locale(locale) { + var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity, + currency = locale.currency, + decimal = locale.decimal; + + function format(specifier) { + specifier = formatSpecifier(specifier); + + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + type = specifier.type; + + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; + + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = !type || /[defgprs%]/.test(type); + + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision == null ? (type ? 6 : 12) + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); + + return function(value) { + var valuePrefix = prefix, + valueSuffix = suffix; + + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; + + // Convert negative to positive, and compute the prefix. + // Note that -0 is not less than 0, but 1 / -0 is! + var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true); + + // Perform the initial formatting. + value = formatType(value, precision); + + // If the original value was negative, it may be rounded to zero during + // formatting; treat this as (positive) zero. + if (valueNegative) { + var i = -1, n = value.length, c; + valueNegative = false; + while (++i < n) { + if (c = value.charCodeAt(i), (48 < c && c < 58) + || (type === "x" && 96 < c && c < 103) + || (type === "X" && 64 < c && c < 71)) { + valueNegative = true; + break; + } + } + } + + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); + + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + var i = -1, n = value.length, c; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } + + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); + + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; + + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": return valuePrefix + value + valueSuffix + padding; + case "=": return valuePrefix + padding + value + valueSuffix; + case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); + } + return padding + valuePrefix + value + valueSuffix; + }; + } + + function formatPrefix(specifier, value) { + var f = format((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; + } + + return { + format: format, + formatPrefix: formatPrefix + }; + }; + + function precisionFixed(step) { + return Math.max(0, -exponent(Math.abs(step))); + }; + + function precisionPrefix(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); + }; + + function precisionRound(step, max) { + return Math.max(0, exponent(Math.abs(max)) - exponent(Math.abs(step))) + 1; + }; + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": enUs, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(enUs); + var format = defaultLocale.format; + var formatPrefix = defaultLocale.formatPrefix; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.3.6"; + + exports.version = version; + exports.format = format; + exports.formatPrefix = formatPrefix; + exports.localeFormat = localeFormat; + exports.formatSpecifier = formatSpecifier; + exports.precisionFixed = precisionFixed; + exports.precisionPrefix = precisionPrefix; + exports.precisionRound = precisionRound; + + })); +},{}],7:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-time')) : + typeof define === 'function' && define.amd ? define('d3-time-format', ['exports', 'd3-time'], factory) : + factory((global.d3_time_format = {}),global.d3_time); + }(this, function (exports,d3Time) { 'use strict'; + + var zhCn = { + dateTime: "%a %b %e %X %Y", + date: "%Y/%-m/%-d", + time: "%H:%M:%S", + periods: ["上午", "下午"], + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + shortMonths: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] + }; + + var svSe = { + dateTime: "%A den %d %B %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["fm", "em"], + days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"], + shortDays: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"], + months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] + }; + + var ruRu = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"], + shortDays: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"], + months: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"], + shortMonths: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"] + }; + + var ptBr = { + dateTime: "%A, %e de %B de %Y. %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"], + shortDays: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"], + months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], + shortMonths: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"] + }; + + var plPl = { + dateTime: "%A, %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"], + shortDays: ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."], + months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"], + shortMonths: ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."]/* In Polish language abbraviated months are not commonly used so there is a dispute about the proper abbraviations. */ + }; + + var nlNl = { + dateTime: "%a %e %B %Y %T", + date: "%d-%m-%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], + shortDays: ["zo", "ma", "di", "wo", "do", "vr", "za"], + months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], + shortMonths: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] + }; + + var mkMk = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"], + shortDays: ["нед", "пон", "вто", "сре", "чет", "пет", "саб"], + months: ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"], + shortMonths: ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"] + }; + + var koKr = { + dateTime: "%Y/%m/%d %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["오전", "오후"], + days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"], + shortDays: ["일", "월", "화", "수", "목", "금", "토"], + months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], + shortMonths: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"] + }; + + var jaJp = { + dateTime: "%Y %b %e %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"], + shortDays: ["日", "月", "火", "水", "木", "金", "土"], + months: ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"], + shortMonths: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"] + }; + + var itIt = { + dateTime: "%A %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"], + shortDays: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"], + months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], + shortMonths: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"] + }; + + var huHu = { + dateTime: "%Y. %B %-e., %A %X", + date: "%Y. %m. %d.", + time: "%H:%M:%S", + periods: ["de.", "du."], // unused + days: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"], + shortDays: ["V", "H", "K", "Sze", "Cs", "P", "Szo"], + months: ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"], + shortMonths: ["jan.", "feb.", "már.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec."] + }; + + var heIl = { + dateTime: "%A, %e ב%B %Y %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"], + shortDays: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"], + months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], + shortMonths: ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"] + }; + + var frFr = { + dateTime: "%A, le %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."] + }; + + var frCa = { + dateTime: "%a %e %b %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["", ""], + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"] + }; + + var fiFi = { + dateTime: "%A, %-d. %Bta %Y klo %X", + date: "%-d.%-m.%Y", + time: "%H:%M:%S", + periods: ["a.m.", "p.m."], + days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"], + shortDays: ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"], + months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], + shortMonths: ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"] + }; + + var esEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], + shortDays: ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], + months: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], + shortMonths: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] + }; + + var locale$1 = { + dateTime: "%a %b %e %X %Y", + date: "%m/%d/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }; + + var enGb = { + dateTime: "%a %e %b %X %Y", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }; + + var enCa = { + dateTime: "%a %b %e %X %Y", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }; + + var deDe = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var deCh = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var caEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"], + shortDays: ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."], + months: ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"], + shortMonths: ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."] + }; + + function localDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); + date.setFullYear(d.y); + return date; + } + return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); + } + + function utcDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); + date.setUTCFullYear(d.y); + return date; + } + return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); + } + + function newYear(y) { + return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; + } + + function locale(locale) { + var locale_dateTime = locale.dateTime, + locale_date = locale.date, + locale_time = locale.time, + locale_periods = locale.periods, + locale_weekdays = locale.days, + locale_shortWeekdays = locale.shortDays, + locale_months = locale.months, + locale_shortMonths = locale.shortMonths; + + var periodLookup = formatLookup(locale_periods), + weekdayRe = formatRe(locale_weekdays), + weekdayLookup = formatLookup(locale_weekdays), + shortWeekdayRe = formatRe(locale_shortWeekdays), + shortWeekdayLookup = formatLookup(locale_shortWeekdays), + monthRe = formatRe(locale_months), + monthLookup = formatLookup(locale_months), + shortMonthRe = formatRe(locale_shortMonths), + shortMonthLookup = formatLookup(locale_shortMonths); + + var formats = { + "a": formatShortWeekday, + "A": formatWeekday, + "b": formatShortMonth, + "B": formatMonth, + "c": null, + "d": formatDayOfMonth, + "e": formatDayOfMonth, + "H": formatHour24, + "I": formatHour12, + "j": formatDayOfYear, + "L": formatMilliseconds, + "m": formatMonthNumber, + "M": formatMinutes, + "p": formatPeriod, + "S": formatSeconds, + "U": formatWeekNumberSunday, + "w": formatWeekdayNumber, + "W": formatWeekNumberMonday, + "x": null, + "X": null, + "y": formatYear, + "Y": formatFullYear, + "Z": formatZone, + "%": formatLiteralPercent + }; + + var utcFormats = { + "a": formatUTCShortWeekday, + "A": formatUTCWeekday, + "b": formatUTCShortMonth, + "B": formatUTCMonth, + "c": null, + "d": formatUTCDayOfMonth, + "e": formatUTCDayOfMonth, + "H": formatUTCHour24, + "I": formatUTCHour12, + "j": formatUTCDayOfYear, + "L": formatUTCMilliseconds, + "m": formatUTCMonthNumber, + "M": formatUTCMinutes, + "p": formatUTCPeriod, + "S": formatUTCSeconds, + "U": formatUTCWeekNumberSunday, + "w": formatUTCWeekdayNumber, + "W": formatUTCWeekNumberMonday, + "x": null, + "X": null, + "y": formatUTCYear, + "Y": formatUTCFullYear, + "Z": formatUTCZone, + "%": formatLiteralPercent + }; + + var parses = { + "a": parseShortWeekday, + "A": parseWeekday, + "b": parseShortMonth, + "B": parseMonth, + "c": parseLocaleDateTime, + "d": parseDayOfMonth, + "e": parseDayOfMonth, + "H": parseHour24, + "I": parseHour24, + "j": parseDayOfYear, + "L": parseMilliseconds, + "m": parseMonthNumber, + "M": parseMinutes, + "p": parsePeriod, + "S": parseSeconds, + "U": parseWeekNumberSunday, + "w": parseWeekdayNumber, + "W": parseWeekNumberMonday, + "x": parseLocaleDate, + "X": parseLocaleTime, + "y": parseYear, + "Y": parseFullYear, + "Z": parseZone, + "%": parseLiteralPercent + }; + + // These recursive directive definitions must be deferred. + formats.x = newFormat(locale_date, formats); + formats.X = newFormat(locale_time, formats); + formats.c = newFormat(locale_dateTime, formats); + utcFormats.x = newFormat(locale_date, utcFormats); + utcFormats.X = newFormat(locale_time, utcFormats); + utcFormats.c = newFormat(locale_dateTime, utcFormats); + + function newFormat(specifier, formats) { + return function(date) { + var string = [], + i = -1, + j = 0, + n = specifier.length, + c, + pad, + format; + + while (++i < n) { + if (specifier.charCodeAt(i) === 37) { + string.push(specifier.slice(j, i)); + if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); + if (format = formats[c]) c = format(date, pad == null ? (c === "e" ? " " : "0") : pad); + string.push(c); + j = i + 1; + } + } + + string.push(specifier.slice(j, i)); + return string.join(""); + }; + } + + function newParse(specifier, newDate) { + return function(string) { + var d = newYear(1900), + i = parseSpecifier(d, specifier, string, 0); + if (i != string.length) return null; + + // The am-pm flag is 0 for AM, and 1 for PM. + if ("p" in d) d.H = d.H % 12 + d.p * 12; + + // If a time zone is specified, all fields are interpreted as UTC and then + // offset according to the specified time zone. + if ("Z" in d) { + if ("w" in d && ("W" in d || "U" in d)) { + var day = utcDate(newYear(d.y)).getUTCDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + d.H += d.Z / 100 | 0; + d.M += d.Z % 100; + return utcDate(d); + } + + // Otherwise, all fields are in local time. + if ("w" in d && ("W" in d || "U" in d)) { + var day = newDate(newYear(d.y)).getDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + return newDate(d); + }; + } + + function parseSpecifier(d, specifier, string, j) { + var i = 0, + n = specifier.length, + m = string.length, + c, + parse; + + while (i < n) { + if (j >= m) return -1; + c = specifier.charCodeAt(i++); + if (c === 37) { + c = specifier.charAt(i++); + parse = parses[c in pads ? specifier.charAt(i++) : c]; + if (!parse || ((j = parse(d, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + + return j; + } + + function parseShortWeekday(d, string, i) { + var n = shortWeekdayRe.exec(string.slice(i)); + return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseWeekday(d, string, i) { + var n = weekdayRe.exec(string.slice(i)); + return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseShortMonth(d, string, i) { + var n = shortMonthRe.exec(string.slice(i)); + return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseMonth(d, string, i) { + var n = monthRe.exec(string.slice(i)); + return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseLocaleDateTime(d, string, i) { + return parseSpecifier(d, locale_dateTime, string, i); + } + + function parseLocaleDate(d, string, i) { + return parseSpecifier(d, locale_date, string, i); + } + + function parseLocaleTime(d, string, i) { + return parseSpecifier(d, locale_time, string, i); + } + + function parsePeriod(d, string, i) { + var n = periodLookup[string.slice(i, i += 2).toLowerCase()]; + return n == null ? -1 : (d.p = n, i); + } + + function formatShortWeekday(d) { + return locale_shortWeekdays[d.getDay()]; + } + + function formatWeekday(d) { + return locale_weekdays[d.getDay()]; + } + + function formatShortMonth(d) { + return locale_shortMonths[d.getMonth()]; + } + + function formatMonth(d) { + return locale_months[d.getMonth()]; + } + + function formatPeriod(d) { + return locale_periods[+(d.getHours() >= 12)]; + } + + function formatUTCShortWeekday(d) { + return locale_shortWeekdays[d.getUTCDay()]; + } + + function formatUTCWeekday(d) { + return locale_weekdays[d.getUTCDay()]; + } + + function formatUTCShortMonth(d) { + return locale_shortMonths[d.getUTCMonth()]; + } + + function formatUTCMonth(d) { + return locale_months[d.getUTCMonth()]; + } + + function formatUTCPeriod(d) { + return locale_periods[+(d.getUTCHours() >= 12)]; + } + + return { + format: function(specifier) { + var f = newFormat(specifier += "", formats); + f.parse = newParse(specifier, localDate); + f.toString = function() { return specifier; }; + return f; + }, + utcFormat: function(specifier) { + var f = newFormat(specifier += "", utcFormats); + f.parse = newParse(specifier, utcDate); + f.toString = function() { return specifier; }; + return f; + } + }; + }; + + var pads = {"-": "", "_": " ", "0": "0"}; + var numberRe = /^\s*\d+/; + var percentRe = /^%/; + var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + function pad(value, fill, width) { + var sign = value < 0 ? "-" : "", + string = (sign ? -value : value) + "", + length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); + } + + function requote(s) { + return s.replace(requoteRe, "\\$&"); + } + + function formatRe(names) { + return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); + } + + function formatLookup(names) { + var map = {}, i = -1, n = names.length; + while (++i < n) map[names[i].toLowerCase()] = i; + return map; + } + + function parseWeekdayNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.w = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.U = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.W = +n[0], i + n[0].length) : -1; + } + + function parseFullYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 4)); + return n ? (d.y = +n[0], i + n[0].length) : -1; + } + + function parseYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; + } + + function parseZone(d, string, i) { + var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); + if (n) { + d.Z = n[1] ? 0 // 'Z' for UTC + : n[3] ? -(n[2] + n[3]) // sign differs from getTimezoneOffset! + : -n[2] * 100; + return i + n[0].length; + } + return -1; + } + + function parseMonthNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.m = n[0] - 1, i + n[0].length) : -1; + } + + function parseDayOfMonth(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.d = +n[0], i + n[0].length) : -1; + } + + function parseDayOfYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; + } + + function parseHour24(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.H = +n[0], i + n[0].length) : -1; + } + + function parseMinutes(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.M = +n[0], i + n[0].length) : -1; + } + + function parseSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.S = +n[0], i + n[0].length) : -1; + } + + function parseMilliseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.L = +n[0], i + n[0].length) : -1; + } + + function parseLiteralPercent(d, string, i) { + var n = percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; + } + + function formatDayOfMonth(d, p) { + return pad(d.getDate(), p, 2); + } + + function formatHour24(d, p) { + return pad(d.getHours(), p, 2); + } + + function formatHour12(d, p) { + return pad(d.getHours() % 12 || 12, p, 2); + } + + function formatDayOfYear(d, p) { + return pad(1 + d3Time.day.count(d3Time.year(d), d), p, 3); + } + + function formatMilliseconds(d, p) { + return pad(d.getMilliseconds(), p, 3); + } + + function formatMonthNumber(d, p) { + return pad(d.getMonth() + 1, p, 2); + } + + function formatMinutes(d, p) { + return pad(d.getMinutes(), p, 2); + } + + function formatSeconds(d, p) { + return pad(d.getSeconds(), p, 2); + } + + function formatWeekNumberSunday(d, p) { + return pad(d3Time.sunday.count(d3Time.year(d), d), p, 2); + } + + function formatWeekdayNumber(d) { + return d.getDay(); + } + + function formatWeekNumberMonday(d, p) { + return pad(d3Time.monday.count(d3Time.year(d), d), p, 2); + } + + function formatYear(d, p) { + return pad(d.getFullYear() % 100, p, 2); + } + + function formatFullYear(d, p) { + return pad(d.getFullYear() % 10000, p, 4); + } + + function formatZone(d) { + var z = d.getTimezoneOffset(); + return (z > 0 ? "-" : (z *= -1, "+")) + + pad(z / 60 | 0, "0", 2) + + pad(z % 60, "0", 2); + } + + function formatUTCDayOfMonth(d, p) { + return pad(d.getUTCDate(), p, 2); + } + + function formatUTCHour24(d, p) { + return pad(d.getUTCHours(), p, 2); + } + + function formatUTCHour12(d, p) { + return pad(d.getUTCHours() % 12 || 12, p, 2); + } + + function formatUTCDayOfYear(d, p) { + return pad(1 + d3Time.utcDay.count(d3Time.utcYear(d), d), p, 3); + } + + function formatUTCMilliseconds(d, p) { + return pad(d.getUTCMilliseconds(), p, 3); + } + + function formatUTCMonthNumber(d, p) { + return pad(d.getUTCMonth() + 1, p, 2); + } + + function formatUTCMinutes(d, p) { + return pad(d.getUTCMinutes(), p, 2); + } + + function formatUTCSeconds(d, p) { + return pad(d.getUTCSeconds(), p, 2); + } + + function formatUTCWeekNumberSunday(d, p) { + return pad(d3Time.utcSunday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCWeekdayNumber(d) { + return d.getUTCDay(); + } + + function formatUTCWeekNumberMonday(d, p) { + return pad(d3Time.utcMonday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCYear(d, p) { + return pad(d.getUTCFullYear() % 100, p, 2); + } + + function formatUTCFullYear(d, p) { + return pad(d.getUTCFullYear() % 10000, p, 4); + } + + function formatUTCZone() { + return "+0000"; + } + + function formatLiteralPercent() { + return "%"; + } + + var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; + + function formatIsoNative(date) { + return date.toISOString(); + } + + formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + + formatIsoNative.toString = function() { + return isoSpecifier; + }; + + var formatIso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") + ? formatIsoNative + : locale$1.utcFormat(isoSpecifier); + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": locale$1, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(locale$1); + var format = defaultLocale.format; + var utcFormat = defaultLocale.utcFormat; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.1.5"; + + exports.version = version; + exports.format = format; + exports.utcFormat = utcFormat; + exports.localeFormat = localeFormat; + exports.isoFormat = formatIso; + + })); +},{"d3-time":8}],8:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-time', ['exports'], factory) : + factory((global.d3_time = {})); + }(this, function (exports) { 'use strict'; + + var t0 = new Date; + var t1 = new Date; + function newInterval(floori, offseti, count) { + + function interval(date) { + return floori(date = new Date(+date)), date; + } + + interval.floor = interval; + + interval.round = function(date) { + var d0 = new Date(+date), + d1 = new Date(date - 1); + floori(d0), floori(d1), offseti(d1, 1); + return date - d0 < d1 - date ? d0 : d1; + }; + + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), date; + }; + + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; + + interval.range = function(start, stop, step) { + var range = []; + start = new Date(start - 1); + stop = new Date(+stop); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + offseti(start, 1), floori(start); + if (start < stop) range.push(new Date(+start)); + while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start)); + return range; + }; + + interval.filter = function(test) { + return newInterval(function(date) { + while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + while (--step >= 0) while (offseti(date, 1), !test(date)); + }); + }; + + if (count) interval.count = function(start, end) { + t0.setTime(+start), t1.setTime(+end); + floori(t0), floori(t1); + return Math.floor(count(t0, t1)); + }; + + return interval; + }; + + var millisecond = newInterval(function() { + // noop + }, function(date, step) { + date.setTime(+date + step); + }, function(start, end) { + return end - start; + }); + + var second = newInterval(function(date) { + date.setMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var minute = newInterval(function(date) { + date.setSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var hour = newInterval(function(date) { + date.setMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5; + }); + + function weekday(i) { + return newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5; + }); + } + + var sunday = weekday(0); + var monday = weekday(1); + var tuesday = weekday(2); + var wednesday = weekday(3); + var thursday = weekday(4); + var friday = weekday(5); + var saturday = weekday(6); + + var month = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(1); + }, function(date, step) { + date.setMonth(date.getMonth() + step); + }, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; + }); + + var year = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setMonth(0, 1); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step); + }, function(start, end) { + return end.getFullYear() - start.getFullYear(); + }); + + var utcSecond = newInterval(function(date) { + date.setUTCMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); + }, function(start, end) { + return (end - start) / 864e5; + }); + + function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / 6048e5; + }); + } + + var utcSunday = utcWeekday(0); + var utcMonday = utcWeekday(1); + var utcTuesday = utcWeekday(2); + var utcWednesday = utcWeekday(3); + var utcThursday = utcWeekday(4); + var utcFriday = utcWeekday(5); + var utcSaturday = utcWeekday(6); + + var utcMonth = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(1); + }, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); + }, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; + }); + + var utcYear = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCMonth(0, 1); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); + }, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); + }); + + var milliseconds = millisecond.range; + var seconds = second.range; + var minutes = minute.range; + var hours = hour.range; + var days = day.range; + var sundays = sunday.range; + var mondays = monday.range; + var tuesdays = tuesday.range; + var wednesdays = wednesday.range; + var thursdays = thursday.range; + var fridays = friday.range; + var saturdays = saturday.range; + var weeks = sunday.range; + var months = month.range; + var years = year.range; + + var utcMillisecond = millisecond; + var utcMilliseconds = milliseconds; + var utcSeconds = utcSecond.range; + var utcMinutes = utcMinute.range; + var utcHours = utcHour.range; + var utcDays = utcDay.range; + var utcSundays = utcSunday.range; + var utcMondays = utcMonday.range; + var utcTuesdays = utcTuesday.range; + var utcWednesdays = utcWednesday.range; + var utcThursdays = utcThursday.range; + var utcFridays = utcFriday.range; + var utcSaturdays = utcSaturday.range; + var utcWeeks = utcSunday.range; + var utcMonths = utcMonth.range; + var utcYears = utcYear.range; + + var version = "0.0.7"; + + exports.version = version; + exports.milliseconds = milliseconds; + exports.seconds = seconds; + exports.minutes = minutes; + exports.hours = hours; + exports.days = days; + exports.sundays = sundays; + exports.mondays = mondays; + exports.tuesdays = tuesdays; + exports.wednesdays = wednesdays; + exports.thursdays = thursdays; + exports.fridays = fridays; + exports.saturdays = saturdays; + exports.weeks = weeks; + exports.months = months; + exports.years = years; + exports.utcMillisecond = utcMillisecond; + exports.utcMilliseconds = utcMilliseconds; + exports.utcSeconds = utcSeconds; + exports.utcMinutes = utcMinutes; + exports.utcHours = utcHours; + exports.utcDays = utcDays; + exports.utcSundays = utcSundays; + exports.utcMondays = utcMondays; + exports.utcTuesdays = utcTuesdays; + exports.utcWednesdays = utcWednesdays; + exports.utcThursdays = utcThursdays; + exports.utcFridays = utcFridays; + exports.utcSaturdays = utcSaturdays; + exports.utcWeeks = utcWeeks; + exports.utcMonths = utcMonths; + exports.utcYears = utcYears; + exports.millisecond = millisecond; + exports.second = second; + exports.minute = minute; + exports.hour = hour; + exports.day = day; + exports.sunday = sunday; + exports.monday = monday; + exports.tuesday = tuesday; + exports.wednesday = wednesday; + exports.thursday = thursday; + exports.friday = friday; + exports.saturday = saturday; + exports.week = sunday; + exports.month = month; + exports.year = year; + exports.utcSecond = utcSecond; + exports.utcMinute = utcMinute; + exports.utcHour = utcHour; + exports.utcDay = utcDay; + exports.utcSunday = utcSunday; + exports.utcMonday = utcMonday; + exports.utcTuesday = utcTuesday; + exports.utcWednesday = utcWednesday; + exports.utcThursday = utcThursday; + exports.utcFriday = utcFriday; + exports.utcSaturday = utcSaturday; + exports.utcWeek = utcSunday; + exports.utcMonth = utcMonth; + exports.utcYear = utcYear; + exports.interval = newInterval; + + })); +},{}],9:[function(require,module,exports){ + var util = require('../util'), + Measures = require('./measures'), + Collector = require('./collector'); + + function Aggregator() { + this._cells = {}; + this._aggr = []; + this._stream = false; + } + + var Flags = Aggregator.Flags = { + ADD_CELL: 1, + MOD_CELL: 2 + }; + + var proto = Aggregator.prototype; + +// Parameters + + proto.stream = function(v) { + if (v == null) return this._stream; + this._stream = !!v; + this._aggr = []; + return this; + }; + +// key accessor to use for streaming removes + proto.key = function(key) { + if (key == null) return this._key; + this._key = util.$(key); + return this; + }; + +// Input: array of objects of the form +// {name: string, get: function} + proto.groupby = function(dims) { + this._dims = util.array(dims).map(function(d, i) { + d = util.isString(d) ? {name: d, get: util.$(d)} + : util.isFunction(d) ? {name: util.name(d) || d.name || ('_' + i), get: d} + : (d.name && util.isFunction(d.get)) ? d : null; + if (d == null) throw 'Invalid groupby argument: ' + d; + return d; + }); + return this.clear(); + }; + +// Input: array of objects of the form +// {name: string, ops: [string, ...]} + proto.summarize = function(fields) { + fields = summarize_args(fields); + this._count = true; + var aggr = (this._aggr = []), + m, f, i, j, op, as, get; + + for (i=0; i 0) { + // consolidate collector values + if (cell.collect) { + cell.data.values(); + } + // update tuple properties + for (i=0; i 0) { + m[a[i]] -= 1; + } else { + x[j++] = a[i]; + } + } + } else if (k) { + // has unique key field, so use that + m = util.toMap(r, k); + for (i=0, j=0, n=a.length; i 1 ? this.dev / (this.valid-1) : 0', + req: ['mean'], idx: 1 + }), + 'variancep': measure({ + name: 'variancep', + set: 'this.valid > 1 ? this.dev / this.valid : 0', + req: ['variance'], idx: 2 + }), + 'stdev': measure({ + name: 'stdev', + set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0', + req: ['variance'], idx: 2 + }), + 'stdevp': measure({ + name: 'stdevp', + set: 'this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0', + req: ['variance'], idx: 2 + }), + 'median': measure({ + name: 'median', + set: 'cell.data.q2(this.get)', + req: ['values'], idx: 3 + }), + 'q1': measure({ + name: 'q1', + set: 'cell.data.q1(this.get)', + req: ['values'], idx: 3 + }), + 'q3': measure({ + name: 'q3', + set: 'cell.data.q3(this.get)', + req: ['values'], idx: 3 + }), + 'distinct': measure({ + name: 'distinct', + set: 'this.distinct(cell.data.values(), this.get)', + req: ['values'], idx: 3 + }), + 'argmin': measure({ + name: 'argmin', + add: 'if (v < this.min) this.argmin = t;', + rem: 'if (v <= this.min) this.argmin = null;', + set: 'this.argmin = this.argmin || cell.data.argmin(this.get)', + req: ['min'], str: ['values'], idx: 3 + }), + 'argmax': measure({ + name: 'argmax', + add: 'if (v > this.max) this.argmax = t;', + rem: 'if (v >= this.max) this.argmax = null;', + set: 'this.argmax = this.argmax || cell.data.argmax(this.get)', + req: ['max'], str: ['values'], idx: 3 + }), + 'min': measure({ + name: 'min', + init: 'this.min = +Infinity;', + add: 'if (v < this.min) this.min = v;', + rem: 'if (v <= this.min) this.min = NaN;', + set: 'this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)', + str: ['values'], idx: 4 + }), + 'max': measure({ + name: 'max', + init: 'this.max = -Infinity;', + add: 'if (v > this.max) this.max = v;', + rem: 'if (v >= this.max) this.max = NaN;', + set: 'this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)', + str: ['values'], idx: 4 + }), + 'modeskew': measure({ + name: 'modeskew', + set: 'this.dev===0 ? 0 : (this.mean - cell.data.q2(this.get)) / Math.sqrt(this.dev/(this.valid-1))', + req: ['mean', 'stdev', 'median'], idx: 5 + }) + }; + + function measure(base) { + return function(out) { + var m = util.extend({init:'', add:'', rem:'', idx:0}, base); + m.out = out || base.name; + return m; + }; + } + + function resolve(agg, stream) { + function collect(m, a) { + function helper(r) { if (!m[r]) collect(m, m[r] = types[r]()); } + if (a.req) a.req.forEach(helper); + if (stream && a.str) a.str.forEach(helper); + return m; + } + var map = agg.reduce( + collect, + agg.reduce(function(m, a) { return (m[a.name] = a, m); }, {}) + ); + return util.vals(map).sort(function(a, b) { return a.idx - b.idx; }); + } + + function create(agg, stream, accessor, mutator) { + var all = resolve(agg, stream), + ctr = 'this.cell = cell; this.tuple = t; this.valid = 0; this.missing = 0;', + add = 'if (v==null) this.missing++; if (!this.isValid(v)) return; ++this.valid;', + rem = 'if (v==null) this.missing--; if (!this.isValid(v)) return; --this.valid;', + set = 'var t = this.tuple; var cell = this.cell;'; + + all.forEach(function(a) { + if (a.idx < 0) { + ctr = a.init + ctr; + add = a.add + add; + rem = a.rem + rem; + } else { + ctr += a.init; + add += a.add; + rem += a.rem; + } + }); + agg.slice() + .sort(function(a, b) { return a.idx - b.idx; }) + .forEach(function(a) { + set += 'this.assign(t,\''+a.out+'\','+a.set+');'; + }); + set += 'return t;'; + + /* jshint evil: true */ + ctr = Function('cell', 't', ctr); + ctr.prototype.assign = mutator; + ctr.prototype.add = Function('t', 'var v = this.get(t);' + add); + ctr.prototype.rem = Function('t', 'var v = this.get(t);' + rem); + ctr.prototype.set = Function(set); + ctr.prototype.get = accessor; + ctr.prototype.distinct = require('../stats').count.distinct; + ctr.prototype.isValid = util.isValid; + ctr.fields = agg.map(util.$('out')); + return ctr; + } + + types.create = create; + module.exports = types; + +},{"../stats":28,"../util":31}],13:[function(require,module,exports){ + var util = require('../util'), + time = require('../time'), + EPSILON = 1e-15; + + function bins(opt) { + if (!opt) { throw Error("Missing binning options."); } + + // determine range + var maxb = opt.maxbins || 15, + base = opt.base || 10, + logb = Math.log(base), + div = opt.div || [5, 2], + min = opt.min, + max = opt.max, + span = max - min, + step, level, minstep, precision, v, i, eps; + + if (opt.step) { + // if step size is explicitly given, use that + step = opt.step; + } else if (opt.steps) { + // if provided, limit choice to acceptable step sizes + step = opt.steps[Math.min( + opt.steps.length - 1, + bisect(opt.steps, span/maxb, 0, opt.steps.length) + )]; + } else { + // else use span to determine step size + level = Math.ceil(Math.log(maxb) / logb); + minstep = opt.minstep || 0; + step = Math.max( + minstep, + Math.pow(base, Math.round(Math.log(span) / logb) - level) + ); + + // increase step size if too many bins + do { step *= base; } while (Math.ceil(span/step) > maxb); + + // decrease step size if allowed + for (i=0; i= minstep && span / v <= maxb) step = v; + } + } + + // update precision, min and max + v = Math.log(step); + precision = v >= 0 ? 0 : ~~(-v / logb) + 1; + eps = Math.pow(base, -precision - 1); + min = Math.min(min, Math.floor(min / step + eps) * step); + max = Math.ceil(max / step) * step; + + return { + start: min, + stop: max, + step: step, + unit: {precision: precision}, + value: value, + index: index + }; + } + + function bisect(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (util.cmp(a[mid], x) < 0) { lo = mid + 1; } + else { hi = mid; } + } + return lo; + } + + function value(v) { + return this.step * Math.floor(v / this.step + EPSILON); + } + + function index(v) { + return Math.floor((v - this.start) / this.step + EPSILON); + } + + function date_value(v) { + return this.unit.date(value.call(this, v)); + } + + function date_index(v) { + return index.call(this, this.unit.unit(v)); + } + + bins.date = function(opt) { + if (!opt) { throw Error("Missing date binning options."); } + + // find time step, then bin + var units = opt.utc ? time.utc : time, + dmin = opt.min, + dmax = opt.max, + maxb = opt.maxbins || 20, + minb = opt.minbins || 4, + span = (+dmax) - (+dmin), + unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb), + spec = bins({ + min: unit.min != null ? unit.min : unit.unit(dmin), + max: unit.max != null ? unit.max : unit.unit(dmax), + maxbins: maxb, + minstep: unit.minstep, + steps: unit.step + }); + + spec.unit = unit; + spec.index = date_index; + if (!opt.raw) spec.value = date_value; + return spec; + }; + + module.exports = bins; + +},{"../time":30,"../util":31}],14:[function(require,module,exports){ + var bins = require('./bins'), + gen = require('../generate'), + type = require('../import/type'), + util = require('../util'), + stats = require('../stats'); + + var qtype = { + 'integer': 1, + 'number': 1, + 'date': 1 + }; + + function $bin(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return !b ? (opt.accessor || util.identity) : + util.$func('bin', b.unit.unit ? + function(x) { return b.value(b.unit.unit(x)); } : + function(x) { return b.value(x); } + )(opt.accessor); + } + + function histogram(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return b ? + numerical(values, opt.accessor, b) : + categorical(values, opt.accessor, opt && opt.sort); + } + + function spec(opt) { + var t = opt.type, b = null; + if (t == null || qtype[t]) { + if (t === 'integer' && opt.minstep == null) opt.minstep = 1; + b = (t === 'date') ? bins.date(opt) : bins(opt); + } + return b; + } + + function options() { + var a = arguments, + i = 0, + values = util.isArray(a[i]) ? a[i++] : null, + f = util.isFunction(a[i]) || util.isString(a[i]) ? util.$(a[i++]) : null, + opt = util.extend({}, a[i]); + + if (values) { + opt.type = opt.type || type(values, f); + if (qtype[opt.type]) { + var ext = stats.extent(values, f); + opt = util.extend({min: ext[0], max: ext[1]}, opt); + } + } + if (f) { opt.accessor = f; } + return opt; + } + + function numerical(values, f, b) { + var h = gen.range(b.start, b.stop + b.step/2, b.step) + .map(function(v) { return {value: b.value(v), count: 0}; }); + + for (var i=0, v, j; i= h.length || !isFinite(j)) continue; + h[j].count += 1; + } + } + h.bins = b; + return h; + } + + function categorical(values, f, sort) { + var u = stats.unique(values, f), + c = stats.count.map(values, f); + return u.map(function(k) { return {value: k, count: c[k]}; }) + .sort(util.comparator(sort ? '-count' : '+value')); + } + + module.exports = { + $bin: $bin, + histogram: histogram + }; + +},{"../generate":16,"../import/type":25,"../stats":28,"../util":31,"./bins":13}],15:[function(require,module,exports){ + var d3_time = require('d3-time'), + d3_timeF = require('d3-time-format'), + d3_numberF = require('d3-format'), + numberF = d3_numberF, // defaults to EN-US + timeF = d3_timeF; // defaults to EN-US + + function numberLocale(l) { + var f = d3_numberF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + numberF = f; + } + + function timeLocale(l) { + var f = d3_timeF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + timeF = f; + } + + module.exports = { + // Update number formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-format + numberLocale: numberLocale, + number: function(f) { return numberF.format(f); }, + numberPrefix: function(f, v) { return numberF.formatPrefix(f, v); }, + + // Update time formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-time-format + timeLocale: timeLocale, + time: function(f) { return timeF.format(f); }, + utc: function(f) { return timeF.utcFormat(f); }, + + // Set number and time locale simultaneously. + locale: function(l) { numberLocale(l); timeLocale(l); }, + + // automatic formatting functions + auto: { + number: numberAutoFormat, + time: function() { return timeAutoFormat(); }, + utc: function() { return utcAutoFormat(); } + } + }; + + var e10 = Math.sqrt(50), + e5 = Math.sqrt(10), + e2 = Math.sqrt(2); + + function intervals(domain, count) { + if (!domain.length) domain = [0]; + if (count == null) count = 10; + + var start = domain[0], + stop = domain[domain.length - 1]; + + if (stop < start) { error = stop; stop = start; start = error; } + + var span = (stop - start) || (count = 1, start || stop || 1), + step = Math.pow(10, Math.floor(Math.log(span / count) / Math.LN10)), + error = span / count / step; + + // Filter ticks to get closer to the desired count. + if (error >= e10) step *= 10; + else if (error >= e5) step *= 5; + else if (error >= e2) step *= 2; + + // Round start and stop values to step interval. + return [ + Math.ceil(start / step) * step, + Math.floor(stop / step) * step + step / 2, // inclusive + step + ]; + } + + function significantDigits(domain) { + return domain.map(function(x) { + // determine significant digits based on exponential format + var s = x.toExponential(), + e = s.indexOf('e'), + d = s.indexOf('.'); + return d < 0 ? 1 : (e-d); + }).reduce(function(max, p) { + // return the maximum sig digit count + return Math.max(max, p); + }, 0); + } + + function numberAutoFormat(domain, count, f) { + var range = intervals(domain, count); + if (f == null) { + f = ',.' + d3_numberF.precisionFixed(range[2]) + 'f'; + } else { + switch (f = d3_numberF.formatSpecifier(f), f.type) { + case 's': { + if (f.precision == null) f.precision = significantDigits(domain); + return numberF.format(f); + } + case '': + case 'e': + case 'g': + case 'p': + case 'r': { + if (f.precision == null) f.precision = d3_numberF.precisionRound(range[2], Math.max(Math.abs(range[0]), Math.abs(range[1]))) - (f.type === 'e'); + break; + } + case 'f': + case '%': { + if (f.precision == null) f.precision = d3_numberF.precisionFixed(range[2]) - (f.type === '%') * 2; + break; + } + } + } + return numberF.format(f); + } + + function timeAutoFormat() { + var f = timeF.format, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.second(date) < d ? formatMillisecond + : d3_time.minute(date) < d ? formatSecond + : d3_time.hour(date) < d ? formatMinute + : d3_time.day(date) < d ? formatHour + : d3_time.month(date) < d ? + (d3_time.week(date) < d ? formatDay : formatWeek) + : d3_time.year(date) < d ? formatMonth + : formatYear)(date); + }; + } + + function utcAutoFormat() { + var f = timeF.utcFormat, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.utcSecond(date) < d ? formatMillisecond + : d3_time.utcMinute(date) < d ? formatSecond + : d3_time.utcHour(date) < d ? formatMinute + : d3_time.utcDay(date) < d ? formatHour + : d3_time.utcMonth(date) < d ? + (d3_time.utcWeek(date) < d ? formatDay : formatWeek) + : d3_time.utcYear(date) < d ? formatMonth + : formatYear)(date); + }; + } + +},{"d3-format":6,"d3-time":8,"d3-time-format":7}],16:[function(require,module,exports){ + var gen = module.exports = {}; + + gen.repeat = function(val, n) { + var a = Array(n), i; + for (i=0; i stop) range.push(j); + else while ((j = start + step * ++i) < stop) range.push(j); + return range; + }; + + gen.random = {}; + + gen.random.uniform = function(min, max) { + if (max === undefined) { + max = min === undefined ? 1 : min; + min = 0; + } + var d = max - min; + var f = function() { + return min + d * Math.random(); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.integer = function(a, b) { + if (b === undefined) { + b = a; + a = 0; + } + var d = b - a; + var f = function() { + return a + Math.floor(d * Math.random()); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.normal = function(mean, stdev) { + mean = mean || 0; + stdev = stdev || 1; + var next; + var f = function() { + var x = 0, y = 0, rds, c; + if (next !== undefined) { + x = next; + next = undefined; + return x; + } + do { + x = Math.random()*2-1; + y = Math.random()*2-1; + rds = x*x + y*y; + } while (rds === 0 || rds > 1); + c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform + next = mean + y*c*stdev; + return mean + x*c*stdev; + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + +},{}],17:[function(require,module,exports){ + var util = require('../../util'); + var d3_dsv = require('d3-dsv'); + + function dsv(data, format) { + if (data) { + var h = format.header; + data = (h ? h.join(format.delimiter) + '\n' : '') + data; + } + return d3_dsv.dsv(format.delimiter).parse(data); + } + + dsv.delimiter = function(delim) { + var fmt = {delimiter: delim}; + return function(data, format) { + return dsv(data, format ? util.extend(format, fmt) : fmt); + }; + }; + + module.exports = dsv; + +},{"../../util":31,"d3-dsv":5}],18:[function(require,module,exports){ + var dsv = require('./dsv'); + + module.exports = { + json: require('./json'), + topojson: require('./topojson'), + treejson: require('./treejson'), + dsv: dsv, + csv: dsv.delimiter(','), + tsv: dsv.delimiter('\t') + }; + +},{"./dsv":17,"./json":19,"./topojson":20,"./treejson":21}],19:[function(require,module,exports){ + var util = require('../../util'); + + module.exports = function(data, format) { + var d = util.isObject(data) && !util.isBuffer(data) ? + data : JSON.parse(data); + if (format && format.property) { + d = util.accessor(format.property)(d); + } + return d; + }; + +},{"../../util":31}],20:[function(require,module,exports){ + (function (global){ + var json = require('./json'); + + var reader = function(data, format) { + var topojson = reader.topojson; + if (topojson == null) { throw Error('TopoJSON library not loaded.'); } + + var t = json(data, format), obj; + + if (format && format.feature) { + if ((obj = t.objects[format.feature])) { + return topojson.feature(t, obj).features; + } else { + throw Error('Invalid TopoJSON object: ' + format.feature); + } + } else if (format && format.mesh) { + if ((obj = t.objects[format.mesh])) { + return [topojson.mesh(t, t.objects[format.mesh])]; + } else { + throw Error('Invalid TopoJSON object: ' + format.mesh); + } + } else { + throw Error('Missing TopoJSON feature or mesh parameter.'); + } + }; + + reader.topojson = (typeof window !== "undefined" ? window['topojson'] : typeof global !== "undefined" ? global['topojson'] : null); + module.exports = reader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./json":19}],21:[function(require,module,exports){ + var json = require('./json'); + + module.exports = function(tree, format) { + return toTable(json(tree, format), format); + }; + + function toTable(root, fields) { + var childrenField = fields && fields.children || 'children', + parentField = fields && fields.parent || 'parent', + table = []; + + function visit(node, parent) { + node[parentField] = parent; + table.push(node); + var children = node[childrenField]; + if (children) { + for (var i=0; i 1 && domain[idx-1] === '.' && domain.lastIndexOf(d) === idx); + }); + if (!whiteListed) { + throw 'URL is not whitelisted: ' + url; + } + } + } + return url; + } + + function load(opt, callback) { + var error = callback || function(e) { throw e; }, url; + + try { + url = load.sanitizeUrl(opt); // enable override + } catch (err) { + error(err); + return; + } + + if (!url) { + error('Invalid URL: ' + opt.url); + } else if (load.useXHR) { + // on client, use xhr + return xhr(url, callback); + } else if (startsWith(url, fileProtocol)) { + // on server, if url starts with 'file://', strip it and load from file + return file(url.slice(fileProtocol.length), callback); + } else if (url.indexOf('://') < 0) { // TODO better protocol check? + // on server, if no protocol assume file + return file(url, callback); + } else { + // for regular URLs on server + return http(url, callback); + } + } + + function xhrHasResponse(request) { + var type = request.responseType; + return type && type !== 'text' ? + request.response : // null on error + request.responseText; // '' on error + } + + function xhr(url, callback) { + var async = !!callback; + var request = new XMLHttpRequest(); + // If IE does not support CORS, use XDomainRequest (copied from d3.xhr) + if (this.XDomainRequest && + !('withCredentials' in request) && + /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); + + function respond() { + var status = request.status; + if (!status && xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { + callback(null, request.responseText); + } else { + callback(request, null); + } + } + + if (async) { + if ('onload' in request) { + request.onload = request.onerror = respond; + } else { + request.onreadystatechange = function() { + if (request.readyState > 3) respond(); + }; + } + } + + request.open('GET', url, async); + request.send(); + + if (!async && xhrHasResponse(request)) { + return request.responseText; + } + } + + function file(filename, callback) { + var fs = require('fs'); + if (!callback) { + return fs.readFileSync(filename, 'utf8'); + } + fs.readFile(filename, callback); + } + + function http(url, callback) { + if (!callback) { + return require('sync-request')('GET', url).getBody(); + } + + var options = {url: url, encoding: null, gzip: true}; + require('request')(options, function(error, response, body) { + if (!error && response.statusCode === 200) { + callback(null, body); + } else { + error = error || + 'Load failed with response code ' + response.statusCode + '.'; + callback(error, null); + } + }); + } + + function startsWith(string, searchString) { + return string == null ? false : string.lastIndexOf(searchString, 0) === 0; + } + + load.sanitizeUrl = sanitizeUrl; + + load.useXHR = (typeof XMLHttpRequest !== 'undefined'); + + module.exports = load; + +},{"fs":2,"request":2,"sync-request":2,"url":2}],23:[function(require,module,exports){ + var util = require('../util'); + var type = require('./type'); + var formats = require('./formats'); + + function read(data, format) { + var type = (format && format.type) || 'json'; + data = formats[type](data, format); + if (format && format.parse) parse(data, format.parse); + return data; + } + + function parse(data, types) { + var cols, parsers, d, i, j, clen, len = data.length; + + types = (types==='auto') ? type.inferAll(data) : util.duplicate(types); + cols = util.keys(types); + parsers = cols.map(function(c) { return type.parsers[types[c]]; }); + + for (i=0, clen=cols.length; i 0 ? Math.min(l, opt.maxwidth) : l; + }); + + // print header row + var head = fields.map(function(name, i) { + return util.truncate(util.pad(name, lens[i], 'center'), lens[i]); + }).join(opt.separator); + + // build template function for each row + var tmpl = template(fields.map(function(name, i) { + return '{{' + + name + + (FMT[types[name]] || '') + + ('|pad:' + lens[i] + ',' + (POS[types[name]] || 'right')) + + ('|truncate:' + lens[i]) + + '}}'; + }).join(opt.separator)); + + // print table + return head + "\n" + data.map(tmpl).join('\n'); + }; + + module.exports.summary = function(s) { + s = s ? s.__summary__ ? s : stats.summary(s) : this; + var str = [], i, n; + for (i=0, n=s.length; i b) b = v; + } + } + return [a, b]; + }; + +// Find the integer indices of the minimum and maximum values. + stats.extent.index = function(values, f) { + f = util.$(f); + var x = -1, y = -1, a, b, v, i, n = values.length; + for (i=0; i b) { b = v; y = i; } + } + } + return [x, y]; + }; + +// Compute the dot product of two arrays of numbers. + stats.dot = function(values, a, b) { + var sum = 0, i, v; + if (!b) { + if (values.length !== a.length) { + throw Error('Array lengths must match.'); + } + for (i=0; i -1 && p !== v) { + mu = 1 + (i-1 + tie) / 2; + for (; tie -1) { + mu = 1 + (n-1 + tie) / 2; + for (; tie max) max = x; + delta = x - mean; + mean = mean + delta / (++valid); + M2 = M2 + delta * (x - mean); + vals.push(x); + } + } + M2 = M2 / (valid - 1); + sd = Math.sqrt(M2); + + // sort values for median and iqr + vals.sort(util.cmp); + + return { + type: type(values, f), + unique: u, + count: values.length, + valid: valid, + missing: missing, + distinct: distinct, + min: min, + max: max, + mean: mean, + stdev: sd, + median: (v = stats.quantile(vals, 0.5)), + q1: stats.quantile(vals, 0.25), + q3: stats.quantile(vals, 0.75), + modeskew: sd === 0 ? 0 : (mean - v) / sd + }; + }; + +// Compute profiles for all variables in a data set. + stats.summary = function(data, fields) { + fields = fields || util.keys(data[0]); + var s = fields.map(function(f) { + var p = stats.profile(data, util.$(f)); + return (p.field = f, p); + }); + return (s.__summary__ = true, s); + }; + + module.exports = stats; + +},{"./generate":16,"./import/type":25,"./util":31}],29:[function(require,module,exports){ + var util = require('./util'), + format = require('./format'); + + var context = { + formats: [], + format_map: {}, + truncate: util.truncate, + pad: util.pad + }; + + function template(text) { + var src = source(text, 'd'); + src = 'var __t; return ' + src + ';'; + + /* jshint evil: true */ + return (new Function('d', src)).bind(context); + } + + template.source = source; + template.context = context; + module.exports = template; + +// Clear cache of format objects. +// This can *break* prior template functions, so invoke with care! + template.clearFormatCache = function() { + context.formats = []; + context.format_map = {}; + }; + +// Generate property access code for use within template source. +// object: the name of the object (variable) containing template data +// property: the property access string, verbatim from template tag + template.property = function(object, property) { + var src = util.field(property).map(util.str).join(']['); + return object + '[' + src + ']'; + }; + +// Generate source code for a template function. +// text: the template text +// variable: the name of the data object variable ('obj' by default) +// properties: optional hash for collecting all accessed properties + function source(text, variable, properties) { + variable = variable || 'obj'; + var index = 0; + var src = '\''; + var regex = template_re; + + // Compile the template source, escaping string literals appropriately. + text.replace(regex, function(match, interpolate, offset) { + src += text + .slice(index, offset) + .replace(template_escaper, template_escapeChar); + index = offset + match.length; + + if (interpolate) { + src += '\'\n+((__t=(' + + template_var(interpolate, variable, properties) + + '))==null?\'\':__t)+\n\''; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + return src + '\''; + } + + function template_var(text, variable, properties) { + var filters = text.match(filter_re); + var prop = filters.shift().trim(); + var stringCast = true; + + function strcall(fn) { + fn = fn || ''; + if (stringCast) { + stringCast = false; + src = 'String(' + src + ')' + fn; + } else { + src += fn; + } + return src; + } + + function date() { + return '(typeof ' + src + '==="number"?new Date('+src+'):'+src+')'; + } + + function number_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+src+')'; + } + + function time_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+date()+')'; + } + + if (properties) properties[prop] = 1; + var src = template.property(variable, prop); + + for (var i=0; i 0) { + f = f.slice(0, pidx); + args = filters[i].slice(pidx+1) + .match(args_re) + .map(function(s) { return s.trim(); }); + } + f = f.trim(); + + switch (f) { + case 'length': + strcall('.length'); + break; + case 'lower': + strcall('.toLowerCase()'); + break; + case 'upper': + strcall('.toUpperCase()'); + break; + case 'lower-locale': + strcall('.toLocaleLowerCase()'); + break; + case 'upper-locale': + strcall('.toLocaleUpperCase()'); + break; + case 'trim': + strcall('.trim()'); + break; + case 'left': + a = util.number(args[0]); + strcall('.slice(0,' + a + ')'); + break; + case 'right': + a = util.number(args[0]); + strcall('.slice(-' + a +')'); + break; + case 'mid': + a = util.number(args[0]); + b = a + util.number(args[1]); + strcall('.slice(+'+a+','+b+')'); + break; + case 'slice': + a = util.number(args[0]); + strcall('.slice('+ a + + (args.length > 1 ? ',' + util.number(args[1]) : '') + + ')'); + break; + case 'truncate': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.truncate(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'pad': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.pad(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'number': + number_format(format.number, 'number'); + break; + case 'time': + time_format(format.time, 'time'); + break; + case 'time-utc': + time_format(format.utc, 'time-utc'); + break; + default: + throw Error('Unrecognized template filter: ' + f); + } + } + + return src; + } + + var template_re = /\{\{(.+?)\}\}|$/g, + filter_re = /(?:"[^"]*"|\'[^\']*\'|[^\|"]+|[^\|\']+)+/g, + args_re = /(?:"[^"]*"|\'[^\']*\'|[^,"]+|[^,\']+)+/g; + +// Certain characters need to be escaped so that they can be put into a +// string literal. + var template_escapes = { + '\'': '\'', + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var template_escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + function template_escapeChar(match) { + return '\\' + template_escapes[match]; + } + + function template_format(pattern, key, fmt) { + if ((pattern[0] === '\'' && pattern[pattern.length-1] === '\'') || + (pattern[0] === '"' && pattern[pattern.length-1] === '"')) { + pattern = pattern.slice(1, -1); + } else { + throw Error('Format pattern must be quoted: ' + pattern); + } + key = key + ':' + pattern; + if (!context.format_map[key]) { + var f = fmt(pattern); + var i = context.formats.length; + context.formats.push(f); + context.format_map[key] = i; + } + return context.format_map[key]; + } + +},{"./format":15,"./util":31}],30:[function(require,module,exports){ + var d3_time = require('d3-time'); + + var tempDate = new Date(), + baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD + utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0); + + function date(d) { + return (tempDate.setTime(+d), tempDate); + } + +// create a time unit entry + function entry(type, date, unit, step, min, max) { + var e = { + type: type, + date: date, + unit: unit + }; + if (step) { + e.step = step; + } else { + e.minstep = 1; + } + if (min != null) e.min = min; + if (max != null) e.max = max; + return e; + } + + function create(type, unit, base, step, min, max) { + return entry(type, + function(d) { return unit.offset(base, d); }, + function(d) { return unit.count(base, d); }, + step, min, max); + } + + var locale = [ + create('second', d3_time.second, baseDate), + create('minute', d3_time.minute, baseDate), + create('hour', d3_time.hour, baseDate), + create('day', d3_time.day, baseDate, [1, 7]), + create('month', d3_time.month, baseDate, [1, 3, 6]), + create('year', d3_time.year, baseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(1970, 0, 1, 0, 0, d); }, + function(d) { return date(d).getSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(1970, 0, 1, 0, d); }, + function(d) { return date(d).getMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(1970, 0, 1, d); }, + function(d) { return date(d).getHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(1970, 0, 4+d); }, + function(d) { return date(d).getDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(1970, 0, d); }, + function(d) { return date(d).getDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(1970, d % 12, 1); }, + function(d) { return date(d).getMonth(); }, + [1], 0, 11 + ) + ]; + + var utc = [ + create('second', d3_time.utcSecond, utcBaseDate), + create('minute', d3_time.utcMinute, utcBaseDate), + create('hour', d3_time.utcHour, utcBaseDate), + create('day', d3_time.utcDay, utcBaseDate, [1, 7]), + create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]), + create('year', d3_time.utcYear, utcBaseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); }, + function(d) { return date(d).getUTCSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); }, + function(d) { return date(d).getUTCMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(Date.UTC(1970, 0, 1, d)); }, + function(d) { return date(d).getUTCHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(Date.UTC(1970, 0, 4+d)); }, + function(d) { return date(d).getUTCDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(Date.UTC(1970, 0, d)); }, + function(d) { return date(d).getUTCDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(Date.UTC(1970, d % 12, 1)); }, + function(d) { return date(d).getUTCMonth(); }, + [1], 0, 11 + ) + ]; + + var STEPS = [ + [31536e6, 5], // 1-year + [7776e6, 4], // 3-month + [2592e6, 4], // 1-month + [12096e5, 3], // 2-week + [6048e5, 3], // 1-week + [1728e5, 3], // 2-day + [864e5, 3], // 1-day + [432e5, 2], // 12-hour + [216e5, 2], // 6-hour + [108e5, 2], // 3-hour + [36e5, 2], // 1-hour + [18e5, 1], // 30-minute + [9e5, 1], // 15-minute + [3e5, 1], // 5-minute + [6e4, 1], // 1-minute + [3e4, 0], // 30-second + [15e3, 0], // 15-second + [5e3, 0], // 5-second + [1e3, 0] // 1-second + ]; + + function find(units, span, minb, maxb) { + var step = STEPS[0], i, n, bins; + + for (i=1, n=STEPS.length; i step[0]) { + bins = span / step[0]; + if (bins > maxb) { + return units[STEPS[i-1][1]]; + } + if (bins >= minb) { + return units[step[1]]; + } + } + } + return units[STEPS[n-1][1]]; + } + + function toUnitMap(units) { + var map = {}, i, n; + for (i=0, n=units.length; i 1 ? + function(x) { return s.reduce(function(x,f) { return x[f]; }, x); } : + function(x) { return x[f]; } + ); + }; + +// short-cut for accessor + u.$ = u.accessor; + + u.mutator = function(f) { + var s; + return u.isString(f) && (s=u.field(f)).length > 1 ? + function(x, v) { + for (var i=0; i y) return sign[i]; + } + return 0; + }; + }; + + u.cmp = function(a, b) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a >= b) { + return 0; + } else if (a === null) { + return -1; + } else if (b === null) { + return 1; + } + return NaN; + }; + + u.numcmp = function(a, b) { return a - b; }; + + u.stablesort = function(array, sortBy, keyFn) { + var indices = array.reduce(function(idx, v, i) { + return (idx[keyFn(v)] = i, idx); + }, {}); + + array.sort(function(a, b) { + var sa = sortBy(a), + sb = sortBy(b); + return sa < sb ? -1 : sa > sb ? 1 + : (indices[keyFn(a)] - indices[keyFn(b)]); + }); + + return array; + }; + + +// string functions + + u.pad = function(s, length, pos, padchar) { + padchar = padchar || " "; + var d = length - s.length; + if (d <= 0) return s; + switch (pos) { + case 'left': + return strrep(d, padchar) + s; + case 'middle': + case 'center': + return strrep(Math.floor(d/2), padchar) + + s + strrep(Math.ceil(d/2), padchar); + default: + return s + strrep(d, padchar); + } + }; + + function strrep(n, str) { + var s = "", i; + for (i=0; i 1) { + for (var i=1, n=ref.length; i 0) { + node = pq.peek(); + pulse = pulses[node._id]; + + if (node.rank() !== node.qrank()) { + // A node's rank might change during a propagation. Re-queue if so. + pq.replace(node.qrank(true)); + } else { + // Evaluate node and propagate pulse. + pq.pop(); + pulses[node._id] = null; + listeners = node._listeners; + pulse = this.evaluate(pulse, node); + + // Propagate the pulse. + if (pulse !== this.doNotPropagate) { + // Ensure reflow pulses always send reflow pulses even if skipped. + if (!pulse.reflow && node.reflows()) { + pulse = ChangeSet.create(pulse, true); + } + + for (i=0, len=listeners.length; i 0) branch[i-1].addListener(node); + } + + return branch; + }; + + prototype.disconnect = function(branch) { + var collector, node, data, signals, i, n, j, m; + + for (i=0, n=branch.length; i= pulse.stamp, + run = node.router() || pulse.add.length || pulse.rem.length; + + return run || !reflowed || node.reevaluate(pulse); + }; + + prototype.evaluate = function(pulse, node) { + if (!this.reevaluate(pulse, node)) return pulse; + pulse = node.evaluate(pulse); + node.last(pulse.stamp); + return pulse; + }; + + module.exports = Graph; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Heap":37,"./Signal":39,"./Tuple":40,"datalib":26}],37:[function(require,module,exports){ + function Heap(comparator) { + this.cmp = comparator; + this.nodes = []; + } + + var prototype = Heap.prototype; + + prototype.size = function() { + return this.nodes.length; + }; + + prototype.clear = function() { + return (this.nodes = [], this); + }; + + prototype.peek = function() { + return this.nodes[0]; + }; + + prototype.push = function(x) { + var array = this.nodes; + array.push(x); + return _siftdown(array, 0, array.length-1, this.cmp); + }; + + prototype.pop = function() { + var array = this.nodes, + last = array.pop(), + item; + + if (array.length) { + item = array[0]; + array[0] = last; + _siftup(array, 0, this.cmp); + } else { + item = last; + } + return item; + }; + + prototype.replace = function(item) { + var array = this.nodes, + retval = array[0]; + array[0] = item; + _siftup(array, 0, this.cmp); + return retval; + }; + + prototype.pushpop = function(item) { + var array = this.nodes, ref = array[0]; + if (array.length && this.cmp(ref, item) < 0) { + array[0] = item; + item = ref; + _siftup(array, 0, this.cmp); + } + return item; + }; + + function _siftdown(array, start, idx, cmp) { + var item, parent, pidx; + + item = array[idx]; + while (idx > start) { + pidx = (idx - 1) >> 1; + parent = array[pidx]; + if (cmp(item, parent) < 0) { + array[idx] = parent; + idx = pidx; + continue; + } + break; + } + return (array[idx] = item); + } + + function _siftup(array, idx, cmp) { + var start = idx, + end = array.length, + item = array[idx], + cidx = 2 * idx + 1, ridx; + + while (cidx < end) { + ridx = cidx + 1; + if (ridx < end && cmp(array[cidx], array[ridx]) >= 0) { + cidx = ridx; + } + array[idx] = array[cidx]; + idx = cidx; + cidx = 2 * idx + 1; + } + array[idx] = item; + return _siftdown(array, start, idx, cmp); + } + + module.exports = Heap; + +},{}],38:[function(require,module,exports){ + var DEPS = require('./Dependencies').ALL, + nodeID = 0; + + function Node(graph) { + if (graph) this.init(graph); + } + + var Flags = Node.Flags = { + Router: 0x01, // Responsible for propagating tuples, cannot be skipped. + Collector: 0x02, // Holds a materialized dataset, pulse node to reflow. + Produces: 0x04, // Produces new tuples. + Mutates: 0x08, // Sets properties of incoming tuples. + Reflows: 0x10, // Forwards a reflow pulse. + Batch: 0x20 // Performs batch data processing, needs collector. + }; + + var prototype = Node.prototype; + + prototype.init = function(graph) { + this._id = ++nodeID; + this._graph = graph; + this._rank = graph.rank(); // Topological sort by rank + this._qrank = null; // Rank when enqueued for propagation + this._stamp = 0; // Last stamp seen + + this._listeners = []; + this._listeners._ids = {}; // To prevent duplicate listeners + + // Initialize dependencies. + this._deps = {}; + for (var i=0, n=DEPS.length; i l._rank) { + l.rerank(); + } + + return this; + }; + + prototype.removeListener = function(l) { + if (!this._listeners._ids[l._id]) return false; + + var idx = this._listeners.indexOf(l), + b = idx >= 0; + + if (b) { + this._listeners.splice(idx, 1); + this._listeners._ids[l._id] = null; + } + return b; + }; + + prototype.disconnect = function() { + this._listeners = []; + this._listeners._ids = {}; + }; + +// Evaluate this dataflow node for the current pulse. +// Subclasses should override to perform custom processing. + prototype.evaluate = function(pulse) { + return pulse; + }; + +// Should this node be re-evaluated for the current pulse? +// Searches pulse to see if any dependencies have updated. + prototype.reevaluate = function(pulse) { + var prop, dep, i, n, j, m; + + for (i=0, n=DEPS.length; i=0;) { + if (!handler || h[i].handler === handler) { + x = h.splice(i, 1)[0]; + this.removeListener(x.node); + } + } + + return this; + }; + + module.exports = Signal; + +},{"./ChangeSet":32,"./Node":38}],40:[function(require,module,exports){ + var tupleID = 0; + + function ingest(datum) { + datum = (datum === Object(datum)) ? datum : {data: datum}; + datum._id = ++tupleID; + if (datum._prev) datum._prev = null; + return datum; + } + + function idMap(a, ids) { + ids = ids || {}; + for (var i=0, n=a.length; i0;) { + idMap(arguments[i], ids); + } + return data.filter(function(x) { return !ids[x._id]; }); + } + }; + +},{}],41:[function(require,module,exports){ + module.exports = { + ChangeSet: require('./ChangeSet'), + Collector: require('./Collector'), + DataSource: require('./DataSource'), + Dependencies: require('./Dependencies'), + Graph: require('./Graph'), + Node: require('./Node'), + Signal: require('./Signal'), + Tuple: require('./Tuple'), + debug: require('vega-logging').debug + }; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Graph":36,"./Node":38,"./Signal":39,"./Tuple":40,"vega-logging":47}],42:[function(require,module,exports){ + function toMap(list) { + var map = {}, i, n; + for (i=0, n=list.length; i 0) { + return id; + } + if (constants.hasOwnProperty(id)) { + return constants[id]; + } + if (idWhiteList) { + if (idWhiteList.hasOwnProperty(id)) { + return id; + } else { + globals[id] = 1; + return lookupGlobal(id); + } + } + if (idBlackList && idBlackList.hasOwnProperty(id)) { + throw new Error('Illegal identifier: ' + id); + } + return id; + }, + 'Program': function(n) { + return n.body.map(codegen).join('\n'); + }, + 'MemberExpression': function(n) { + var d = !n.computed; + var o = codegen(n.object); + if (d) memberDepth += 1; + var p = codegen(n.property); + if (o === FIELD_VAR) { fields[p] = 1; } // HACKish... + if (d) memberDepth -= 1; + return o + (d ? '.'+p : '['+p+']'); + }, + 'CallExpression': function(n) { + if (n.callee.type !== 'Identifier') { + throw new Error('Illegal callee type: ' + n.callee.type); + } + var callee = n.callee.name; + var args = n.arguments; + var fn = functions.hasOwnProperty(callee) && functions[callee]; + if (!fn) throw new Error('Unrecognized function: ' + callee); + return fn instanceof Function ? + fn(args) : + fn + '(' + args.map(codegen).join(',') + ')'; + }, + 'ArrayExpression': function(n) { + return '[' + n.elements.map(codegen).join(',') + ']'; + }, + 'BinaryExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'UnaryExpression': function(n) { + return '(' + n.operator + codegen(n.argument) + ')'; + }, + 'ConditionalExpression': function(n) { + return '(' + codegen(n.test) + + '?' + codegen(n.consequent) + + ':' + codegen(n.alternate) + + ')'; + }, + 'LogicalExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'ObjectExpression': function(n) { + return '{' + n.properties.map(codegen).join(',') + '}'; + }, + 'Property': function(n) { + memberDepth += 1; + var k = codegen(n.key); + memberDepth -= 1; + return k + ':' + codegen(n.value); + }, + 'ExpressionStatement': function(n) { + return codegen(n.expression); + } + }; + + codegen_wrap.functions = functions; + codegen_wrap.constants = constants; + return codegen_wrap; + }; + +},{"./constants":43,"./functions":44}],43:[function(require,module,exports){ + module.exports = { + 'NaN': 'NaN', + 'E': 'Math.E', + 'LN2': 'Math.LN2', + 'LN10': 'Math.LN10', + 'LOG2E': 'Math.LOG2E', + 'LOG10E': 'Math.LOG10E', + 'PI': 'Math.PI', + 'SQRT1_2': 'Math.SQRT1_2', + 'SQRT2': 'Math.SQRT2' + }; +},{}],44:[function(require,module,exports){ + module.exports = function(codegen) { + + function fncall(name, args, cast, type) { + var obj = codegen(args[0]); + if (cast) { + obj = cast + '(' + obj + ')'; + if (cast.lastIndexOf('new ', 0) === 0) obj = '(' + obj + ')'; + } + return obj + '.' + name + (type < 0 ? '' : type === 0 ? + '()' : + '(' + args.slice(1).map(codegen).join(',') + ')'); + } + + function fn(name, cast, type) { + return function(args) { + return fncall(name, args, cast, type); + }; + } + + var DATE = 'new Date', + STRING = 'String', + REGEXP = 'RegExp'; + + return { + // MATH functions + 'isNaN': 'isNaN', + 'isFinite': 'isFinite', + 'abs': 'Math.abs', + 'acos': 'Math.acos', + 'asin': 'Math.asin', + 'atan': 'Math.atan', + 'atan2': 'Math.atan2', + 'ceil': 'Math.ceil', + 'cos': 'Math.cos', + 'exp': 'Math.exp', + 'floor': 'Math.floor', + 'log': 'Math.log', + 'max': 'Math.max', + 'min': 'Math.min', + 'pow': 'Math.pow', + 'random': 'Math.random', + 'round': 'Math.round', + 'sin': 'Math.sin', + 'sqrt': 'Math.sqrt', + 'tan': 'Math.tan', + + 'clamp': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to clamp function.'); + if (args.length > 3) + throw new Error('Too many arguments to clamp function.'); + var a = args.map(codegen); + return 'Math.max('+a[1]+', Math.min('+a[2]+','+a[0]+'))'; + }, + + // DATE functions + 'now': 'Date.now', + 'datetime': DATE, + 'date': fn('getDate', DATE, 0), + 'day': fn('getDay', DATE, 0), + 'year': fn('getFullYear', DATE, 0), + 'month': fn('getMonth', DATE, 0), + 'hours': fn('getHours', DATE, 0), + 'minutes': fn('getMinutes', DATE, 0), + 'seconds': fn('getSeconds', DATE, 0), + 'milliseconds': fn('getMilliseconds', DATE, 0), + 'time': fn('getTime', DATE, 0), + 'timezoneoffset': fn('getTimezoneOffset', DATE, 0), + 'utcdate': fn('getUTCDate', DATE, 0), + 'utcday': fn('getUTCDay', DATE, 0), + 'utcyear': fn('getUTCFullYear', DATE, 0), + 'utcmonth': fn('getUTCMonth', DATE, 0), + 'utchours': fn('getUTCHours', DATE, 0), + 'utcminutes': fn('getUTCMinutes', DATE, 0), + 'utcseconds': fn('getUTCSeconds', DATE, 0), + 'utcmilliseconds': fn('getUTCMilliseconds', DATE, 0), + + // shared sequence functions + 'length': fn('length', null, -1), + 'indexof': fn('indexOf', null), + 'lastindexof': fn('lastIndexOf', null), + + // STRING functions + 'parseFloat': 'parseFloat', + 'parseInt': 'parseInt', + 'upper': fn('toUpperCase', STRING, 0), + 'lower': fn('toLowerCase', STRING, 0), + 'slice': fn('slice', STRING), + 'substring': fn('substring', STRING), + + // REGEXP functions + 'regexp': REGEXP, + 'test': fn('test', REGEXP), + + // Control Flow functions + 'if': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to if function.'); + if (args.length > 3) + throw new Error('Too many arguments to if function.'); + var a = args.map(codegen); + return a[0]+'?'+a[1]+':'+a[2]; + } + }; + }; +},{}],45:[function(require,module,exports){ + var parser = require('./parser'), + codegen = require('./codegen'); + + var expr = module.exports = { + parse: function(input, opt) { + return parser.parse('('+input+')', opt); + }, + code: function(opt) { + return codegen(opt); + }, + compiler: function(args, opt) { + args = args.slice(); + var generator = codegen(opt), + len = args.length, + compile = function(str) { + var value = generator(expr.parse(str)); + args[len] = '"use strict"; return (' + value.code + ');'; + value.fn = Function.apply(null, args); + return value; + }; + compile.codegen = generator; + return compile; + }, + functions: require('./functions'), + constants: require('./constants') + }; + +},{"./codegen":42,"./constants":43,"./functions":44,"./parser":46}],46:[function(require,module,exports){ + /* + The following expression parser is based on Esprima (http://esprima.org/). + Original header comment and license for Esprima is included here: + + Copyright (C) 2013 Ariya Hidayat + Copyright (C) 2013 Thaddee Tyl + Copyright (C) 2013 Mathias Bynens + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* istanbul ignore next */ + module.exports = (function() { + 'use strict'; + + var Token, + TokenName, + Syntax, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + lookahead, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8, + RegularExpression: 9 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + TokenName[Token.RegularExpression] = 'RegularExpression'; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BinaryExpression: 'BinaryExpression', + CallExpression: 'CallExpression', + ConditionalExpression: 'ConditionalExpression', + ExpressionStatement: 'ExpressionStatement', + Identifier: 'Identifier', + Literal: 'Literal', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + UnaryExpression: 'UnaryExpression' + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), + NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); + } + + function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + default: + return false; + } + } + + function isStrictModeReservedWord(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + default: + return false; + } + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + // 'const' is specialized as Keyword in V8. + // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next. + // Some others are from future reserved words. + + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || + (id === 'try') || (id === 'let'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + function skipComment() { + var ch, start; + + start = (index === 0); + while (index < length) { + ch = source.charCodeAt(index); + + if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { + ++index; + } + ++lineNumber; + lineStart = index; + start = true; + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanUnicodeCodePointEscape() { + var ch, code, cu1, cu2; + + ch = source[index]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + while (index < length) { + ch = source[index++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // UTF-16 Encoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } + cu1 = ((code - 0x10000) >> 10) + 0xD800; + cu2 = ((code - 0x10000) & 1023) + 0xDC00; + return String.fromCharCode(cu1, cu2); + } + + function getEscapedIdentifier() { + var ch, id; + + ch = source.charCodeAt(index++); + id = String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id = ch; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (!isIdentifierPart(ch)) { + break; + } + ++index; + id += String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + id = id.substr(0, id.length - 1); + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id += ch; + } + } + + return id; + } + + function getIdentifier() { + var start, ch; + + start = index++; + while (index < length) { + ch = source.charCodeAt(index); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index = start; + return getEscapedIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index; + } else { + break; + } + } + + return source.slice(start, index); + } + + function scanIdentifier() { + var start, id, type; + + start = index; + + // Backslash (U+005C) starts an escaped character. + id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = Token.Identifier; + } else if (isKeyword(id)) { + type = Token.Keyword; + } else if (id === 'null') { + type = Token.NullLiteral; + } else if (id === 'true' || id === 'false') { + type = Token.BooleanLiteral; + } else { + type = Token.Identifier; + } + + return { + type: type, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + code = source.charCodeAt(index), + code2, + ch1 = source[index], + ch2, + ch3, + ch4; + + switch (code) { + + // Check for most common single-character punctuators. + case 0x2E: // . dot + case 0x28: // ( open bracket + case 0x29: // ) close bracket + case 0x3B: // ; semicolon + case 0x2C: // , comma + case 0x7B: // { open curly brace + case 0x7D: // } close curly brace + case 0x5B: // [ + case 0x5D: // ] + case 0x3A: // : + case 0x3F: // ? + case 0x7E: // ~ + ++index; + if (extra.tokenize) { + if (code === 0x28) { + extra.openParenToken = extra.tokens.length; + } else if (code === 0x7B) { + extra.openCurlyToken = extra.tokens.length; + } + } + return { + type: Token.Punctuator, + value: String.fromCharCode(code), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + default: + code2 = source.charCodeAt(index + 1); + + // '=' (U+003D) marks an assignment or comparison operator. + if (code2 === 0x3D) { + switch (code) { + case 0x2B: // + + case 0x2D: // - + case 0x2F: // / + case 0x3C: // < + case 0x3E: // > + case 0x5E: // ^ + case 0x7C: // | + case 0x25: // % + case 0x26: // & + case 0x2A: // * + index += 2; + return { + type: Token.Punctuator, + value: String.fromCharCode(code) + String.fromCharCode(code2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + case 0x21: // ! + case 0x3D: // = + index += 2; + + // !== and === + if (source.charCodeAt(index) === 0x3D) { + ++index; + } + return { + type: Token.Punctuator, + value: source.slice(start, index), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + } + } + + // 4-character punctuator: >>>= + + ch4 = source.substr(index, 4); + + if (ch4 === '>>>=') { + index += 4; + return { + type: Token.Punctuator, + value: ch4, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + ch3 = ch4.substr(0, 3); + + if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') { + index += 3; + return { + type: Token.Punctuator, + value: ch3, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // Other 2-character punctuators: ++ -- << >> && || + ch2 = ch3.substr(0, 2); + + if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') { + index += 2; + return { + type: Token.Punctuator, + value: ch2, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 1-character punctuators: < > = ! + - * % & | ^ / + + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // 7.8.3 Numeric Literals + + function scanHexLiteral(start) { + var number = ''; + + while (index < length) { + if (!isHexDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt('0x' + number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanOctalLiteral(start) { + var number = '0' + source[index++]; + while (index < length) { + if (!isOctalDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: true, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index; + return scanHexLiteral(start); + } + if (isOctalDigit(ch)) { + return scanOctalLiteral(start); + } + + // decimal number starts with '0' such as '09' is illegal. + if (ch && isDecimalDigit(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === '.') { + number += source[index++]; + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + if (isDecimalDigit(source.charCodeAt(index))) { + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + } else { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart; + startLineNumber = lineNumber; + startLineStart = lineStart; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + str += scanUnicodeCodePointEscape(); + } else { + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + startLineNumber: startLineNumber, + startLineStart: startLineStart, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function testRegExp(pattern, flags) { + var tmp = pattern, + value; + + if (flags.indexOf('u') >= 0) { + // Replace each astral symbol and every Unicode code point + // escape sequence with a single ASCII symbol to avoid throwing on + // regular expressions that are only valid in combination with the + // `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it + // would be replaced by `[x-b]` which throws an error. + tmp = tmp + .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) { + if (parseInt($1, 16) <= 0x10FFFF) { + return 'x'; + } + throwError({}, Messages.InvalidRegExp); + }) + .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); + } + + // First, detect invalid regular expressions. + try { + value = new RegExp(tmp); + } catch (e) { + throwError({}, Messages.InvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + return null; + } + } + + function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + classMarker = false; + terminated = false; + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwError({}, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; + } + + function scanRegExpFlags() { + var ch, str, flags, restore; + + str = ''; + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + for (str += '\\u'; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } else { + str += '\\'; + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + flags += ch; + str += ch; + } + } + + return { + value: flags, + literal: str + }; + } + + function scanRegExp() { + var start, body, flags, value; + + lookahead = null; + skipComment(); + start = index; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + + if (extra.tokenize) { + return { + type: Token.RegularExpression, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index + }; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = scanRegExp(); + + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (!extra.tokenize) { + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + regex: regex.regex, + range: [pos, index], + loc: loc + }); + } + + return regex; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advanceSlash() { + var prevToken, + checkToken; + // Using the following algorithm: + // https://github.com/mozilla/sweet.js/wiki/design + prevToken = extra.tokens[extra.tokens.length - 1]; + if (!prevToken) { + // Nothing before that: it cannot be a division. + return collectRegex(); + } + if (prevToken.type === 'Punctuator') { + if (prevToken.value === ']') { + return scanPunctuator(); + } + if (prevToken.value === ')') { + checkToken = extra.tokens[extra.openParenToken - 1]; + if (checkToken && + checkToken.type === 'Keyword' && + (checkToken.value === 'if' || + checkToken.value === 'while' || + checkToken.value === 'for' || + checkToken.value === 'with')) { + return collectRegex(); + } + return scanPunctuator(); + } + if (prevToken.value === '}') { + // Dividing a function by anything makes little sense, + // but we have to check for that. + if (extra.tokens[extra.openCurlyToken - 3] && + extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { + // Anonymous function. + checkToken = extra.tokens[extra.openCurlyToken - 4]; + if (!checkToken) { + return scanPunctuator(); + } + } else if (extra.tokens[extra.openCurlyToken - 4] && + extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { + // Named function. + checkToken = extra.tokens[extra.openCurlyToken - 5]; + if (!checkToken) { + return collectRegex(); + } + } else { + return scanPunctuator(); + } + return scanPunctuator(); + } + return collectRegex(); + } + if (prevToken.type === 'Keyword' && prevToken.value !== 'this') { + return collectRegex(); + } + return scanPunctuator(); + } + + function advance() { + var ch; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + } + + ch = source.charCodeAt(index); + + if (isIdentifierStart(ch)) { + return scanIdentifier(); + } + + // Very common: ( and ) and ; + if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (ch === 0x27 || ch === 0x22) { + return scanStringLiteral(); + } + + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (ch === 0x2E) { + if (isDecimalDigit(source.charCodeAt(index + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + // Slash (/) U+002F can also start a regex. + if (extra.tokenize && ch === 0x2F) { + return advanceSlash(); + } + + return scanPunctuator(); + } + + function collectToken() { + var loc, token, value, entry; + + skipComment(); + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + value = source.slice(token.start, token.end); + entry = { + type: TokenName[token.type], + value: value, + range: [token.start, token.end], + loc: loc + }; + if (token.regex) { + entry.regex = { + pattern: token.regex.pattern, + flags: token.regex.flags + }; + } + extra.tokens.push(entry); + } + + return token; + } + + function lex() { + var token; + + token = lookahead; + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + return token; + } + + function peek() { + var pos, line, start; + + pos = index; + line = lineNumber; + start = lineStart; + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + index = pos; + lineNumber = line; + lineStart = start; + } + + function Position() { + this.line = lineNumber; + this.column = index - lineStart; + } + + function SourceLocation() { + this.start = new Position(); + this.end = null; + } + + function WrappingSourceLocation(startToken) { + if (startToken.type === Token.StringLiteral) { + this.start = { + line: startToken.startLineNumber, + column: startToken.start - startToken.startLineStart + }; + } else { + this.start = { + line: startToken.lineNumber, + column: startToken.start - startToken.lineStart + }; + } + this.end = null; + } + + function Node() { + // Skip comment. + index = lookahead.start; + if (lookahead.type === Token.StringLiteral) { + lineNumber = lookahead.startLineNumber; + lineStart = lookahead.startLineStart; + } else { + lineNumber = lookahead.lineNumber; + lineStart = lookahead.lineStart; + } + if (extra.range) { + this.range = [index, 0]; + } + if (extra.loc) { + this.loc = new SourceLocation(); + } + } + + function WrappingNode(startToken) { + if (extra.range) { + this.range = [startToken.start, 0]; + } + if (extra.loc) { + this.loc = new WrappingSourceLocation(startToken); + } + } + + WrappingNode.prototype = Node.prototype = { + + finish: function () { + if (extra.range) { + this.range[1] = index; + } + if (extra.loc) { + this.loc.end = new Position(); + if (extra.source) { + this.loc.source = extra.source; + } + } + }, + + finishArrayExpression: function (elements) { + this.type = Syntax.ArrayExpression; + this.elements = elements; + this.finish(); + return this; + }, + + finishAssignmentExpression: function (operator, left, right) { + this.type = Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBinaryExpression: function (operator, left, right) { + this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishCallExpression: function (callee, args) { + this.type = Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishConditionalExpression: function (test, consequent, alternate) { + this.type = Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishExpressionStatement: function (expression) { + this.type = Syntax.ExpressionStatement; + this.expression = expression; + this.finish(); + return this; + }, + + finishIdentifier: function (name) { + this.type = Syntax.Identifier; + this.name = name; + this.finish(); + return this; + }, + + finishLiteral: function (token) { + this.type = Syntax.Literal; + this.value = token.value; + this.raw = source.slice(token.start, token.end); + if (token.regex) { + if (this.raw == '//') { + this.raw = '/(?:)/'; + } + this.regex = token.regex; + } + this.finish(); + return this; + }, + + finishMemberExpression: function (accessor, object, property) { + this.type = Syntax.MemberExpression; + this.computed = accessor === '['; + this.object = object; + this.property = property; + this.finish(); + return this; + }, + + finishObjectExpression: function (properties) { + this.type = Syntax.ObjectExpression; + this.properties = properties; + this.finish(); + return this; + }, + + finishProgram: function (body) { + this.type = Syntax.Program; + this.body = body; + this.finish(); + return this; + }, + + finishProperty: function (kind, key, value) { + this.type = Syntax.Property; + this.key = key; + this.value = value; + this.kind = kind; + this.finish(); + return this; + }, + + finishUnaryExpression: function (operator, argument) { + this.type = Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + this.finish(); + return this; + } + }; + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + // Throw an exception + + function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function (whole, index) { + assert(index < args.length, 'Message reference must be in range'); + return args[index]; + } + ); + + if (typeof token.lineNumber === 'number') { + error = new Error('Line ' + token.lineNumber + ': ' + msg); + error.index = token.start; + error.lineNumber = token.lineNumber; + error.column = token.start - lineStart + 1; + } else { + error = new Error('Line ' + lineNumber + ': ' + msg); + error.index = index; + error.lineNumber = lineNumber; + error.column = index - lineStart + 1; + } + + error.description = msg; + throw error; + } + + function throwErrorTolerant() { + try { + throwError.apply(null, arguments); + } catch (e) { + if (extra.errors) { + extra.errors.push(e); + } else { + throw e; + } + } + } + + + // Throw an exception because of the token. + + function throwUnexpected(token) { + if (token.type === Token.EOF) { + throwError(token, Messages.UnexpectedEOS); + } + + if (token.type === Token.NumericLiteral) { + throwError(token, Messages.UnexpectedNumber); + } + + if (token.type === Token.StringLiteral) { + throwError(token, Messages.UnexpectedString); + } + + if (token.type === Token.Identifier) { + throwError(token, Messages.UnexpectedIdentifier); + } + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + throwError(token, Messages.UnexpectedReserved); + } else if (strict && isStrictModeReservedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictReservedWord); + return; + } + throwError(token, Messages.UnexpectedToken, token.value); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, Messages.UnexpectedToken, token.value); + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpected(token); + } + } + + /** + * @name expectTolerant + * @description Quietly expect the given token value when in tolerant mode, otherwise delegates + * to expect(value) + * @param {String} value The value we are expecting the lookahead token to have + * @since 2.0 + */ + function expectTolerant(value) { + if (extra.errors) { + var token = lookahead; + if (token.type !== Token.Punctuator && token.value !== value) { + throwErrorTolerant(token, Messages.UnexpectedToken, token.value); + } else { + lex(); + } + } else { + expect(value); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + return lookahead.type === Token.Punctuator && lookahead.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + return lookahead.type === Token.Keyword && lookahead.value === keyword; + } + + function consumeSemicolon() { + var line; + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(index) === 0x3B || match(';')) { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + return; + } + + if (lookahead.type !== Token.EOF && !match('}')) { + throwUnexpected(lookahead); + } + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = [], node = new Node(); + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return node.finishArrayExpression(elements); + } + + // 11.1.5 Object Initialiser + + function parseObjectPropertyKey() { + var token, node = new Node(); + + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return node.finishLiteral(token); + } + + return node.finishIdentifier(token.value); + } + + function parseObjectProperty() { + var token, key, id, value, node = new Node(); + + token = lookahead; + + if (token.type === Token.Identifier) { + id = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', id, value); + } + if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', key, value); + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, key, kind, map = {}, toString = String, node = new Node(); + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + + key = '$' + name; + if (Object.prototype.hasOwnProperty.call(map, key)) { + if (map[key] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } else if (map[key] & kind) { + throwErrorTolerant({}, Messages.AccessorGetSet); + } + } + map[key] |= kind; + } else { + map[key] = kind; + } + + properties.push(property); + + if (!match('}')) { + expectTolerant(','); + } + } + + expect('}'); + + return node.finishObjectExpression(properties); + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + ++state.parenthesisCount; + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + var legalKeywords = {"if":1, "this":1}; + + function parsePrimaryExpression() { + var type, token, expr, node; + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + type = lookahead.type; + node = new Node(); + + if (type === Token.Identifier || legalKeywords[lookahead.value]) { + expr = node.finishIdentifier(lex().value); + } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && lookahead.octal) { + throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); + } + expr = node.finishLiteral(lex()); + } else if (type === Token.Keyword) { + throw new Error("Disabled."); + } else if (type === Token.BooleanLiteral) { + token = lex(); + token.value = (token.value === 'true'); + expr = node.finishLiteral(token); + } else if (type === Token.NullLiteral) { + token = lex(); + token.value = null; + expr = node.finishLiteral(token); + } else if (match('/') || match('/=')) { + if (typeof extra.tokens !== 'undefined') { + expr = node.finishLiteral(collectRegex()); + } else { + expr = node.finishLiteral(scanRegExp()); + } + peek(); + } else { + throwUnexpected(lex()); + } + + return expr; + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expectTolerant(','); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token, node = new Node(); + + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return node.finishIdentifier(token.value); + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseLeftHandSideExpressionAllowCall() { + var expr, args, property, startToken, previousAllowIn = state.allowIn; + + startToken = lookahead; + state.allowIn = true; + expr = parsePrimaryExpression(); + + for (;;) { + if (match('.')) { + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (match('(')) { + args = parseArguments(); + expr = new WrappingNode(startToken).finishCallExpression(expr, args); + } else if (match('[')) { + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else { + break; + } + } + state.allowIn = previousAllowIn; + + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(); + + if (lookahead.type === Token.Punctuator) { + if ((match('++') || match('--')) && !peekLineTerminator()) { + throw new Error("Disabled."); + } + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr, startToken; + + if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + throw new Error("Disabled."); + } else if (match('+') || match('-') || match('~') || match('!')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + throw new Error("Disabled."); + } else { + expr = parsePostfixExpression(); + } + + return expr; + } + + function binaryPrecedence(token, allowIn) { + var prec = 0; + + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + prec = 7; + break; + + case 'in': + prec = allowIn ? 7 : 0; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; + } + + // 11.5 Multiplicative Operators + // 11.6 Additive Operators + // 11.7 Bitwise Shift Operators + // 11.8 Relational Operators + // 11.9 Equality Operators + // 11.10 Binary Bitwise Operators + // 11.11 Binary Logical Operators + + function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = parseUnaryExpression(); + + token = lookahead; + prec = binaryPrecedence(token, state.allowIn); + if (prec === 0) { + return left; + } + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = parseUnaryExpression(); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = parseUnaryExpression(); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; + } + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent, alternate, startToken; + + startToken = lookahead; + + expr = parseBinaryExpression(); + + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + alternate = parseAssignmentExpression(); + + expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); + } + + return expr; + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var oldParenthesisCount, token, expr, startToken; + + oldParenthesisCount = state.parenthesisCount; + + startToken = lookahead; + token = lookahead; + + expr = parseConditionalExpression(); + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr = parseAssignmentExpression(); + + if (match(',')) { + throw new Error("Disabled."); // no sequence expressions + } + + return expr; + } + + // 12.4 Expression Statement + + function parseExpressionStatement(node) { + var expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 12 Statements + + function parseStatement() { + var type = lookahead.type, + expr, + node; + + if (type === Token.EOF) { + throwUnexpected(lookahead); + } + + if (type === Token.Punctuator && lookahead.value === '{') { + throw new Error("Disabled."); // block statement + } + + node = new Node(); + + if (type === Token.Punctuator) { + switch (lookahead.value) { + case ';': + throw new Error("Disabled."); // empty statement + case '(': + return parseExpressionStatement(node); + default: + break; + } + } else if (type === Token.Keyword) { + throw new Error("Disabled."); // keyword + } + + expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 14 Program + + function parseSourceElement() { + if (lookahead.type === Token.Keyword) { + switch (lookahead.value) { + case 'const': + case 'let': + throw new Error("Disabled."); + case 'function': + throw new Error("Disabled."); + default: + return parseStatement(); + } + } + + if (lookahead.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead; + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var body, node; + + skipComment(); + peek(); + node = new Node(); + strict = true; // assume strict + + body = parseSourceElements(); + return node.finishProgram(body); + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (entry.regex) { + token.regex = { + pattern: entry.regex.pattern, + flags: entry.regex.flags + }; + } + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function tokenize(code, options) { + var toString, + tokens; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + + // Options matching. + options = options || {}; + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + extra.tokenize = true; + // The following two fields are necessary to compute the Regex tokens. + extra.openParenToken = -1; + extra.openCurlyToken = -1; + + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + + try { + peek(); + if (lookahead.type === Token.EOF) { + return extra.tokens; + } + + lex(); + while (lookahead.type !== Token.EOF) { + try { + lex(); + } catch (lexError) { + if (extra.errors) { + extra.errors.push(lexError); + // We have to break on the first error + // to avoid infinite loops. + break; + } else { + throw lexError; + } + } + } + + filterTokenLocation(); + tokens = extra.tokens; + if (typeof extra.errors !== 'undefined') { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + return tokens; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + parenthesisCount: 0, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + } + + try { + program = parseProgram(); + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + + return program; + } + + return { + tokenize: tokenize, + parse: parse + }; + + })(); +},{}],47:[function(require,module,exports){ + var ts = Date.now(); + + function write(msg) { + msg = '[Vega Log] ' + msg; + console.log(msg); + } + + function error(msg) { + msg = '[Vega Err] ' + msg; + console.error(msg); + } + + function debug(input, args) { + if (!debug.enable) return; + var log = Function.prototype.bind.call(console.log, console); + var state = { + prevTime: Date.now() - ts, + stamp: input.stamp + }; + + if (input.add) { + state.add = input.add.length; + state.mod = input.mod.length; + state.rem = input.rem.length; + state.reflow = !!input.reflow; + } + + log.apply(console, (args.push(JSON.stringify(state)), args)); + ts = Date.now(); + } + + module.exports = { + log: write, + error: error, + debug: (debug.enable = false, debug) + }; + +},{}],48:[function(require,module,exports){ + module.exports = { + path: require('./path'), + render: require('./render'), + Item: require('./util/Item'), + bound: require('./util/bound'), + Bounds: require('./util/Bounds'), + canvas: require('./util/canvas'), + Gradient: require('./util/Gradient'), + toJSON: require('./util/scene').toJSON, + fromJSON: require('./util/scene').fromJSON + }; +},{"./path":50,"./render":70,"./util/Bounds":76,"./util/Gradient":78,"./util/Item":80,"./util/bound":81,"./util/canvas":82,"./util/scene":84}],49:[function(require,module,exports){ + var segmentCache = {}, + bezierCache = {}, + join = [].join; + +// Copied from Inkscape svgtopdf, thanks! + function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) { + var key = join.call(arguments); + if (segmentCache[key]) { + return segmentCache[key]; + } + + var th = rotateX * (Math.PI/180); + var sin_th = Math.sin(th); + var cos_th = Math.cos(th); + rx = Math.abs(rx); + ry = Math.abs(ry); + var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5; + var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5; + var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry); + if (pl > 1) { + pl = Math.sqrt(pl); + rx *= pl; + ry *= pl; + } + + var a00 = cos_th / rx; + var a01 = sin_th / rx; + var a10 = (-sin_th) / ry; + var a11 = (cos_th) / ry; + var x0 = a00 * ox + a01 * oy; + var y0 = a10 * ox + a11 * oy; + var x1 = a00 * x + a01 * y; + var y1 = a10 * x + a11 * y; + + var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0); + var sfactor_sq = 1 / d - 0.25; + if (sfactor_sq < 0) sfactor_sq = 0; + var sfactor = Math.sqrt(sfactor_sq); + if (sweep == large) sfactor = -sfactor; + var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0); + var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0); + + var th0 = Math.atan2(y0-yc, x0-xc); + var th1 = Math.atan2(y1-yc, x1-xc); + + var th_arc = th1-th0; + if (th_arc < 0 && sweep === 1){ + th_arc += 2 * Math.PI; + } else if (th_arc > 0 && sweep === 0) { + th_arc -= 2 * Math.PI; + } + + var segs = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001))); + var result = []; + for (var i=0; i len) { + for (j=1, m=parsed.length; j=0;) { + if (h[i].type !== type) continue; + if (!handler || h[i].handler === handler) h.splice(i, 1); + } + return this; + }; + + prototype.pickEvent = function(evt) { + var rect = this._canvas.getBoundingClientRect(), + pad = this._padding, x, y; + return this.pick(this._scene, + x = (evt.clientX - rect.left), + y = (evt.clientY - rect.top), + x - pad.left, y - pad.top); + }; + +// find the scenegraph item at the current mouse position +// x, y -- the absolute x, y mouse coordinates on the canvas element +// gx, gy -- the relative coordinates within the current group + prototype.pick = function(scene, x, y, gx, gy) { + var g = this.context(), + mark = marks[scene.marktype]; + return mark.pick.call(this, g, scene, x, y, gx, gy); + }; + + module.exports = CanvasHandler; + +},{"../../util/dom":83,"../Handler":53,"./marks":62}],56:[function(require,module,exports){ + var DOM = require('../../util/dom'), + Bounds = require('../../util/Bounds'), + ImageLoader = require('../../util/ImageLoader'), + Canvas = require('../../util/canvas'), + Renderer = require('../Renderer'), + marks = require('./marks'); + + function CanvasRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + } + + CanvasRenderer.RETINA = true; + + var base = Renderer.prototype; + var prototype = (CanvasRenderer.prototype = Object.create(base)); + prototype.constructor = CanvasRenderer; + + prototype.initialize = function(el, width, height, padding) { + this._canvas = Canvas.instance(width, height); + if (el) { + DOM.clear(el, 0).appendChild(this._canvas); + this._canvas.setAttribute('class', 'marks'); + } + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + Canvas.resize(this._canvas, this._width, this._height, + this._padding, CanvasRenderer.RETINA); + return this; + }; + + prototype.canvas = function() { + return this._canvas; + }; + + prototype.context = function() { + return this._canvas ? this._canvas.getContext('2d') : null; + }; + + prototype.pendingImages = function() { + return this._loader.pending(); + }; + + function clipToBounds(g, items) { + if (!items) return null; + + var b = new Bounds(), i, n, item, mark, group; + for (i=0, n=items.length; i 0) { + if (group.fill && util.fill(g, group, opac)) { + g.fillRect(gx, gy, w, h); + } + if (group.stroke && util.stroke(g, group, opac)) { + g.strokeRect(gx, gy, w, h); + } + } + } + + // setup graphics context + g.save(); + g.translate(gx, gy); + if (group.clip) { + g.beginPath(); + g.rect(0, 0, w, h); + g.clip(); + } + if (bounds) bounds.translate(-gx, -gy); + + // draw group contents + for (j=0, m=axes.length; j=0;) { + group = groups[i]; + + // first hit test against bounding box + // if a group is clipped, that should be handled by the bounds check. + b = group.bounds; + if (b && !b.contains(gx, gy)) continue; + + // passed bounds check, so test sub-groups + axes = group.axisItems || EMPTY; + items = group.items || EMPTY; + legends = group.legendItems || EMPTY; + dx = (group.x || 0); + dy = (group.y || 0); + + g.save(); + g.translate(dx, dy); + dx = gx - dx; + dy = gy - dy; + for (j=legends.length; --j>=0;) { + subscene = legends[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interactive !== false && subscene.layer !== 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=items.length; --j>=0;) { + subscene = items[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interative !== false && subscene.layer === 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + g.restore(); + + if (scene.interactive !== false && (group.fill || group.stroke) && + dx >= 0 && dx <= group.width && dy >= 0 && dy <= group.height) { + return group; + } + } + + return null; + } + + module.exports = { + draw: draw, + pick: pick + }; + +},{"./util":69}],61:[function(require,module,exports){ + var util = require('./util'); + + function draw(g, scene, bounds) { + if (!scene.items || !scene.items.length) return; + + var renderer = this, + items = scene.items, o; + + for (var i=0, len=items.length; i= 0;) { + o = scene.items[i]; b = o.bounds; + // first hit test against bounding box + if ((b && !b.contains(gx, gy)) || !b) continue; + // if in bounding box, perform more careful test + if (test(g, o, x, y, gx, gy)) return o; + } + return null; + }; + } + + function testPath(path, filled) { + return function(g, o, x, y) { + var item = Array.isArray(o) ? o[0] : o, + fill = (filled == null) ? item.fill : filled, + stroke = item.stroke && g.isPointInStroke, lw, lc; + + if (stroke) { + lw = item.strokeWidth; + lc = item.strokeCap; + g.lineWidth = lw != null ? lw : 1; + g.lineCap = lc != null ? lc : 'butt'; + } + + return path(g, o) ? false : + (fill && g.isPointInPath(x, y)) || + (stroke && g.isPointInStroke(x, y)); + }; + } + + function pickPath(path) { + return pick(testPath(path)); + } + + function fill(g, o, opacity) { + opacity *= (o.fillOpacity==null ? 1 : o.fillOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.fillStyle = color(g, o, o.fill); + return true; + } else { + return false; + } + } + + function stroke(g, o, opacity) { + var lw = (lw = o.strokeWidth) != null ? lw : 1, lc; + if (lw <= 0) return false; + + opacity *= (o.strokeOpacity==null ? 1 : o.strokeOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.strokeStyle = color(g, o, o.stroke); + g.lineWidth = lw; + g.lineCap = (lc = o.strokeCap) != null ? lc : 'butt'; + g.vgLineDash(o.strokeDash || null); + g.vgLineDashOffset(o.strokeDashOffset || 0); + return true; + } else { + return false; + } + } + + function color(g, o, value) { + return (value.id) ? + gradient(g, value, o.bounds) : + value; + } + + function gradient(g, p, b) { + var w = b.width(), + h = b.height(), + x1 = b.x1 + p.x1 * w, + y1 = b.y1 + p.y1 * h, + x2 = b.x1 + p.x2 * w, + y2 = b.y1 + p.y2 * h, + grad = g.createLinearGradient(x1, y1, x2, y2), + stop = p.stops, + i, n; + + for (i=0, n=stop.length; i=0;) { + if (h[i].type === type && !handler || h[i].handler === handler) { + svg.removeEventListener(name, h[i].listener); + h.splice(i, 1); + } + } + return this; + }; + + module.exports = SVGHandler; + +},{"../../util/dom":83,"../Handler":53}],72:[function(require,module,exports){ + var ImageLoader = require('../../util/ImageLoader'), + Renderer = require('../Renderer'), + text = require('../../util/text'), + DOM = require('../../util/dom'), + SVG = require('../../util/svg'), + ns = SVG.metadata.xmlns, + marks = require('./marks'); + + function SVGRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + this._dirtyID = 0; + } + + var base = Renderer.prototype; + var prototype = (SVGRenderer.prototype = Object.create(base)); + prototype.constructor = SVGRenderer; + + prototype.initialize = function(el, width, height, padding) { + if (el) { + this._svg = DOM.child(el, 0, 'svg', ns, 'marks'); + DOM.clear(el, 1); + // set the svg root group + this._root = DOM.child(this._svg, 0, 'g', ns); + DOM.clear(this._svg, 1); + } + + // create the svg definitions cache + this._defs = { + clip_id: 1, + gradient: {}, + clipping: {} + }; + + // set background color if defined + this.background(this._bgcolor); + + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.background = function(bgcolor) { + if (arguments.length && this._svg) { + this._svg.style.setProperty('background-color', bgcolor); + } + return base.background.apply(this, arguments); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + + if (this._svg) { + var w = this._width, + h = this._height, + p = this._padding; + + this._svg.setAttribute('width', w + p.left + p.right); + this._svg.setAttribute('height', h + p.top + p.bottom); + + this._root.setAttribute('transform', 'translate('+p.left+','+p.top+')'); + } + + return this; + }; + + prototype.svg = function() { + if (!this._svg) return null; + + var attr = { + 'class': 'marks', + 'width': this._width + this._padding.left + this._padding.right, + 'height': this._height + this._padding.top + this._padding.bottom, + }; + for (var key in SVG.metadata) { + attr[key] = SVG.metadata[key]; + } + + return DOM.openTag('svg', attr) + this._svg.innerHTML + DOM.closeTag('svg'); + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + +// -- Render entry point -- + + prototype.render = function(scene, items) { + if (this._dirtyCheck(items)) { + if (this._dirtyAll) this._resetDefs(); + this.draw(this._root, scene, -1); + DOM.clear(this._root, 1); + } + this.updateDefs(); + return this; + }; + + prototype.draw = function(el, scene, index) { + this.drawMark(el, scene, index, marks[scene.marktype]); + }; + + +// -- Manage SVG definitions ('defs') block -- + + prototype.updateDefs = function() { + var svg = this._svg, + defs = this._defs, + el = defs.el, + index = 0, id; + + for (id in defs.gradient) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateGradient(el, defs.gradient[id], index++); + } + + for (id in defs.clipping) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateClipping(el, defs.clipping[id], index++); + } + + // clean-up + if (el) { + if (index === 0) { + svg.removeChild(el); + defs.el = null; + } else { + DOM.clear(el, index); + } + } + }; + + function updateGradient(el, grad, index) { + var i, n, stop; + + el = DOM.child(el, index, 'linearGradient', ns); + el.setAttribute('id', grad.id); + el.setAttribute('x1', grad.x1); + el.setAttribute('x2', grad.x2); + el.setAttribute('y1', grad.y1); + el.setAttribute('y2', grad.y2); + + for (i=0, n=grad.stops.length; i 0) ? openTag('defs') + defs + closeTag('defs') : ''; + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + var object; + + function emit(name, value, ns, prefixed) { + object[prefixed || name] = value; + } + + prototype.attributes = function(attr, item) { + object = {}; + attr(emit, item, this); + return object; + }; + + prototype.mark = function(scene) { + var mdef = MARKS[scene.marktype], + tag = mdef.tag, + attr = mdef.attr, + nest = mdef.nest || false, + data = nest ? + (scene.items && scene.items.length ? [scene.items[0]] : []) : + (scene.items || []), + defs = this._defs, + str = '', + style, i, item; + + if (tag !== 'g' && scene.interactive === false) { + style = 'style="pointer-events: none;"'; + } + + // render opening group tag + str += openTag('g', { + 'class': DOM.cssClass(scene) + }, style); + + // render contained elements + for (i=0; i/g, '>'); + } + + module.exports = SVGStringRenderer; + +},{"../../util/ImageLoader":79,"../../util/dom":83,"../../util/svg":85,"../../util/text":86,"../Renderer":54,"./marks":75}],74:[function(require,module,exports){ + module.exports = { + Handler: require('./SVGHandler'), + Renderer: require('./SVGRenderer'), + string: { + Renderer : require('./SVGStringRenderer') + } + }; +},{"./SVGHandler":71,"./SVGRenderer":72,"./SVGStringRenderer":73}],75:[function(require,module,exports){ + var text = require('../../util/text'), + SVG = require('../../util/svg'), + textAlign = SVG.textAlign, + path = SVG.path; + + function translateItem(o) { + return translate(o.x || 0, o.y || 0); + } + + function translate(x, y) { + return 'translate(' + x + ',' + y + ')'; + } + + module.exports = { + arc: { + tag: 'path', + type: 'arc', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.arc(o)); + } + }, + area: { + tag: 'path', + type: 'area', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.area(items)); + } + }, + group: { + tag: 'g', + type: 'group', + attr: function(emit, o, renderer) { + var id = null, defs, c; + emit('transform', translateItem(o)); + if (o.clip) { + defs = renderer._defs; + id = o.clip_id || (o.clip_id = 'clip' + defs.clip_id++); + c = defs.clipping[id] || (defs.clipping[id] = {id: id}); + c.width = o.width || 0; + c.height = o.height || 0; + } + emit('clip-path', id ? ('url(#' + id + ')') : null); + }, + background: function(emit, o) { + emit('class', 'background'); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + image: { + tag: 'image', + type: 'image', + attr: function(emit, o, renderer) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0, + url = renderer.imageURL(o.url); + + x = x - (o.align === 'center' ? w/2 : o.align === 'right' ? w : 0); + y = y - (o.baseline === 'middle' ? h/2 : o.baseline === 'bottom' ? h : 0); + + emit('href', url, 'http://www.w3.org/1999/xlink', 'xlink:href'); + emit('transform', translate(x, y)); + emit('width', w); + emit('height', h); + } + }, + line: { + tag: 'path', + type: 'line', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.line(items)); + } + }, + path: { + tag: 'path', + type: 'path', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', o.path); + } + }, + rect: { + tag: 'rect', + type: 'rect', + nest: false, + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + rule: { + tag: 'line', + type: 'rule', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('x2', o.x2 != null ? o.x2 - (o.x||0) : 0); + emit('y2', o.y2 != null ? o.y2 - (o.y||0) : 0); + } + }, + symbol: { + tag: 'path', + type: 'symbol', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.symbol(o)); + } + }, + text: { + tag: 'text', + type: 'text', + nest: false, + attr: function(emit, o) { + var dx = (o.dx || 0), + dy = (o.dy || 0) + text.offset(o), + x = (o.x || 0), + y = (o.y || 0), + a = o.angle || 0, + r = o.radius || 0, t; + + if (r) { + t = (o.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + emit('text-anchor', textAlign[o.align] || 'start'); + + if (a) { + t = translate(x, y) + ' rotate('+a+')'; + if (dx || dy) t += ' ' + translate(dx, dy); + } else { + t = translate(x+dx, y+dy); + } + emit('transform', t); + } + } + }; + +},{"../../util/svg":85,"../../util/text":86}],76:[function(require,module,exports){ + function Bounds(b) { + this.clear(); + if (b) this.union(b); + } + + var prototype = Bounds.prototype; + + prototype.clone = function() { + return new Bounds(this); + }; + + prototype.clear = function() { + this.x1 = +Number.MAX_VALUE; + this.y1 = +Number.MAX_VALUE; + this.x2 = -Number.MAX_VALUE; + this.y2 = -Number.MAX_VALUE; + return this; + }; + + prototype.set = function(x1, y1, x2, y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + return this; + }; + + prototype.add = function(x, y) { + if (x < this.x1) this.x1 = x; + if (y < this.y1) this.y1 = y; + if (x > this.x2) this.x2 = x; + if (y > this.y2) this.y2 = y; + return this; + }; + + prototype.expand = function(d) { + this.x1 -= d; + this.y1 -= d; + this.x2 += d; + this.y2 += d; + return this; + }; + + prototype.round = function() { + this.x1 = Math.floor(this.x1); + this.y1 = Math.floor(this.y1); + this.x2 = Math.ceil(this.x2); + this.y2 = Math.ceil(this.y2); + return this; + }; + + prototype.translate = function(dx, dy) { + this.x1 += dx; + this.x2 += dx; + this.y1 += dy; + this.y2 += dy; + return this; + }; + + prototype.rotate = function(angle, x, y) { + var cos = Math.cos(angle), + sin = Math.sin(angle), + cx = x - x*cos + y*sin, + cy = y - x*sin - y*cos, + x1 = this.x1, x2 = this.x2, + y1 = this.y1, y2 = this.y2; + + return this.clear() + .add(cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy) + .add(cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy) + .add(cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy) + .add(cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy); + }; + + prototype.union = function(b) { + if (b.x1 < this.x1) this.x1 = b.x1; + if (b.y1 < this.y1) this.y1 = b.y1; + if (b.x2 > this.x2) this.x2 = b.x2; + if (b.y2 > this.y2) this.y2 = b.y2; + return this; + }; + + prototype.encloses = function(b) { + return b && ( + this.x1 <= b.x1 && + this.x2 >= b.x2 && + this.y1 <= b.y1 && + this.y2 >= b.y2 + ); + }; + + prototype.intersects = function(b) { + return b && !( + this.x2 < b.x1 || + this.x1 > b.x2 || + this.y2 < b.y1 || + this.y1 > b.y2 + ); + }; + + prototype.contains = function(x, y) { + return !( + x < this.x1 || + x > this.x2 || + y < this.y1 || + y > this.y2 + ); + }; + + prototype.width = function() { + return this.x2 - this.x1; + }; + + prototype.height = function() { + return this.y2 - this.y1; + }; + + module.exports = Bounds; + +},{}],77:[function(require,module,exports){ + module.exports = function(b) { + function noop() { } + function add(x,y) { b.add(x, y); } + + return { + bounds: function(_) { + if (!arguments.length) return b; + return (b = _, this); + }, + beginPath: noop, + closePath: noop, + moveTo: add, + lineTo: add, + quadraticCurveTo: function(x1, y1, x2, y2) { + b.add(x1, y1); + b.add(x2, y2); + }, + bezierCurveTo: function(x1, y1, x2, y2, x3, y3) { + b.add(x1, y1); + b.add(x2, y2); + b.add(x3, y3); + } + }; + }; + +},{}],78:[function(require,module,exports){ + var gradient_id = 0; + + function Gradient(type) { + this.id = 'gradient_' + (gradient_id++); + this.type = type || 'linear'; + this.stops = []; + this.x1 = 0; + this.x2 = 1; + this.y1 = 0; + this.y2 = 0; + } + + var prototype = Gradient.prototype; + + prototype.stop = function(offset, color) { + this.stops.push({ + offset: offset, + color: color + }); + return this; + }; + + module.exports = Gradient; +},{}],79:[function(require,module,exports){ + (function (global){ + var load = require('datalib/src/import/load'); + + function ImageLoader(loadConfig) { + this._pending = 0; + this._config = loadConfig || ImageLoader.Config; + } + +// Overridable global default load configuration + ImageLoader.Config = null; + + var prototype = ImageLoader.prototype; + + prototype.pending = function() { + return this._pending; + }; + + prototype.params = function(uri) { + var p = {url: uri}, k; + for (k in this._config) { p[k] = this._config[k]; } + return p; + }; + + prototype.imageURL = function(uri) { + return load.sanitizeUrl(this.params(uri)); + }; + + function browser(uri, callback) { + var url = load.sanitizeUrl(this.params(uri)); + if (!url) { // error + if (callback) callback(uri, null); + return null; + } + + var loader = this, + image = new Image(); + + loader._pending += 1; + + image.onload = function() { + loader._pending -= 1; + image.loaded = true; + if (callback) callback(null, image); + }; + image.src = url; + + return image; + } + + function server(uri, callback) { + var loader = this, + image = new ((typeof window !== "undefined" ? window['canvas'] : typeof global !== "undefined" ? global['canvas'] : null).Image)(); + + loader._pending += 1; + + load(this.params(uri), function(err, data) { + loader._pending -= 1; + if (err) { + if (callback) callback(err, null); + return null; + } + image.src = data; + image.loaded = true; + if (callback) callback(null, image); + }); + + return image; + } + + prototype.loadImage = function(uri, callback) { + return load.useXHR ? + browser.call(this, uri, callback) : + server.call(this, uri, callback); + }; + + module.exports = ImageLoader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib/src/import/load":22}],80:[function(require,module,exports){ + function Item(mark) { + this.mark = mark; + } + + var prototype = Item.prototype; + + prototype.hasPropertySet = function(name) { + var props = this.mark.def.properties; + return props && props[name] != null; + }; + + prototype.cousin = function(offset, index) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + group = mark.group, + iidx = index==null ? mark.items.indexOf(this) : index, + midx = group.items.indexOf(mark) + offset; + return group.items[midx].items[iidx]; + }; + + prototype.sibling = function(offset) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + iidx = mark.items.indexOf(this) + offset; + return mark.items[iidx]; + }; + + prototype.remove = function() { + var item = this, + list = item.mark.items, + i = list.indexOf(item); + if (i >= 0) { + if (i===list.length-1) { + list.pop(); + } else { + list.splice(i, 1); + } + } + return item; + }; + + prototype.touch = function() { + if (this.pathCache) this.pathCache = null; + }; + + module.exports = Item; +},{}],81:[function(require,module,exports){ + var BoundsContext = require('./BoundsContext'), + Bounds = require('./Bounds'), + canvas = require('./canvas'), + svg = require('./svg'), + text = require('./text'), + paths = require('../path'), + parse = paths.parse, + drawPath = paths.render, + areaPath = svg.path.area, + linePath = svg.path.line, + halfpi = Math.PI / 2, + sqrt3 = Math.sqrt(3), + tan30 = Math.tan(30 * Math.PI / 180), + g2D = null, + bc = BoundsContext(); + + function context() { + return g2D || (g2D = canvas.instance(1,1).getContext('2d')); + } + + function strokeBounds(o, bounds) { + if (o.stroke && o.opacity !== 0 && o.stokeOpacity !== 0) { + bounds.expand(o.strokeWidth != null ? o.strokeWidth : 1); + } + return bounds; + } + + function pathBounds(o, path, bounds, x, y) { + if (path == null) { + bounds.set(0, 0, 0, 0); + } else { + drawPath(bc.bounds(bounds), path, x, y); + strokeBounds(o, bounds); + } + return bounds; + } + + function path(o, bounds) { + var p = o.path ? o.pathCache || (o.pathCache = parse(o.path)) : null; + return pathBounds(o, p, bounds, o.x, o.y); + } + + function area(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(areaPath(items))); + return pathBounds(item, p, bounds); + } + + function line(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(linePath(items))); + return pathBounds(item, p, bounds); + } + + function rect(o, bounds) { + var x, y; + return strokeBounds(o, bounds.set( + x = o.x || 0, + y = o.y || 0, + (x + o.width) || 0, + (y + o.height) || 0 + )); + } + + function image(o, bounds) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0; + x = x - (o.align === 'center' ? w/2 : (o.align === 'right' ? w : 0)); + y = y - (o.baseline === 'middle' ? h/2 : (o.baseline === 'bottom' ? h : 0)); + return bounds.set(x, y, x+w, y+h); + } + + function rule(o, bounds) { + var x1, y1; + return strokeBounds(o, bounds.set( + x1 = o.x || 0, + y1 = o.y || 0, + o.x2 != null ? o.x2 : x1, + o.y2 != null ? o.y2 : y1 + )); + } + + function arc(o, bounds) { + var cx = o.x || 0, + cy = o.y || 0, + ir = o.innerRadius || 0, + or = o.outerRadius || 0, + sa = (o.startAngle || 0) - halfpi, + ea = (o.endAngle || 0) - halfpi, + xmin = Infinity, xmax = -Infinity, + ymin = Infinity, ymax = -Infinity, + a, i, n, x, y, ix, iy, ox, oy; + + var angles = [sa, ea], + s = sa - (sa % halfpi); + for (i=0; i<4 && s index) { + el.removeChild(el.childNodes[--curr]); + } + return el; + }, + remove: remove, + // generate css class name for mark + cssClass: function(mark) { + return 'mark-' + mark.marktype + (mark.name ? ' '+mark.name : ''); + }, + // generate string for an opening xml tag + // tag: the name of the xml tag + // attr: hash of attribute name-value pairs to include + // raw: additional raw string to include in tag markup + openTag: function(tag, attr, raw) { + var s = '<' + tag, key, val; + if (attr) { + for (key in attr) { + val = attr[key]; + if (val != null) { + s += ' ' + key + '="' + val + '"'; + } + } + } + if (raw) s += ' ' + raw; + return s + '>'; + }, + // generate string for closing xml tag + // tag: the name of the xml tag + closeTag: function(tag) { + return ''; + } + }; + +},{}],84:[function(require,module,exports){ + var bound = require('../util/bound'); + + var sets = [ + 'items', + 'axisItems', + 'legendItems' + ]; + + var keys = [ + 'marktype', 'name', 'interactive', 'clip', + 'items', 'axisItems', 'legendItems', 'layer', + 'x', 'y', 'width', 'height', 'align', 'baseline', // layout + 'fill', 'fillOpacity', 'opacity', // fill + 'stroke', 'strokeOpacity', 'strokeWidth', 'strokeCap', // stroke + 'strokeDash', 'strokeDashOffset', // stroke dash + 'startAngle', 'endAngle', 'innerRadius', 'outerRadius', // arc + 'interpolate', 'tension', 'orient', // area, line + 'url', // image + 'path', // path + 'x2', 'y2', // rule + 'size', 'shape', // symbol + 'text', 'angle', 'theta', 'radius', 'dx', 'dy', // text + 'font', 'fontSize', 'fontWeight', 'fontStyle', 'fontVariant' // font + ]; + + function toJSON(scene, indent) { + return JSON.stringify(scene, keys, indent); + } + + function fromJSON(json) { + var scene = (typeof json === 'string' ? JSON.parse(json) : json); + return initialize(scene); + } + + function initialize(scene) { + var type = scene.marktype, + i, n, s, m, items; + + for (s=0, m=sets.length; s 0) { wait(); } else { callback(this.canvas()); } + }; + + prototype.svg = function() { + return (this._type === 'svg') ? this._renderer.svg() : null; + }; + + prototype.initialize = function() { + var w = this._width, + h = this._height, + bg = this._bgcolor, + pad = this._padding, + config = this.model().config(); + + if (this._viewport) { + w = this._viewport[0] - (pad ? pad.left + pad.right : 0); + h = this._viewport[1] - (pad ? pad.top + pad.bottom : 0); + } + + this._renderer = (this._renderer || new this._io.Renderer(config.load)) + .initialize(null, w, h, pad) + .background(bg); + + return this; + }; + + module.exports = HeadlessView; +},{"./View":89,"vega-scenegraph":48}],88:[function(require,module,exports){ + var dl = require('datalib'), + df = require('vega-dataflow'), + ChangeSet = df.ChangeSet, + Base = df.Graph.prototype, + Node = df.Node, // jshint ignore:line + GroupBuilder = require('../scene/GroupBuilder'), + visit = require('../scene/visit'), + config = require('./config'); + + function Model(cfg) { + this._defs = {}; + this._predicates = {}; + this._scene = null; + + this._node = null; + this._builder = null; // Top-level scenegraph builder + + this._reset = {axes: false, legends: false}; + + this.config(cfg); + Base.init.call(this); + } + + var prototype = (Model.prototype = Object.create(Base)); + prototype.constructor = Model; + + prototype.defs = function(defs) { + if (!arguments.length) return this._defs; + this._defs = defs; + return this; + }; + + prototype.config = function(cfg) { + if (!arguments.length) return this._config; + this._config = Object.create(config); + for (var name in cfg) { + var x = cfg[name], y = this._config[name]; + if (dl.isObject(x) && dl.isObject(y)) { + dl.extend(y, x); + } else { + this._config[name] = x; + } + } + + return this; + }; + + prototype.width = function(width) { + if (this._defs) this._defs.width = width; + if (this._defs && this._defs.marks) this._defs.marks.width = width; + if (this._scene) { + this._scene.items[0].width = width; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.height = function(height) { + if (this._defs) this._defs.height = height; + if (this._defs && this._defs.marks) this._defs.marks.height = height; + if (this._scene) { + this._scene.items[0].height = height; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.node = function() { + return this._node || (this._node = new Node(this)); + }; + + prototype.data = function() { + var data = Base.data.apply(this, arguments); + if (arguments.length > 1) { // new Datasource + this.node().addListener(data.pipeline()[0]); + } + return data; + }; + + function predicates(name) { + var m = this, pred = {}; + if (!dl.isArray(name)) return this._predicates[name]; + name.forEach(function(n) { pred[n] = m._predicates[n]; }); + return pred; + } + + prototype.predicate = function(name, predicate) { + if (arguments.length === 1) return predicates.call(this, name); + return (this._predicates[name] = predicate); + }; + + prototype.predicates = function() { return this._predicates; }; + + prototype.scene = function(renderer) { + if (!arguments.length) return this._scene; + + if (this._builder) { + this.node().removeListener(this._builder); + this._builder._groupBuilder.disconnect(); + } + + var m = this, + b = this._builder = new Node(this); + + b.evaluate = function(input) { + if (b._groupBuilder) return input; + + var gb = b._groupBuilder = new GroupBuilder(m, m._defs.marks, m._scene={}), + p = gb.pipeline(); + + this.addListener(gb.connect()); + p[p.length-1].addListener(renderer); + return input; + }; + + this.addListener(b); + return this; + }; + + prototype.reset = function() { + if (this._scene && this._reset.axes) { + visit(this._scene, function(item) { + if (item.axes) item.axes.forEach(function(axis) { axis.reset(); }); + }); + this._reset.axes = false; + } + if (this._scene && this._reset.legends) { + visit(this._scene, function(item) { + if (item.legends) item.legends.forEach(function(l) { l.reset(); }); + }); + this._reset.legends = false; + } + return this; + }; + + prototype.addListener = function(l) { + this.node().addListener(l); + }; + + prototype.removeListener = function(l) { + this.node().removeListener(l); + }; + + prototype.fire = function(cs) { + if (!cs) cs = ChangeSet.create(); + this.propagate(cs, this.node()); + }; + + module.exports = Model; +},{"../scene/GroupBuilder":112,"../scene/visit":117,"./config":90,"datalib":26,"vega-dataflow":41}],89:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + sg = require('vega-scenegraph').render, + log = require('vega-logging'), + Deps = df.Dependencies, + parseStreams = require('../parse/streams'), + Encoder = require('../scene/Encoder'), + Transition = require('../scene/Transition'); + + function View(el, width, height) { + this._el = null; + this._model = null; + this._width = this.__width = width || 500; + this._height = this.__height = height || 300; + this._bgcolor = null; + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._viewport = null; + this._renderer = null; + this._handler = null; + this._streamer = null; // Targeted update for streaming changes + this._changeset = null; + this._repaint = true; // Full re-render on every re-init + this._renderers = sg; + this._io = null; + this._api = {}; // Stash streaming data API sandboxes. + } + + var prototype = View.prototype; + + prototype.model = function(model) { + if (!arguments.length) return this._model; + if (this._model !== model) { + this._model = model; + this._streamer = new df.Node(model); + this._streamer._rank = -1; // HACK: To reduce re-ranking churn. + this._changeset = df.ChangeSet.create(); + if (this._handler) this._handler.model(model); + } + return this; + }; + +// Sandboxed streaming data API + function streaming(src) { + var view = this, + ds = this._model.data(src), + name = ds.name(), + listener = ds.pipeline()[0], + streamer = this._streamer, + api = {}; + + // If we have it stashed, don't create a new closure. + if (this._api[src]) return this._api[src]; + + api.insert = function(vals) { + ds.insert(dl.duplicate(vals)); // Don't pollute the environment + streamer.addListener(listener); + view._changeset.data[name] = 1; + return api; + }; + + api.update = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.update.apply(ds, arguments), api); + }; + + api.remove = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.remove.apply(ds, arguments), api); + }; + + api.values = function() { return ds.values(); }; + + return (this._api[src] = api); + } + + prototype.data = function(data) { + var v = this; + if (!arguments.length) return v._model.values(); + else if (dl.isString(data)) return streaming.call(v, data); + else if (dl.isObject(data)) { + dl.keys(data).forEach(function(k) { + var api = streaming.call(v, k); + data[k](api); + }); + } + return this; + }; + + var VIEW_SIGNALS = dl.toMap(['width', 'height', 'padding']); + + prototype.signal = function(name, value, propagate) { + var m = this._model, + key, values; + + // Getter. Returns the value for the specified signal, or + // returns all signal values. + if (!arguments.length) { + return m.values(Deps.SIGNALS); + } else if (arguments.length === 1 && dl.isString(name)) { + return m.values(Deps.SIGNALS, name); + } + + // Setter. Can be done in batch or individually. In either case, + // the final argument determines if set values should propagate. + if (dl.isObject(name)) { + values = name; + propagate = value; + } else { + values = {}; + values[name] = value; + } + for (key in values) { + if (VIEW_SIGNALS[key]) { + this[key](values[key]); + } else { + setSignal.call(this, key, values[key], propagate); + } + } + return this; + }; + + function setSignal(name, value, propagate) { + var cs = this._changeset; + this._streamer.addListener(this._model.signal(name).value(value)); + if (propagate !== false) cs.signals[name] = 1; + cs.reflow = true; + } + + prototype.width = function(width) { + if (!arguments.length) return this.__width; + if (this.__width !== width) { + this._width = this.__width = width; + this.model().width(width); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'width', width); + } + return this; + }; + + prototype.height = function(height) { + if (!arguments.length) return this.__height; + if (this.__height !== height) { + this._height = this.__height = height; + this.model().height(height); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'height', height); + } + return this; + }; + + prototype.background = function(bgcolor) { + if (!arguments.length) return this._bgcolor; + if (this._bgcolor !== bgcolor) { + this._bgcolor = bgcolor; + this.initialize(); + } + return this; + }; + + prototype.padding = function(pad) { + if (!arguments.length) return this._padding; + if (this._padding !== pad) { + if (dl.isString(pad)) { + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._strict = (pad === 'strict'); + } else { + this._autopad = 0; + this._padding = pad; + this._strict = false; + } + if (this._renderer) this._renderer.resize(this._width, this._height, this._padding); + if (this._handler) this._handler.padding(this._padding); + setSignal.call(this, 'padding', this._padding); + } + return (this._repaint = true, this); + }; + + prototype.autopad = function(opt) { + if (this._autopad < 1) return this; + else this._autopad = 0; + + var b = this.model().scene().bounds, + pad = this._padding, + config = this.model().config(), + inset = config.autopadInset, + l = b.x1 < 0 ? Math.ceil(-b.x1) + inset : 0, + t = b.y1 < 0 ? Math.ceil(-b.y1) + inset : 0, + r = b.x2 > this._width ? Math.ceil(+b.x2 - this._width) + inset : 0; + b = b.y2 > this._height ? Math.ceil(+b.y2 - this._height) + inset : 0; + pad = {left:l, top:t, right:r, bottom:b}; + + if (this._strict) { + this._autopad = 0; + this._padding = pad; + this._width = Math.max(0, this.__width - (l+r)); + this._height = Math.max(0, this.__height - (t+b)); + + this._model.width(this._width).height(this._height).reset(); + setSignal.call(this, 'width', this._width); + setSignal.call(this, 'height', this._height); + setSignal.call(this, 'padding', pad); + + this.initialize().update({props:'enter'}).update({props:'update'}); + } else { + this.padding(pad).update(opt); + } + return this; + }; + + prototype.viewport = function(size) { + if (!arguments.length) return this._viewport; + if (this._viewport !== size) { + this._viewport = size; + this.initialize(); + } + return this; + }; + + prototype.renderer = function(type) { + if (!arguments.length) return this._renderer; + if (this._renderers[type]) type = this._renderers[type]; + else if (dl.isString(type)) throw new Error('Unknown renderer: ' + type); + else if (!type) throw new Error('No renderer specified'); + + if (this._io !== type) { + this._io = type; + this._renderer = null; + this.initialize(); + if (this._build) this.render(); + } + return this; + }; + + prototype.initialize = function(el) { + var v = this, prevHandler, + w = v._width, h = v._height, pad = v._padding, bg = v._bgcolor, + config = this.model().config(); + + if (!arguments.length || el === null) { + el = this._el ? this._el.parentNode : null; + if (!el) return this; // This View cannot init w/o an + } + + // clear pre-existing container + d3.select(el).select('div.vega').remove(); + + // add div container + this._el = el = d3.select(el) + .append('div') + .attr('class', 'vega') + .style('position', 'relative') + .node(); + if (v._viewport) { + d3.select(el) + .style('width', (v._viewport[0] || w)+'px') + .style('height', (v._viewport[1] || h)+'px') + .style('overflow', 'auto'); + } + + // renderer + sg.canvas.Renderer.RETINA = config.render.retina; + v._renderer = (v._renderer || new this._io.Renderer(config.load)) + .initialize(el, w, h, pad) + .background(bg); + + // input handler + prevHandler = v._handler; + v._handler = new this._io.Handler() + .initialize(el, pad, v); + + if (prevHandler) { + prevHandler.handlers().forEach(function(h) { + v._handler.on(h.type, h.handler); + }); + } else { + // Register event listeners for signal stream definitions. + v._detach = parseStreams(this); + } + + return (this._repaint = true, this); + }; + + prototype.destroy = function() { + if (this._detach) this._detach(); + }; + + function build() { + var v = this; + v._renderNode = new df.Node(v._model) + .router(true); + + v._renderNode.evaluate = function(input) { + log.debug(input, ['rendering']); + + var s = v._model.scene(), + h = v._handler; + + if (h && h.scene) h.scene(s); + + if (input.trans) { + input.trans.start(function(items) { v._renderer.render(s, items); }); + } else if (v._repaint) { + v._renderer.render(s); + v._repaint = false; + } else if (input.dirty.length) { + v._renderer.render(s, input.dirty); + } + + if (input.dirty.length) { + input.dirty.forEach(function(i) { i._dirty = false; }); + s.items[0]._dirty = false; + } + + // For all updated datasources, clear their previous values. + for (var d in input.data) { v._model.data(d).synchronize(); } + return input; + }; + + return (v._model.scene(v._renderNode), true); + } + + prototype.update = function(opt) { + opt = opt || {}; + var v = this, + model = this._model, + streamer = this._streamer, + cs = this._changeset, + trans = opt.duration ? new Transition(opt.duration, opt.ease) : null; + + if (trans) cs.trans = trans; + if (opt.props !== undefined) { + if (dl.keys(cs.data).length > 0) { + throw Error( + 'New data values are not reflected in the visualization.' + + ' Please call view.update() before updating a specified property set.' + ); + } + + cs.reflow = true; + cs.request = opt.props; + } + + var built = v._build; + v._build = v._build || build.call(this); + + // If specific items are specified, short-circuit dataflow graph. + // Else-If there are streaming updates, perform a targeted propagation. + // Otherwise, re-evaluate the entire model (datasources + scene). + if (opt.items && built) { + Encoder.update(model, opt.trans, opt.props, opt.items, cs.dirty); + v._renderNode.evaluate(cs); + } else if (streamer.listeners().length && built) { + // Include re-evaluation entire model when repaint flag is set + if (this._repaint) streamer.addListener(model.node()); + model.propagate(cs, streamer); + streamer.disconnect(); + } else { + model.fire(cs); + } + + v._changeset = df.ChangeSet.create(); + + return v.autopad(opt); + }; + + prototype.toImageURL = function(type) { + var v = this, Renderer; + + // lookup appropriate renderer + switch (type || 'png') { + case 'canvas': + case 'png': + Renderer = sg.canvas.Renderer; break; + case 'svg': + Renderer = sg.svg.string.Renderer; break; + default: throw Error('Unrecognized renderer type: ' + type); + } + + var retina = sg.canvas.Renderer.RETINA; + sg.canvas.Renderer.RETINA = false; // ignore retina screen + + // render the scenegraph + var ren = new Renderer(v._model.config.load) + .initialize(null, v._width, v._height, v._padding) + .render(v._model.scene()); + + sg.canvas.Renderer.RETINA = retina; // restore retina settings + + // return data url + if (type === 'svg') { + var blob = new Blob([ren.svg()], {type: 'image/svg+xml'}); + return window.URL.createObjectURL(blob); + } else { + return ren.canvas().toDataURL('image/png'); + } + }; + + prototype.render = function(items) { + this._renderer.render(this._model.scene(), items); + return this; + }; + + prototype.on = function() { + this._handler.on.apply(this._handler, arguments); + return this; + }; + + prototype.onSignal = function(name, handler) { + this._model.signal(name).on(handler); + return this; + }; + + prototype.off = function() { + this._handler.off.apply(this._handler, arguments); + return this; + }; + + prototype.offSignal = function(name, handler) { + this._model.signal(name).off(handler); + return this; + }; + + View.factory = function(model) { + var HeadlessView = require('./HeadlessView'); + return function(opt) { + opt = opt || {}; + var defs = model.defs(); + var v = (opt.el ? new View() : new HeadlessView()) + .model(model) + .renderer(opt.renderer || 'canvas') + .width(defs.width) + .height(defs.height) + .background(defs.background) + .padding(defs.padding) + .viewport(defs.viewport) + .initialize(opt.el); + + if (opt.data) v.data(opt.data); + + if (opt.hover !== false && opt.el) { + v.on('mouseover', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'hover', items:item}); + } + }) + .on('mouseout', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'update', items:item}); + } + }); + } + + return v; + }; + }; + + module.exports = View; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"../parse/streams":107,"../scene/Encoder":111,"../scene/Transition":114,"./HeadlessView":87,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],90:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + config = {}; + + config.load = { + // base url for loading external data files + // used only for server-side operation + baseURL: '', + // Allows domain restriction when using data loading via XHR. + // To enable, set it to a list of allowed domains + // e.g., ['wikipedia.org', 'eff.org'] + domainWhiteList: false + }; + +// inset padding for automatic padding calculation + config.autopadInset = 5; + +// extensible scale lookup table +// all d3.scale.* instances also supported + config.scale = { + time: d3.time.scale, + utc: d3.time.scale.utc + }; + +// default rendering settings + config.render = { + retina: true + }; + +// root scenegraph group + config.scene = { + fill: undefined, + fillOpacity: undefined, + stroke: undefined, + strokeOpacity: undefined, + strokeWidth: undefined, + strokeDash: undefined, + strokeDashOffset: undefined + }; + +// default axis properties + config.axis = { + orient: 'bottom', + ticks: 10, + padding: 3, + axisColor: '#000', + axisWidth: 1, + gridColor: '#000', + gridOpacity: 0.15, + tickColor: '#000', + tickLabelColor: '#000', + tickWidth: 1, + tickSize: 6, + tickLabelFontSize: 11, + tickLabelFont: 'sans-serif', + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold', + titleOffset: 'auto', + titleOffsetAutoMin: 30, + titleOffsetAutoMax: Infinity, + titleOffsetAutoMargin: 4 + }; + +// default legend properties + config.legend = { + orient: 'right', + offset: 20, + padding: 3, // padding between legend items and border + margin: 2, // extra margin between two consecutive legends + gradientStrokeColor: '#888', + gradientStrokeWidth: 1, + gradientHeight: 16, + gradientWidth: 100, + labelColor: '#000', + labelFontSize: 10, + labelFont: 'sans-serif', + labelAlign: 'left', + labelBaseline: 'middle', + labelOffset: 8, + symbolShape: 'circle', + symbolSize: 50, + symbolColor: '#888', + symbolStrokeWidth: 1, + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold' + }; + +// default color values + config.color = { + rgb: [128, 128, 128], + lab: [50, 0, 0], + hcl: [0, 0, 50], + hsl: [0, 0, 0.5] + }; + +// default scale ranges + config.range = { + category10: d3.scale.category10().range(), + category20: d3.scale.category20().range(), + category20b: d3.scale.category20b().range(), + category20c: d3.scale.category20c().range(), + shapes: [ + 'circle', + 'cross', + 'diamond', + 'square', + 'triangle-down', + 'triangle-up' + ] + }; + + module.exports = config; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],91:[function(require,module,exports){ + var dl = require('datalib'), + parse = require('../parse'), + Scale = require('../scene/Scale'), + config = require('./config'); + + function compile(module, opt, schema) { + var s = module.schema; + if (!s) return; + if (s.refs) dl.extend(schema.refs, s.refs); + if (s.defs) dl.extend(schema.defs, s.defs); + } + + module.exports = function(opt) { + var schema = null; + opt = opt || {}; + + // Compile if we're not loading the schema from a URL. + // Load from a URL to extend the existing base schema. + if (opt.url) { + schema = dl.json(dl.extend({url: opt.url}, config.load)); + } else { + schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Vega Visualization Specification Language", + "defs": {}, + "refs": {}, + "$ref": "#/defs/spec" + }; + + dl.keys(parse).forEach(function(k) { compile(parse[k], opt, schema); }); + + // Scales aren't in the parser, add schema manually + compile(Scale, opt, schema); + } + + // Extend schema to support custom mark properties or property sets. + if (opt.properties) dl.keys(opt.properties).forEach(function(k) { + schema.defs.propset.properties[k] = {"$ref": "#/refs/"+opt.properties[k]+"Value"}; + }); + + if (opt.propertySets) dl.keys(opt.propertySets).forEach(function(k) { + schema.defs.mark.properties.properties.properties[k] = {"$ref": "#/defs/propset"}; + }); + + return schema; + }; +},{"../parse":97,"../scene/Scale":113,"./config":90,"datalib":26}],92:[function(require,module,exports){ + var dl = require('datalib'), + axs = require('../scene/axis'); + + var ORIENT = { + "x": "bottom", + "y": "left", + "top": "top", + "bottom": "bottom", + "left": "left", + "right": "right" + }; + + function parseAxes(model, spec, axes, group) { + var config = model.config(); + (spec || []).forEach(function(def, index) { + axes[index] = axes[index] || axs(model); + parseAxis(config, def, index, axes[index], group); + }); + } + + function parseAxis(config, def, index, axis, group) { + // axis scale + if (def.scale !== undefined) { + axis.scale(group.scale(def.scale)); + } + + // axis orientation + axis.orient(def.orient || ORIENT[def.type]); + // axis offset + axis.offset(def.offset || 0); + // axis layer + axis.layer(def.layer || "front"); + // axis grid lines + axis.grid(def.grid || false); + // axis title + axis.title(def.title || null); + // axis title offset + axis.titleOffset(def.titleOffset != null ? + def.titleOffset : config.axis.titleOffset); + // axis values + axis.tickValues(def.values || null); + // axis label formatting + axis.tickFormat(def.format || null); + axis.tickFormatType(def.formatType || null); + // axis tick subdivision + axis.tickSubdivide(def.subdivide || 0); + // axis tick padding + axis.tickPadding(def.tickPadding || config.axis.padding); + + // axis tick size(s) + var size = []; + if (def.tickSize !== undefined) { + for (var i=0; i<3; ++i) size.push(def.tickSize); + } else { + var ts = config.axis.tickSize; + size = [ts, ts, ts]; + } + if (def.tickSizeMajor != null) size[0] = def.tickSizeMajor; + if (def.tickSizeMinor != null) size[1] = def.tickSizeMinor; + if (def.tickSizeEnd != null) size[2] = def.tickSizeEnd; + if (size.length) { + axis.tickSize.apply(axis, size); + } + + // axis tick count + axis.tickCount(def.ticks || config.axis.ticks); + + // style properties + var p = def.properties; + if (p && p.ticks) { + axis.majorTickProperties(p.majorTicks ? + dl.extend({}, p.ticks, p.majorTicks) : p.ticks); + axis.minorTickProperties(p.minorTicks ? + dl.extend({}, p.ticks, p.minorTicks) : p.ticks); + } else { + axis.majorTickProperties(p && p.majorTicks || {}); + axis.minorTickProperties(p && p.minorTicks || {}); + } + axis.tickLabelProperties(p && p.labels || {}); + axis.titleProperties(p && p.title || {}); + axis.gridLineProperties(p && p.grid || {}); + axis.domainProperties(p && p.axis || {}); + } + + module.exports = parseAxes; +},{"../scene/axis":115,"datalib":26}],93:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null); + + function parseBg(bg) { + // return null if input is null or undefined + if (bg == null) return null; + // run through d3 rgb to sanity check + return d3.rgb(bg) + ''; + } + + module.exports = parseBg; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],94:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + parseTransforms = require('./transforms'), + parseModify = require('./modify'); + + function parseData(model, spec, callback) { + var config = model.config(), + count = 0; + + function loaded(d) { + return function(error, data) { + if (error) { + log.error('LOADING FAILED: ' + d.url + ' ' + error); + } else { + model.data(d.name).values(dl.read(data, d.format)); + } + if (--count === 0) callback(); + }; + } + + // process each data set definition + (spec || []).forEach(function(d) { + if (d.url) { + count += 1; + dl.load(dl.extend({url: d.url}, config.load), loaded(d)); + } + parseData.datasource(model, d); + }); + + if (count === 0) setTimeout(callback, 1); + return spec; + } + + parseData.datasource = function(model, d) { + var transform = (d.transform || []).map(function(t) { + return parseTransforms(model, t); + }), + mod = (d.modify || []).map(function(m) { + return parseModify(model, m, d); + }), + ds = model.data(d.name, mod.concat(transform)); + + if (d.values) { + ds.values(dl.read(d.values, d.format)); + } else if (d.source) { + // Derived ds will be pulsed by its src rather than the model. + ds.source(d.source).addListener(ds); + model.removeListener(ds.pipeline()[0]); + } + + return ds; + }; + + module.exports = parseData; +},{"./modify":101,"./transforms":108,"datalib":26,"vega-logging":47}],95:[function(require,module,exports){ + module.exports = (function() { + /* + * Generated by PEG.js 0.8.0. + * + * http://pegjs.majda.cz/ + */ + + function peg$subclass(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + } + + function SyntaxError(message, expected, found, offset, line, column) { + this.message = message; + this.expected = expected; + this.found = found; + this.offset = offset; + this.line = line; + this.column = column; + + this.name = "SyntaxError"; + } + + peg$subclass(SyntaxError, Error); + + function parse(input) { + var options = arguments.length > 1 ? arguments[1] : {}, + + peg$FAILED = {}, + + peg$startRuleFunctions = { start: peg$parsestart }, + peg$startRuleFunction = peg$parsestart, + + peg$c0 = peg$FAILED, + peg$c1 = ",", + peg$c2 = { type: "literal", value: ",", description: "\",\"" }, + peg$c3 = function(o, m) { return [o].concat(m); }, + peg$c4 = function(o) { return [o]; }, + peg$c5 = "[", + peg$c6 = { type: "literal", value: "[", description: "\"[\"" }, + peg$c7 = "]", + peg$c8 = { type: "literal", value: "]", description: "\"]\"" }, + peg$c9 = ">", + peg$c10 = { type: "literal", value: ">", description: "\">\"" }, + peg$c11 = function(f1, f2, o) { return {start: f1, end: f2, middle: o}; }, + peg$c12 = [], + peg$c13 = function(s, f) { return (s.filters = f, s); }, + peg$c14 = function(s) { return s; }, + peg$c15 = "(", + peg$c16 = { type: "literal", value: "(", description: "\"(\"" }, + peg$c17 = ")", + peg$c18 = { type: "literal", value: ")", description: "\")\"" }, + peg$c19 = function(m) { return {stream: m}; }, + peg$c20 = "@", + peg$c21 = { type: "literal", value: "@", description: "\"@\"" }, + peg$c22 = ":", + peg$c23 = { type: "literal", value: ":", description: "\":\"" }, + peg$c24 = function(n, e) { return {event: e, name: n}; }, + peg$c25 = function(m, e) { return {event: e, mark: m}; }, + peg$c26 = function(t, e) { return {event: e, target: t}; }, + peg$c27 = function(e) { return {event: e}; }, + peg$c28 = function(s) { return {signal: s}; }, + peg$c29 = "rect", + peg$c30 = { type: "literal", value: "rect", description: "\"rect\"" }, + peg$c31 = "symbol", + peg$c32 = { type: "literal", value: "symbol", description: "\"symbol\"" }, + peg$c33 = "path", + peg$c34 = { type: "literal", value: "path", description: "\"path\"" }, + peg$c35 = "arc", + peg$c36 = { type: "literal", value: "arc", description: "\"arc\"" }, + peg$c37 = "area", + peg$c38 = { type: "literal", value: "area", description: "\"area\"" }, + peg$c39 = "line", + peg$c40 = { type: "literal", value: "line", description: "\"line\"" }, + peg$c41 = "rule", + peg$c42 = { type: "literal", value: "rule", description: "\"rule\"" }, + peg$c43 = "image", + peg$c44 = { type: "literal", value: "image", description: "\"image\"" }, + peg$c45 = "text", + peg$c46 = { type: "literal", value: "text", description: "\"text\"" }, + peg$c47 = "group", + peg$c48 = { type: "literal", value: "group", description: "\"group\"" }, + peg$c49 = "mousedown", + peg$c50 = { type: "literal", value: "mousedown", description: "\"mousedown\"" }, + peg$c51 = "mouseup", + peg$c52 = { type: "literal", value: "mouseup", description: "\"mouseup\"" }, + peg$c53 = "click", + peg$c54 = { type: "literal", value: "click", description: "\"click\"" }, + peg$c55 = "dblclick", + peg$c56 = { type: "literal", value: "dblclick", description: "\"dblclick\"" }, + peg$c57 = "wheel", + peg$c58 = { type: "literal", value: "wheel", description: "\"wheel\"" }, + peg$c59 = "keydown", + peg$c60 = { type: "literal", value: "keydown", description: "\"keydown\"" }, + peg$c61 = "keypress", + peg$c62 = { type: "literal", value: "keypress", description: "\"keypress\"" }, + peg$c63 = "keyup", + peg$c64 = { type: "literal", value: "keyup", description: "\"keyup\"" }, + peg$c65 = "mousewheel", + peg$c66 = { type: "literal", value: "mousewheel", description: "\"mousewheel\"" }, + peg$c67 = "mousemove", + peg$c68 = { type: "literal", value: "mousemove", description: "\"mousemove\"" }, + peg$c69 = "mouseout", + peg$c70 = { type: "literal", value: "mouseout", description: "\"mouseout\"" }, + peg$c71 = "mouseover", + peg$c72 = { type: "literal", value: "mouseover", description: "\"mouseover\"" }, + peg$c73 = "mouseenter", + peg$c74 = { type: "literal", value: "mouseenter", description: "\"mouseenter\"" }, + peg$c75 = "touchstart", + peg$c76 = { type: "literal", value: "touchstart", description: "\"touchstart\"" }, + peg$c77 = "touchmove", + peg$c78 = { type: "literal", value: "touchmove", description: "\"touchmove\"" }, + peg$c79 = "touchend", + peg$c80 = { type: "literal", value: "touchend", description: "\"touchend\"" }, + peg$c81 = function(e) { return e; }, + peg$c82 = /^[a-zA-Z0-9_\-]/, + peg$c83 = { type: "class", value: "[a-zA-Z0-9_\\-]", description: "[a-zA-Z0-9_\\-]" }, + peg$c84 = function(n) { return n.join(""); }, + peg$c85 = /^[a-zA-Z0-9\-_ #.>+~[\]=|\^$*]/, + peg$c86 = { type: "class", value: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]", description: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]" }, + peg$c87 = function(c) { return c.join(""); }, + peg$c88 = /^['"a-zA-Z0-9_().><=! \t-&|~]/, + peg$c89 = { type: "class", value: "['\"a-zA-Z0-9_().><=! \\t-&|~]", description: "['\"a-zA-Z0-9_().><=! \\t-&|~]" }, + peg$c90 = function(v) { return v.join(""); }, + peg$c91 = /^[ \t\r\n]/, + peg$c92 = { type: "class", value: "[ \\t\\r\\n]", description: "[ \\t\\r\\n]" }, + + peg$currPos = 0, + peg$reportedPos = 0, + peg$cachedPos = 0, + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$silentFails = 0, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$reportedPos, peg$currPos); + } + + function offset() { + return peg$reportedPos; + } + + function line() { + return peg$computePosDetails(peg$reportedPos).line; + } + + function column() { + return peg$computePosDetails(peg$reportedPos).column; + } + + function expected(description) { + throw peg$buildException( + null, + [{ type: "other", description: description }], + peg$reportedPos + ); + } + + function error(message) { + throw peg$buildException(message, null, peg$reportedPos); + } + + function peg$computePosDetails(pos) { + function advance(details, startPos, endPos) { + var p, ch; + + for (p = startPos; p < endPos; p++) { + ch = input.charAt(p); + if (ch === "\n") { + if (!details.seenCR) { details.line++; } + details.column = 1; + details.seenCR = false; + } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { + details.line++; + details.column = 1; + details.seenCR = true; + } else { + details.column++; + details.seenCR = false; + } + } + } + + if (peg$cachedPos !== pos) { + if (peg$cachedPos > pos) { + peg$cachedPos = 0; + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; + } + advance(peg$cachedPosDetails, peg$cachedPos, pos); + peg$cachedPos = pos; + } + + return peg$cachedPosDetails; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildException(message, expected, pos) { + function cleanupExpected(expected) { + var i = 1; + + expected.sort(function(a, b) { + if (a.description < b.description) { + return -1; + } else if (a.description > b.description) { + return 1; + } else { + return 0; + } + }); + + while (i < expected.length) { + if (expected[i - 1] === expected[i]) { + expected.splice(i, 1); + } else { + i++; + } + } + } + + function buildMessage(expected, found) { + function stringEscape(s) { + function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } + + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\x08/g, '\\b') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\f/g, '\\f') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) + .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) + .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); + } + + var expectedDescs = new Array(expected.length), + expectedDesc, foundDesc, i; + + for (i = 0; i < expected.length; i++) { + expectedDescs[i] = expected[i].description; + } + + expectedDesc = expected.length > 1 + ? expectedDescs.slice(0, -1).join(", ") + + " or " + + expectedDescs[expected.length - 1] + : expectedDescs[0]; + + foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; + + return "Expected " + expectedDesc + " but " + foundDesc + " found."; + } + + var posDetails = peg$computePosDetails(pos), + found = pos < input.length ? input.charAt(pos) : null; + + if (expected !== null) { + cleanupExpected(expected); + } + + return new SyntaxError( + message !== null ? message : buildMessage(expected, found), + expected, + found, + pos, + posDetails.line, + posDetails.column + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parsemerged(); + + return s0; + } + + function peg$parsemerged() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s3 = peg$c1; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + s5 = peg$parsemerged(); + if (s5 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c3(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c4(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parseordered() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + s3 = peg$parsefiltered(); + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c1; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parsesep(); + if (s6 !== peg$FAILED) { + s7 = peg$parsefiltered(); + if (s7 !== peg$FAILED) { + s8 = peg$parsesep(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c7; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parsesep(); + if (s10 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 62) { + s11 = peg$c9; + peg$currPos++; + } else { + s11 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c10); } + } + if (s11 !== peg$FAILED) { + s12 = peg$parsesep(); + if (s12 !== peg$FAILED) { + s13 = peg$parseordered(); + if (s13 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c11(s3, s7, s13); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$parsefiltered(); + } + + return s0; + } + + function peg$parsefiltered() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsefilter(); + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsefilter(); + } + } else { + s2 = peg$c0; + } + if (s2 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c14(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parsestream() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c15; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c16); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsemerged(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c19(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 64) { + s1 = peg$c20; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c21); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsename(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c22; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parseeventType(); + if (s4 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c24(s2, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsemarkType(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c25(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsecss(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c26(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseeventType(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c27(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsename(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c28(s1); + } + s0 = s1; + } + } + } + } + } + + return s0; + } + + function peg$parsemarkType() { + var s0; + + if (input.substr(peg$currPos, 4) === peg$c29) { + s0 = peg$c29; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c30); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c31) { + s0 = peg$c31; + peg$currPos += 6; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c32); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c33) { + s0 = peg$c33; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c34); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c35) { + s0 = peg$c35; + peg$currPos += 3; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c36); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c37) { + s0 = peg$c37; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c38); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c39) { + s0 = peg$c39; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c40); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c41) { + s0 = peg$c41; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c42); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c43) { + s0 = peg$c43; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c45) { + s0 = peg$c45; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c46); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c47) { + s0 = peg$c47; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c48); } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parseeventType() { + var s0; + + if (input.substr(peg$currPos, 9) === peg$c49) { + s0 = peg$c49; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c50); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c51) { + s0 = peg$c51; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c53) { + s0 = peg$c53; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c54); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c55) { + s0 = peg$c55; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c56); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c57) { + s0 = peg$c57; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c58); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c59) { + s0 = peg$c59; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c60); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c61) { + s0 = peg$c61; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c62); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c63) { + s0 = peg$c63; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c64); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c65) { + s0 = peg$c65; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c66); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c67) { + s0 = peg$c67; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c68); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c69) { + s0 = peg$c69; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c70); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c71) { + s0 = peg$c71; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c72); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c73) { + s0 = peg$c73; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c74); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c75) { + s0 = peg$c75; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c76); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c77) { + s0 = peg$c77; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c78); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c79) { + s0 = peg$c79; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c80); } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefilter() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseexpr(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s3 = peg$c7; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c81(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + + return s0; + } + + function peg$parsename() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c84(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsecss() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c87(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseexpr() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c90(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsesep() { + var s0, s1; + + s0 = []; + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail({ type: "end", description: "end of input" }); + } + + throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); + } + } + + return { + SyntaxError: SyntaxError, + parse: parse + }; + })(); +},{}],96:[function(require,module,exports){ + var expr = require('vega-expression'), + args = ['datum', 'event', 'signals']; + + module.exports = expr.compiler(args, { + idWhiteList: args, + fieldVar: args[0], + globalVar: args[2], + functions: function(codegen) { + var fn = expr.functions(codegen); + fn.eventItem = function() { return 'event.vg.item'; }; + fn.eventGroup = 'event.vg.getGroup'; + fn.eventX = 'event.vg.getX'; + fn.eventY = 'event.vg.getY'; + fn.open = 'window.open'; + return fn; + } + }); +},{"vega-expression":45}],97:[function(require,module,exports){ + module.exports = { + axes: require('./axes'), + background: require('./background'), + data: require('./data'), + events: require('./events'), + expr: require('./expr'), + legends: require('./legends'), + mark: require('./mark'), + marks: require('./marks'), + modify: require('./modify'), + padding: require('./padding'), + predicates: require('./predicates'), + properties: require('./properties'), + signals: require('./signals'), + spec: require('./spec'), + streams: require('./streams'), + transforms: require('./transforms') + }; +},{"./axes":92,"./background":93,"./data":94,"./events":95,"./expr":96,"./legends":98,"./mark":99,"./marks":100,"./modify":101,"./padding":102,"./predicates":103,"./properties":104,"./signals":105,"./spec":106,"./streams":107,"./transforms":108}],98:[function(require,module,exports){ + var lgnd = require('../scene/legend'); + + function parseLegends(model, spec, legends, group) { + (spec || []).forEach(function(def, index) { + legends[index] = legends[index] || lgnd(model); + parseLegend(def, index, legends[index], group); + }); + } + + function parseLegend(def, index, legend, group) { + // legend scales + legend.size (def.size ? group.scale(def.size) : null); + legend.shape (def.shape ? group.scale(def.shape) : null); + legend.fill (def.fill ? group.scale(def.fill) : null); + legend.stroke(def.stroke ? group.scale(def.stroke) : null); + + // legend orientation + if (def.orient) legend.orient(def.orient); + + // legend offset + if (def.offset != null) legend.offset(def.offset); + + // legend title + legend.title(def.title || null); + + // legend values + legend.values(def.values || null); + + // legend label formatting + legend.format(def.format !== undefined ? def.format : null); + + // style properties + var p = def.properties; + legend.titleProperties(p && p.title || {}); + legend.labelProperties(p && p.labels || {}); + legend.legendProperties(p && p.legend || {}); + legend.symbolProperties(p && p.symbols || {}); + legend.gradientProperties(p && p.gradient || {}); + } + + module.exports = parseLegends; +},{"../scene/legend":116}],99:[function(require,module,exports){ + var dl = require('datalib'), + parseProperties = require('./properties'); + + function parseMark(model, mark) { + var props = mark.properties, + group = mark.marks; + + // parse mark property definitions + dl.keys(props).forEach(function(k) { + props[k] = parseProperties(model, mark.type, props[k]); + }); + + // parse delay function + if (mark.delay) { + mark.delay = parseProperties(model, mark.type, {delay: mark.delay}); + } + + // recurse if group type + if (group) { + mark.marks = group.map(function(g) { return parseMark(model, g); }); + } + + return mark; + } + + module.exports = parseMark; +},{"./properties":104,"datalib":26}],100:[function(require,module,exports){ + var parseMark = require('./mark'), + parseProperties = require('./properties'); + + function parseRootMark(model, spec, width, height) { + return { + type: 'group', + width: width, + height: height, + properties: defaults(spec.scene || {}, model), + scales: spec.scales || [], + axes: spec.axes || [], + legends: spec.legends || [], + marks: (spec.marks || []).map(function(m) { return parseMark(model, m); }) + }; + } + + var PROPERTIES = [ + 'fill', 'fillOpacity', 'stroke', 'strokeOpacity', + 'strokeWidth', 'strokeDash', 'strokeDashOffset' + ]; + + function defaults(spec, model) { + var config = model.config().scene, + props = {}, i, n, m, p, s; + + for (i=0, n=m=PROPERTIES.length; i= 0; --i) { + if (src[i][field] == value) + dest.push.apply(dest, src.splice(i, 1)); + } + }; + + function parseModify(model, def, ds) { + var signal = def.signal ? dl.field(def.signal) : null, + signalName = signal ? signal[0] : null, + predicate = def.predicate ? model.predicate(def.predicate.name || def.predicate) : null, + reeval = (predicate === null), + isClear = def.type === Types.CLEAR, + node = new Node(model).router(isClear); + + node.evaluate = function(input) { + if (predicate !== null) { // TODO: predicate args + var db = model.values(Deps.DATA, predicate.data || EMPTY), + sg = model.values(Deps.SIGNALS, predicate.signals || EMPTY); + reeval = predicate.call(predicate, {}, db, sg, model._predicates); + } + + log.debug(input, [def.type+"ing", reeval]); + if (!reeval || (!isClear && !input.signals[signalName])) return input; + + var datum = {}, + value = signal ? model.signalRef(def.signal) : null, + d = model.data(ds.name), + t = null; + + datum[def.field] = value; + + // We have to modify ds._data so that subsequent pulses contain + // our dynamic data. W/o modifying ds._data, only the output + // collector will contain dynamic tuples. + if (def.type === Types.INSERT) { + t = Tuple.ingest(datum); + input.add.push(t); + d._data.push(t); + } else if (def.type === Types.REMOVE) { + filter(def.field, value, input.add, input.rem); + filter(def.field, value, input.mod, input.rem); + d._data = d._data.filter(function(x) { return x[def.field] !== value; }); + } else if (def.type === Types.TOGGLE) { + var add = [], rem = []; + filter(def.field, value, input.rem, add); + filter(def.field, value, input.add, rem); + filter(def.field, value, input.mod, rem); + if (!(add.length || rem.length)) add.push(Tuple.ingest(datum)); + + input.add.push.apply(input.add, add); + d._data.push.apply(d._data, add); + input.rem.push.apply(input.rem, rem); + d._data = d._data.filter(function(x) { return rem.indexOf(x) === -1; }); + } else if (def.type === Types.CLEAR) { + input.rem.push.apply(input.rem, input.add); + input.rem.push.apply(input.rem, input.mod); + input.add = []; + input.mod = []; + d._data = []; + } + + input.fields[def.field] = 1; + return input; + }; + + if (signalName) node.dependency(Deps.SIGNALS, signalName); + + if (predicate) { + node.dependency(Deps.DATA, predicate.data); + node.dependency(Deps.SIGNALS, predicate.signals); + } + + return node; + } + + module.exports = parseModify; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],102:[function(require,module,exports){ + var dl = require('datalib'); + + function parsePadding(pad) { + return pad == null ? 'auto' : + dl.isObject(pad) ? pad : + dl.isNumber(pad) ? {top:pad, left:pad, right:pad, bottom:pad} : + pad === 'strict' ? pad : 'auto'; + } + + module.exports = parsePadding; +},{"datalib":26}],103:[function(require,module,exports){ + var dl = require('datalib'); + + var types = { + '=': parseComparator, + '==': parseComparator, + '!=': parseComparator, + '>': parseComparator, + '>=': parseComparator, + '<': parseComparator, + '<=': parseComparator, + 'and': parseLogical, + '&&': parseLogical, + 'or': parseLogical, + '||': parseLogical, + 'in': parseIn + }; + + var nullScale = function() { return 0; }; + nullScale.invert = nullScale; + + function parsePredicates(model, spec) { + (spec || []).forEach(function(s) { + var parse = types[s.type](model, s); + + /* jshint evil:true */ + var pred = Function("args", "db", "signals", "predicates", parse.code); + pred.root = function() { return model.scene().items[0]; }; // For global scales + pred.nullScale = nullScale; + pred.isFunction = dl.isFunction; + pred.signals = parse.signals; + pred.data = parse.data; + + model.predicate(s.name, pred); + }); + + return spec; + } + + function parseSignal(signal, signals) { + var s = dl.field(signal), + code = "signals["+s.map(dl.str).join("][")+"]"; + signals[s[0]] = 1; + return code; + } + + function parseOperands(model, operands) { + var decl = [], defs = [], + signals = {}, db = {}; + + function setSignal(s) { signals[s] = 1; } + function setData(d) { db[d] = 1; } + + dl.array(operands).forEach(function(o, i) { + var name = "o" + i, + def = ""; + + if (o.value !== undefined) { + def = dl.str(o.value); + } else if (o.arg) { + def = "args["+dl.str(o.arg)+"]"; + } else if (o.signal) { + def = parseSignal(o.signal, signals); + } else if (o.predicate) { + var ref = o.predicate, + predName = ref && (ref.name || ref), + pred = model.predicate(predName), + p = "predicates["+dl.str(predName)+"]"; + + pred.signals.forEach(setSignal); + pred.data.forEach(setData); + + if (dl.isObject(ref)) { + dl.keys(ref).forEach(function(k) { + if (k === "name") return; + var i = ref[k]; + def += "args["+dl.str(k)+"] = "; + if (i.signal) { + def += parseSignal(i.signal, signals); + } else if (i.arg) { + def += "args["+dl.str(i.arg)+"]"; + } + def += ", "; + }); + } + + def += p+".call("+p+", args, db, signals, predicates)"; + } + + decl.push(name); + defs.push(name+"=("+def+")"); + }); + + return { + code: "var " + decl.join(", ") + ";\n" + defs.join(";\n") + ";\n", + signals: dl.keys(signals), + data: dl.keys(db) + }; + } + + function parseComparator(model, spec) { + var ops = parseOperands(model, spec.operands); + if (spec.type === '=') spec.type = '=='; + + ops.code += "o0 = o0 instanceof Date ? o0.getTime() : o0;\n" + + "o1 = o1 instanceof Date ? o1.getTime() : o1;\n"; + + return { + code: ops.code + "return " + ["o0", "o1"].join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseLogical(model, spec) { + var ops = parseOperands(model, spec.operands), + o = [], i = 0, len = spec.operands.length; + + while (o.push("o"+i++) < len); + if (spec.type === 'and') spec.type = '&&'; + else if (spec.type === 'or') spec.type = '||'; + + return { + code: ops.code + "return " + o.join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseIn(model, spec) { + var o = [spec.item], code = ""; + if (spec.range) o.push.apply(o, spec.range); + if (spec.scale) { + code = parseScale(spec.scale, o); + } + + var ops = parseOperands(model, o); + code = ops.code + code + "\n var ordSet = null;\n"; + + if (spec.data) { + var field = dl.field(spec.field).map(dl.str); + code += "var where = function(d) { return d["+field.join("][")+"] == o0 };\n"; + code += "return db["+dl.str(spec.data)+"].filter(where).length > 0;"; + } else if (spec.range) { + // TODO: inclusive/exclusive range? + if (spec.scale) { + code += "if (scale.length == 2) {\n" + // inverting ordinal scales + " ordSet = scale(o1, o2);\n" + + "} else {\n" + + " o1 = scale(o1);\no2 = scale(o2);\n" + + "}"; + } + + code += "return ordSet !== null ? ordSet.indexOf(o0) !== -1 :\n" + + " o1 < o2 ? o1 <= o0 && o0 <= o2 : o2 <= o0 && o0 <= o1;"; + } + + return { + code: code, + signals: ops.signals, + data: ops.data.concat(spec.data ? [spec.data] : []) + }; + } + +// Populate ops such that ultimate scale/inversion function will be in `scale` var. + function parseScale(spec, ops) { + var code = "var scale = ", + idx = ops.length; + + if (dl.isString(spec)) { + ops.push({ value: spec }); + code += "this.root().scale(o"+idx+")"; + } else if (spec.arg) { // Scale function is being passed as an arg + ops.push(spec); + code += "o"+idx; + } else if (spec.name) { // Full scale parameter {name: ..} + ops.push(dl.isString(spec.name) ? {value: spec.name} : spec.name); + code += "(this.isFunction(o"+idx+") ? o"+idx+" : "; + if (spec.scope) { + ops.push(spec.scope); + code += "((o"+(idx+1)+".scale || this.root().scale)(o"+idx+") || this.nullScale)"; + } else { + code += "this.root().scale(o"+idx+")"; + } + code += ")"; + } + + if (spec.invert === true) { // Allow spec.invert.arg? + code += ".invert"; + } + + return code+";\n"; + } + + module.exports = parsePredicates; +},{"datalib":26}],104:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple; + + var DEPS = ["signals", "scales", "data", "fields"]; + + function properties(model, mark, spec) { + var config = model.config(), + code = "", + names = dl.keys(spec), + i, len, name, ref, vars = {}, + deps = { + signals: {}, + scales: {}, + data: {}, + fields: {}, + nested: [], + _nRefs: {}, // Temp stash to de-dupe nested refs. + reflow: false + }; + + code += "var o = trans ? {} : item, d=0, set=this.tpl.set, tmpl=signals||{}, t;\n" + + // Stash for dl.template + "tmpl.datum = item.datum;\n" + + "tmpl.group = group;\n" + + "tmpl.parent = group.datum;\n"; + + function handleDep(p) { + if (ref[p] == null) return; + var k = dl.array(ref[p]), i, n; + for (i=0, n=k.length; i 0) ? "\n " : " "; + if (ref.rule) { + ref = rule(model, name, ref.rule); + code += "\n " + ref.code; + } else if (dl.isArray(ref)) { + ref = rule(model, name, ref); + code += "\n " + ref.code; + } else { + ref = valueRef(config, name, ref); + code += "d += set(o, "+dl.str(name)+", "+ref.val+");"; + } + + vars[name] = true; + DEPS.forEach(handleDep); + deps.reflow = deps.reflow || ref.reflow; + if (ref.nested.length) ref.nested.forEach(handleNestedRefs); + } + + // If nested references are present, sort them based on their level + // to speed up determination of whether encoders should be reeval'd. + dl.keys(deps._nRefs).forEach(function(k) { deps.nested.push(deps._nRefs[k]); }); + deps.nested.sort(function(a, b) { + a = a.level; + b = b.level; + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + }); + + if (vars.x2) { + if (vars.x) { + code += "\n if (o.x > o.x2) { " + + "\n t = o.x;" + + "\n d += set(o, 'x', o.x2);" + + "\n d += set(o, 'x2', t); " + + "\n };"; + code += "\n d += set(o, 'width', (o.x2 - o.x));"; + } else if (vars.width) { + code += "\n d += set(o, 'x', (o.x2 - o.width));"; + } else { + code += "\n d += set(o, 'x', o.x2);"; + } + } + + if (vars.xc) { + if (vars.width) { + code += "\n d += set(o, 'x', (o.xc - o.width/2));" ; + } else { + code += "\n d += set(o, 'x', o.xc);" ; + } + } + + if (vars.y2) { + if (vars.y) { + code += "\n if (o.y > o.y2) { " + + "\n t = o.y;" + + "\n d += set(o, 'y', o.y2);" + + "\n d += set(o, 'y2', t);" + + "\n };"; + code += "\n d += set(o, 'height', (o.y2 - o.y));"; + } else if (vars.height) { + code += "\n d += set(o, 'y', (o.y2 - o.height));"; + } else { + code += "\n d += set(o, 'y', o.y2);"; + } + } + + if (vars.yc) { + if (vars.height) { + code += "\n d += set(o, 'y', (o.yc - o.height/2));" ; + } else { + code += "\n d += set(o, 'y', o.yc);" ; + } + } + + if (hasPath(mark, vars)) code += "\n d += (item.touch(), 1);"; + code += "\n if (trans) trans.interpolate(item, o);"; + code += "\n return d > 0;"; + + try { + /* jshint evil:true */ + var encoder = Function('item', 'group', 'trans', 'db', + 'signals', 'predicates', code); + encoder.tpl = Tuple; + encoder.util = dl; + encoder.d3 = d3; // For color spaces + dl.extend(encoder, dl.template.context); + return { + encode: encoder, + signals: dl.keys(deps.signals), + scales: dl.keys(deps.scales), + data: dl.keys(deps.data), + fields: dl.keys(deps.fields), + nested: deps.nested, + reflow: deps.reflow + }; + } catch (e) { + log.error(e); + log.log(code); + } + } + + function dependencies(a, b) { + if (!dl.isObject(a)) { + a = {reflow: false, nested: []}; + DEPS.forEach(function(d) { a[d] = []; }); + } + + if (dl.isObject(b)) { + a.reflow = a.reflow || b.reflow; + a.nested.push.apply(a.nested, b.nested); + DEPS.forEach(function(d) { a[d].push.apply(a[d], b[d]); }); + } + + return a; + } + + function hasPath(mark, vars) { + return vars.path || + ((mark==='area' || mark==='line') && + (vars.x || vars.x2 || vars.width || + vars.y || vars.y2 || vars.height || + vars.tension || vars.interpolate)); + } + + function rule(model, name, rules) { + var config = model.config(), + deps = dependencies(), + inputs = [], code = ''; + + (rules||[]).forEach(function(r, i) { + var def = r.predicate, + predName = def && (def.name || def), + pred = model.predicate(predName), + p = 'predicates['+dl.str(predName)+']', + input = [], args = name+'_arg'+i, + ref; + + if (dl.isObject(def)) { + dl.keys(def).forEach(function(k) { + if (k === 'name') return; + var ref = valueRef(config, i, def[k]); + input.push(dl.str(k)+': '+ref.val); + dependencies(deps, ref); + }); + } + + ref = valueRef(config, name, r); + dependencies(deps, ref); + + if (predName) { + deps.signals.push.apply(deps.signals, pred.signals); + deps.data.push.apply(deps.data, pred.data); + inputs.push(args+" = {\n "+input.join(",\n ")+"\n }"); + code += "if ("+p+".call("+p+","+args+", db, signals, predicates)) {" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"; + code += rules[i+1] ? "\n } else " : " }"; + } else { + code += "{" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"+ + "\n }\n"; + } + }); + + code = "var " + inputs.join(",\n ") + ";\n " + code; + return (deps.code = code, deps); + } + + function valueRef(config, name, ref) { + if (ref == null) return null; + + if (name==='fill' || name==='stroke') { + if (ref.c) { + return colorRef(config, 'hcl', ref.h, ref.c, ref.l); + } else if (ref.h || ref.s) { + return colorRef(config, 'hsl', ref.h, ref.s, ref.l); + } else if (ref.l || ref.a) { + return colorRef(config, 'lab', ref.l, ref.a, ref.b); + } else if (ref.r || ref.g || ref.b) { + return colorRef(config, 'rgb', ref.r, ref.g, ref.b); + } + } + + // initialize value + var val = null, scale = null, + deps = dependencies(), + sgRef = null, fRef = null, sRef = null, tmpl = {}; + + if (ref.template !== undefined) { + val = dl.template.source(ref.template, 'tmpl', tmpl); + dl.keys(tmpl).forEach(function(k) { + var f = dl.field(k), + a = f.shift(); + if (a === 'parent' || a === 'group') { + deps.nested.push({ + parent: a === 'parent', + group: a === 'group', + level: 1 + }); + } else if (a === 'datum') { + deps.fields.push(f[0]); + } else { + deps.signals.push(a); + } + }); + } + + if (ref.value !== undefined) { + val = dl.str(ref.value); + } + + if (ref.signal !== undefined) { + sgRef = dl.field(ref.signal); + val = 'signals['+sgRef.map(dl.str).join('][')+']'; + deps.signals.push(sgRef.shift()); + } + + if (ref.field !== undefined) { + ref.field = dl.isString(ref.field) ? {datum: ref.field} : ref.field; + fRef = fieldRef(ref.field); + val = fRef.val; + dependencies(deps, fRef); + } + + if (ref.scale !== undefined) { + sRef = scaleRef(ref.scale); + scale = sRef.val; + dependencies(deps, sRef); + deps.scales.push(ref.scale.name || ref.scale); + + // run through scale function if val specified. + // if no val, scale function is predicate arg. + if (val !== null || ref.band || ref.mult || ref.offset) { + val = scale + (ref.band ? '.rangeBand()' : + '('+(val !== null ? val : 'item.datum.data')+')'); + } else { + val = scale; + } + } + + // multiply, offset, return value + val = '(' + (ref.mult?(dl.number(ref.mult)+' * '):'') + val + ')' + + (ref.offset ? ' + ' + dl.number(ref.offset) : ''); + + // Collate dependencies + return (deps.val = val, deps); + } + + function colorRef(config, type, x, y, z) { + var xx = x ? valueRef(config, '', x) : config.color[type][0], + yy = y ? valueRef(config, '', y) : config.color[type][1], + zz = z ? valueRef(config, '', z) : config.color[type][2], + deps = dependencies(); + + [xx, yy, zz].forEach(function(v) { + if (dl.isArray) return; + dependencies(deps, v); + }); + + var val = '(this.d3.' + type + '(' + [xx.val, yy.val, zz.val].join(',') + ') + "")'; + return (deps.val = val, deps); + } + +// {field: {datum: "foo"} } -> item.datum.foo +// {field: {group: "foo"} } -> group.foo +// {field: {parent: "foo"} } -> group.datum.foo + function fieldRef(ref) { + if (dl.isString(ref)) { + return {val: dl.field(ref).map(dl.str).join('][')}; + } + + // Resolve nesting/parent lookups + var l = ref.level || 1, + nested = (ref.group || ref.parent) && l, + scope = nested ? Array(l).join('group.mark.') : '', + r = fieldRef(ref.datum || ref.group || ref.parent || ref.signal), + val = r.val, + deps = dependencies(null, r); + + if (ref.datum) { + val = 'item.datum['+val+']'; + deps.fields.push(ref.datum); + } else if (ref.group) { + val = scope+'group['+val+']'; + deps.nested.push({ level: l, group: true }); + } else if (ref.parent) { + val = scope+'group.datum['+val+']'; + deps.nested.push({ level: l, parent: true }); + } else if (ref.signal) { + val = 'signals['+val+']'; + deps.signals.push(dl.field(ref.signal)[0]); + deps.reflow = true; + } + + return (deps.val = val, deps); + } + +// {scale: "x"} +// {scale: {name: "x"}}, +// {scale: fieldRef} + function scaleRef(ref) { + var scale = null, + fr = null, + deps = dependencies(); + + if (dl.isString(ref)) { + scale = dl.str(ref); + } else if (ref.name) { + scale = dl.isString(ref.name) ? dl.str(ref.name) : (fr = fieldRef(ref.name)).val; + } else { + scale = (fr = fieldRef(ref)).val; + } + + scale = '(item.mark._scaleRefs['+scale+'] = 1, group.scale('+scale+'))'; + if (ref.invert) scale += '.invert'; + + // Mark scale refs as they're dealt with separately in mark._scaleRefs. + if (fr) fr.nested.forEach(function(g) { g.scale = true; }); + return fr ? (fr.val = scale, fr) : (deps.val = scale, deps); + } + + module.exports = properties; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],105:[function(require,module,exports){ + var dl = require('datalib'), + SIGNALS = require('vega-dataflow').Dependencies.SIGNALS, + expr = require('./expr'); + + var RESERVED = ['datum', 'event', 'signals', 'width', 'height', 'padding'] + .concat(dl.keys(expr.codegen.functions)); + + function parseSignals(model, spec) { + // process each signal definition + (spec || []).forEach(function(s) { + if (RESERVED.indexOf(s.name) !== -1) { + throw Error('Signal name "'+s.name+'" is a '+ + 'reserved keyword ('+RESERVED.join(', ')+').'); + } + + var signal = model.signal(s.name, s.init) + .verbose(s.verbose); + + if (s.init && s.init.expr) { + s.init.expr = expr(s.init.expr); + signal.value(exprVal(model, s.init)); + } + + if (s.expr) { + s.expr = expr(s.expr); + signal.evaluate = function(input) { + var val = exprVal(model, s), + sg = input.signals; + if (val !== signal.value() || signal.verbose()) { + signal.value(val); + sg[s.name] = 1; + } + return sg[s.name] ? input : model.doNotPropagate; + }; + signal.dependency(SIGNALS, s.expr.globals); + s.expr.globals.forEach(function(dep) { + model.signal(dep).addListener(signal); + }); + } + }); + + return spec; + } + + function exprVal(model, spec) { + var e = spec.expr, + val = e.fn(null, null, model.values(SIGNALS, e.globals)); + return spec.scale ? parseSignals.scale(model, spec, val) : val; + } + + parseSignals.scale = function scale(model, spec, value, datum, evt) { + var def = spec.scale, + name = def.name || def.signal || def, + scope = def.scope, e; + + if (scope) { + if (scope.signal) { + scope = model.signalRef(scope.signal); + } else if (dl.isString(scope)) { // Scope is an expression + e = def._expr = (def._expr || expr(scope)); + scope = e.fn(datum, evt, model.values(SIGNALS, e.globals)); + } + } + + if (!scope || !scope.scale) { + scope = (scope && scope.mark) ? scope.mark.group : model.scene().items[0]; + } + + var s = scope.scale(name); + return !s ? value : (def.invert ? s.invert(value) : s(value)); + }; + + module.exports = parseSignals; +},{"./expr":96,"datalib":26,"vega-dataflow":41}],106:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Model = require('../core/Model'), + View = require('../core/View'); + + function parseSpec(spec, callback) { + var vf = arguments[arguments.length-1], + viewFactory = arguments.length > 2 && dl.isFunction(vf) ? vf : View.factory, + config = arguments[2] !== viewFactory ? arguments[2] : {}, + model = new Model(config); + + function parse(spec) { + // protect against subsequent spec modification + spec = dl.duplicate(spec); + + var parsers = require('./'), + create = function() { callback(viewFactory(model)); }, + width = spec.width || 500, + height = spec.height || 500, + padding = parsers.padding(spec.padding); + + // create signals for width, height and padding + model.signal('width', width); + model.signal('height', height); + model.signal('padding', padding); + + // initialize model + model.defs({ + width: width, + height: height, + padding: padding, + viewport: spec.viewport || null, + background: parsers.background(spec.background), + signals: parsers.signals(model, spec.signals), + predicates: parsers.predicates(model, spec.predicates), + marks: parsers.marks(model, spec, width, height), + data: parsers.data(model, spec.data, create) + }); + } + + if (dl.isObject(spec)) { + parse(spec); + } else if (dl.isString(spec)) { + var opts = dl.extend({url: spec}, model.config().load); + dl.load(opts, function(err, data) { + if (err) { + log.error('LOADING SPECIFICATION FAILED: ' + err.statusText); + } else { + try { + parse(JSON.parse(data)); + } catch (e) { + log.error('INVALID SPECIFICATION: Must be a valid JSON object. '+e); + } + } + }); + } else { + log.error('INVALID SPECIFICATION: Must be a valid JSON object or URL.'); + } + } + + module.exports = parseSpec; +},{"../core/Model":88,"../core/View":89,"./":97,"datalib":26,"vega-logging":47}],107:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + parseSignals = require('./signals'), + selector = require('./events'), + expr = require('./expr'); + + var GATEKEEPER = '_vgGATEKEEPER'; + + var vgEvent = { + getGroup: function(name) { return name ? this.name[name] : this.group; }, + getXY: function(item) { + var p = {x: this.x, y: this.y}; + if (typeof item === 'string') { + item = this.name[item]; + } + for (; item; item = item.mark && item.mark.group) { + p.x -= item.x || 0; + p.y -= item.y || 0; + } + return p; + }, + getX: function(item) { return this.getXY(item).x; }, + getY: function(item) { return this.getXY(item).y; } + }; + + function parseStreams(view) { + var model = view.model(), + spec = model.defs().signals, + registry = {handlers: {}, nodes: {}}, + internal = dl.duplicate(registry), // Internal event processing + external = dl.duplicate(registry); // External event processing + + (spec || []).forEach(function(sig) { + var signal = model.signal(sig.name); + if (sig.expr) return; // Cannot have an expr and stream definition. + + (sig.streams || []).forEach(function(stream) { + var sel = selector.parse(stream.type), + exp = expr(stream.expr); + mergedStream(signal, sel, exp, stream); + }); + }); + + // We register the event listeners all together so that if multiple + // signals are registered on the same event, they will receive the + // new value on the same pulse. + dl.keys(internal.handlers).forEach(function(type) { + view.on(type, function(evt, item) { + evt.preventDefault(); // stop text selection + extendEvent(evt, item); + fire(internal, type, (item && item.datum) || {}, evt); + }); + }); + + // add external event listeners + dl.keys(external.handlers).forEach(function(type) { + if (typeof window === 'undefined') return; // No external support + + var h = external.handlers[type], + t = type.split(':'), // --> no element pseudo-selectors + elt = (t[0] === 'window') ? [window] : + window.document.querySelectorAll(t[0]); + + function handler(evt) { + extendEvent(evt); + fire(external, type, d3.select(this).datum(), evt); + } + + for (var i=0; i 0, + i, ilen, j, jlen, group, legend; + + if (input.add.length || input.rem.length || !items.length || + input.mod.length === items.length || + type === 'area' || type === 'line') { + bound.mark(this._mark, null, isGrp && !hasLegends); + } else { + input.mod.forEach(function(item) { bound.item(item); }); + } + + if (isGrp && hasLegends) { + for (i=0, ilen=items.length; i this._stamp) { + join.call(this, fcs, output, this._ds.values(), true, fullUpdate); + } else if (fullUpdate) { + output.mod = this._mark.items.slice(); + } + } else { + data = dl.isFunction(this._def.from) ? this._def.from() : [Sentinel]; + join.call(this, input, output, data); + } + + // Stash output before Bounder for downstream reactive geometry. + this._output = output = this._graph.evaluate(output, this._encoder); + + // Add any new scale references to the dependency list, and ensure + // they're connected. + if (update.nested && update.nested.length && this._status === CONNECTED) { + dl.keys(this._mark._scaleRefs).forEach(function(s) { + var scale = self._parent.scale(s); + if (!scale) return; + + scale.addListener(self); + self.dependency(Deps.SCALES, s); + self._encoder.dependency(Deps.SCALES, s); + }); + } + + // Supernodes calculate bounds too, but only on items marked dirty. + if (this._isSuper) { + output.mod = output.mod.filter(function(x) { return x._dirty; }); + output = this._graph.evaluate(output, this._bounder); + } + + return output; + }; + + function newItem() { + var item = Tuple.ingest(new Item(this._mark)); + + // For the root node's item + if (this._def.width) Tuple.set(item, 'width', this._def.width); + if (this._def.height) Tuple.set(item, 'height', this._def.height); + return item; + } + + function join(input, output, data, ds, fullUpdate) { + var keyf = keyFunction(this._def.key || (ds ? '_id' : null)), + prev = this._mark.items || [], + rem = ds ? input.rem : prev, + mod = Tuple.idMap((!ds || fullUpdate) ? data : input.mod), + next = [], + i, key, len, item, datum, enter, diff; + + // Only mark rems as exiting. Due to keyf, there may be an add/mod + // tuple that replaces it. + for (i=0, len=rem.length; i0) s += '|'; + s += String(f[i](d)); + } + return s; + }; + } + + module.exports = Builder; +},{"../parse/data":94,"./Bounder":109,"./Encoder":111,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],111:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + df = require('vega-dataflow'), + Node = df.Node, // jshint ignore:line + Deps = df.Dependencies, + bound = require('vega-scenegraph').bound; + + var EMPTY = {}; + + function Encoder(graph, mark, builder) { + var props = mark.def.properties || {}, + enter = props.enter, + update = props.update, + exit = props.exit; + + Node.prototype.init.call(this, graph); + + this._mark = mark; + this._builder = builder; + var s = this._scales = []; + + // Only scales used in the 'update' property set are set as + // encoder depedencies to have targeted reevaluations. However, + // we still want scales in 'enter' and 'exit' to be evaluated + // before the encoder. + if (enter) s.push.apply(s, enter.scales); + + if (update) { + this.dependency(Deps.DATA, update.data); + this.dependency(Deps.SIGNALS, update.signals); + this.dependency(Deps.FIELDS, update.fields); + this.dependency(Deps.SCALES, update.scales); + s.push.apply(s, update.scales); + } + + if (exit) s.push.apply(s, exit.scales); + + return this.mutates(true); + } + + var proto = (Encoder.prototype = new Node()); + + proto.evaluate = function(input) { + log.debug(input, ['encoding', this._mark.def.type]); + var graph = this._graph, + props = this._mark.def.properties || {}, + items = this._mark.items, + enter = props.enter, + update = props.update, + exit = props.exit, + dirty = input.dirty, + preds = graph.predicates(), + req = input.request, + group = this._mark.group, + guide = group && (group.mark.axis || group.mark.legend), + db = EMPTY, sg = EMPTY, i, len, item, prop; + + if (req && !guide) { + if ((prop = props[req]) && input.mod.length) { + db = prop.data ? graph.values(Deps.DATA, prop.data) : null; + sg = prop.signals ? graph.values(Deps.SIGNALS, prop.signals) : null; + + for (i=0, len=input.mod.length; i this._stamp) return true; + } + + return false; + } + +// Short-circuit encoder if user specifies items + Encoder.update = function(graph, trans, request, items, dirty) { + items = dl.array(items); + var preds = graph.predicates(), + db = graph.values(Deps.DATA), + sg = graph.values(Deps.SIGNALS), + i, len, item, props, prop; + + for (i=0, len=items.length; i 0, + hasAxes = dl.array(this._def.axes).length > 0, + hasLegends = dl.array(this._def.legends).length > 0, + i, j, c, len, group, pipeline, def, inline = false; + + for (i=0, len=input.add.length; i=0; --i) { + group = input.add[i]; + for (j=this._children[group._id].length-1; j>=0; --j) { + c = this._children[group._id][j]; + c.builder.connect(); + pipeline = c.builder.pipeline(); + def = c.builder._def; + + // This new child needs to be built during this propagation cycle. + // We could add its builder as a listener off the _recursor node, + // but try to inline it if we can to minimize graph dispatches. + inline = (def.type !== Types.GROUP); + inline = inline && (this._graph.data(c.from) !== undefined); + inline = inline && (pipeline[pipeline.length-1].listeners().length === 1); // Reactive geom source + inline = inline && (def.from && !def.from.mark); // Reactive geom target + c.inline = inline; + + if (inline) this._graph.evaluate(input, c.builder); + else this._recursor.addListener(c.builder); + } + } + + function removeTemp(c) { + if (c.type == Types.MARK && !c.inline && + builder._graph.data(c.from) !== undefined) { + builder._recursor.removeListener(c.builder); + } + } + + function updateAxis(a) { + var scale = a.scale(); + if (!input.scales[scale.scaleName]) return; + a.reset().def(); + } + + function updateLegend(l) { + var scale = l.size() || l.shape() || l.fill() || l.stroke(); + if (!input.scales[scale.scaleName]) return; + l.reset().def(); + } + + for (i=0, len=input.mod.length; i rng[1]) { + start = rng[1] || 0; + rng = [start + (bw * len + space), start]; + } else { + start = rng[0] || 0; + rng = [start, start + (bw * len + space)]; + } + } + + str = typeof rng[0] === 'string'; + if (str || rng.length > 2 || rng.length===1 || dataDrivenRange) { + scale.range(rng); // color or shape values + spatial = false; + } else if (points && round) { + scale.rangeRoundPoints(rng, pad); + } else if (points) { + scale.rangePoints(rng, pad); + } else if (round) { + scale.rangeRoundBands(rng, pad, outer); + } else { + scale.rangeBands(rng, pad, outer); + } + + prev.range = rng; + this._updated = true; + } + + if (!scale.invert && spatial) invertOrdinal(scale); + } + +// "Polyfill" ordinal scale inversion. Currently, only ordinal scales +// with ordered numeric ranges are supported. + var bisect = d3.bisector(dl.numcmp).right, + findAsc = function(a, x) { return bisect(a,x) - 1; }, + findDsc = d3.bisector(function(a,b) { return -1 * dl.numcmp(a,b); }).left; + + function invertOrdinal(scale) { + scale.invert = function(x, y) { + var rng = scale.range(), + asc = rng[0] < rng[1], + find = asc ? findAsc : findDsc; + + if (arguments.length === 1) { + if (!dl.isNumber(x)) { + throw Error('Ordinal scale inversion is only supported for numeric input ('+x+').'); + } + return scale.domain()[find(rng, x)]; + + } else if (arguments.length === 2) { // Invert extents + if (!dl.isNumber(x) || !dl.isNumber(y)) { + throw Error('Extents to ordinal invert are not numbers ('+x+', '+y+').'); + } + + var domain = scale.domain(), + a = find(rng, x), + b = find(rng, y), + n = rng.length - 1, r; + if (b < a) { r = a; a = b; b = a; } // ensure a <= b + if (a < 0) a = 0; + if (b > n) b = n; + + return (asc ? dl.range(a, b+1) : dl.range(b, a-1, -1)) + .map(function(i) { return domain[i]; }); + } + }; + } + + function quantitative(scale, rng, group) { + var def = this._def, + prev = scale._prev, + round = signal.call(this, def.round), + exponent = signal.call(this, def.exponent), + clamp = signal.call(this, def.clamp), + nice = signal.call(this, def.nice), + domain, interval; + + // domain + domain = (def.type === Types.QUANTILE) ? + dataRef.call(this, DataRef.DOMAIN, def.domain, scale, group) : + domainMinMax.call(this, scale, group); + if (domain && !dl.equal(prev.domain, domain)) { + scale.domain(domain); + prev.domain = domain; + this._updated = true; + } + + // range + // vertical scales should flip by default, so use XOR here + if (signal.call(this, def.range) === 'height') rng = rng.reverse(); + if (dl.equal(prev.range, rng)) return; + scale[round && scale.rangeRound ? 'rangeRound' : 'range'](rng); + prev.range = rng; + this._updated = true; + + // TODO: Support signals for these properties. Until then, only eval + // them once. + if (this._stamp > 0) return; + if (exponent && def.type===Types.POWER) scale.exponent(exponent); + if (clamp) scale.clamp(true); + if (nice) { + if (def.type === Types.TIME) { + interval = d3.time[nice]; + if (!interval) log.error('Unrecognized interval: ' + interval); + scale.nice(interval); + } else { + scale.nice(); + } + } + } + + function isUniques(scale) { + return scale.type === Types.ORDINAL || scale.type === Types.QUANTILE; + } + + function getRefs(def) { + return def.fields || dl.array(def); + } + + function inherits(refs) { + return refs.some(function(r) { + if (!r.data) return true; + return r.data && dl.array(r.field).some(function(f) { + return f.parent; + }); + }); + } + + function getFields(ref, group) { + return dl.array(ref.field).map(function(f) { + return f.parent ? + dl.accessor(f.parent)(group.datum) : + f; // String or {'signal'} + }); + } + +// Scale datarefs can be computed over multiple schema types. +// This function determines the type of aggregator created, and +// what data is sent to it: values, tuples, or multi-tuples that must +// be standardized into a consistent schema. + function aggrType(def, scale) { + var refs = getRefs(def); + + // If we're operating over only a single domain, send full tuples + // through for efficiency (fewer accessor creations/calls) + if (refs.length == 1 && dl.array(refs[0].field).length == 1) { + return Aggregate.TYPES.TUPLE; + } + + // With quantitative scales, we only care about min/max. + if (!isUniques(scale)) return Aggregate.TYPES.VALUE; + + // If we don't sort, then we can send values directly to aggrs as well + if (!dl.isObject(def.sort)) return Aggregate.TYPES.VALUE; + + return Aggregate.TYPES.MULTI; + } + + function getCache(which, def, scale, group) { + var refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + uniques = isUniques(scale), + sort = def.sort, + ck = '_'+which, + fields = getFields(refs[0], group); + + if (scale[ck] || this[ck]) return scale[ck] || this[ck]; + + var cache = new Aggregate(this._graph).type(atype), + groupby, summarize; + + // If a scale's dataref doesn't inherit data from the group, we can + // store the dataref aggregator at the Scale (dataflow node) level. + if (inherit) { + scale[ck] = cache; + } else { + this[ck] = cache; + } + + if (uniques) { + if (atype === Aggregate.TYPES.VALUE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.identity }]; + summarize = {'*': DataRef.COUNT}; + } else if (atype === Aggregate.TYPES.TUPLE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.$(fields[0]) }]; + summarize = dl.isObject(sort) ? [{ + field: DataRef.VALUE, + get: dl.$(sort.field), + ops: [sort.op] + }] : {'*': DataRef.COUNT}; + } else { // atype === Aggregate.TYPES.MULTI + groupby = DataRef.GROUPBY; + summarize = [{ field: DataRef.VALUE, ops: [sort.op] }]; + } + } else { + groupby = []; + summarize = [{ + field: DataRef.VALUE, + get: (atype == Aggregate.TYPES.TUPLE) ? dl.$(fields[0]) : dl.identity, + ops: [DataRef.MIN, DataRef.MAX], + as: [DataRef.MIN, DataRef.MAX] + }]; + } + + cache.param('groupby', groupby) + .param('summarize', summarize); + + return (cache._lastUpdate = -1, cache); + } + + function dataRef(which, def, scale, group) { + if (def == null) { return []; } + if (dl.isArray(def)) return def.map(signal.bind(this)); + + var self = this, graph = this._graph, + refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + cache = getCache.apply(this, arguments), + sort = def.sort, + uniques = isUniques(scale), + i, rlen, j, flen, ref, fields, field, data, from, so, cmp; + + function addDep(s) { + self.dependency(Deps.SIGNALS, s); + } + + if (inherit || (!inherit && cache._lastUpdate < this._stamp)) { + for (i=0, rlen=refs.length; i 1) f = 1; + e = curr.ease(f); + + for (i=0, n=curr.length; i 0 ? (e = 1e-12, Math.ceil) : (e = -1e-12, Math.floor), + e; + function log(x) { + return (domain[0] < 0 ? + -Math.log(x > 0 ? 0 : -x) : + Math.log(x < 0 ? 0 : x)) / Math.log(base); + } + function pow(x) { + return domain[0] < 0 ? -Math.pow(base, -x) : Math.pow(base, x); + } + return function(d) { + return pow(v(log(d) + e)) / d >= k ? f(d) : ''; + }; + } + + function getFormatter(formatType, str) { + var fmt = dl.format, + log = scale.type === 'log', + domain, f; + + switch (formatType) { + case NUMBER: + domain = scale.domain(); + f = fmt.auto.number(domain, tickCount, str || (log ? '.1r' : null)); + return log ? logFilter(domain, tickCount, f) : f; + case TIME: return (str ? fmt : fmt.auto).time(str); + case UTC: return (str ? fmt : fmt.auto).utc(str); + default: return String; + } + } + + function getTicks(format) { + var major = tickValues || (scale.ticks ? scale.ticks(tickCount) : scale.domain()), + minor = axisSubdivide(scale, major, tickSubdivide).map(ingest); + major = major.map(function(d) { return (d = ingest(d), d.label = format(d.data), d); }); + return [major, minor]; + } + + axis.def = function() { + if (!axisDef.type) axis_def(scale); + + var ticks = getTicks(getTickFormat()); + var tdata = title ? [title].map(ingest) : []; + + axisDef.marks[0].from = function() { return grid ? ticks[0] : []; }; + axisDef.marks[1].from = function() { return ticks[0]; }; + axisDef.marks[2].from = function() { return ticks[1]; }; + axisDef.marks[3].from = axisDef.marks[1].from; + axisDef.marks[4].from = function() { return [1]; }; + axisDef.marks[5].from = function() { return tdata; }; + axisDef.offset = offset; + axisDef.orient = orient; + axisDef.layer = layer; + if (titleOffset === 'auto') titleAutoOffset(axisDef); + + return axisDef; + }; + + function titleAutoOffset(axisDef) { + var orient = axisDef.orient, + update = axisDef.marks[5].properties.update, + fn = update.encode, + min = config.titleOffsetAutoMin, + max = config.titleOffsetAutoMax, + pad = config.titleOffsetAutoMargin; + + // Offset axis title using bounding box of axis domain and labels + // Assumes other components are **encoded and bounded** beforehand + update.encode = function(item, group, trans, db, signals, preds) { + var dirty = fn.call(fn, item, group, trans, db, signals, preds), + field = (orient==='bottom' || orient==='top') ? 'y' : 'x'; + if (titleStyle[field] != null) return dirty; + + axisBounds.clear() + .union(group.items[3].bounds) + .union(group.items[4].bounds); + + var o = trans ? {} : item, + method = (orient==='left' || orient==='right') ? 'width' : 'height', + sign = (orient==='top' || orient==='left') ? -1 : 1, + off = ~~(axisBounds[method]() + item.fontSize/2 + pad); + + Tuple.set(o, field, sign * Math.min(Math.max(min, off), max)); + if (trans) trans.interpolate(item, o); + return true; + }; + } + + function axis_def(scale) { + // setup scale mapping + var newScale, oldScale, range; + if (scale.type === ORDINAL) { + newScale = {scale: scale.scaleName, offset: 0.5 + scale.rangeBand()/2}; + oldScale = newScale; + } else { + newScale = {scale: scale.scaleName, offset: 0.5}; + oldScale = {scale: scale.scaleName+':prev', offset: 0.5}; + } + range = axisScaleRange(scale); + + // setup axis marks + dl.extend(m.gridLines, axisTicks(config)); + dl.extend(m.majorTicks, axisTicks(config)); + dl.extend(m.minorTicks, axisTicks(config)); + dl.extend(m.tickLabels, axisTickLabels(config)); + dl.extend(m.domain, axisDomain(config)); + dl.extend(m.title, axisTitle(config)); + m.gridLines.properties.enter.stroke = {value: config.gridColor}; + m.gridLines.properties.enter.strokeOpacity = {value: config.gridOpacity}; + + // extend axis marks based on axis orientation + axisTicksExtend(orient, m.gridLines, oldScale, newScale, Infinity); + axisTicksExtend(orient, m.majorTicks, oldScale, newScale, tickMajorSize); + axisTicksExtend(orient, m.minorTicks, oldScale, newScale, tickMinorSize); + axisLabelExtend(orient, m.tickLabels, oldScale, newScale, tickMajorSize, tickPadding); + + axisDomainExtend(orient, m.domain, range, tickEndSize); + axisTitleExtend(orient, m.title, range, +titleOffset || -1); + + // add / override custom style properties + dl.extend(m.gridLines.properties.update, gridLineStyle); + dl.extend(m.majorTicks.properties.update, majorTickStyle); + dl.extend(m.minorTicks.properties.update, minorTickStyle); + dl.extend(m.tickLabels.properties.update, tickLabelStyle); + dl.extend(m.domain.properties.update, domainStyle); + dl.extend(m.title.properties.update, titleStyle); + + var marks = [m.gridLines, m.majorTicks, m.minorTicks, m.tickLabels, m.domain, m.title]; + dl.extend(axisDef, { + type: 'group', + interactive: false, + properties: { + enter: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + }, + update: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + } + } + }); + + axisDef.marks = marks.map(function(m) { return parseMark(model, m); }); + } + + axis.scale = function(x) { + if (!arguments.length) return scale; + if (scale !== x) { scale = x; reset(); } + return axis; + }; + + axis.orient = function(x) { + if (!arguments.length) return orient; + if (orient !== x) { + orient = x in axisOrients ? x + '' : config.orient; + reset(); + } + return axis; + }; + + axis.title = function(x) { + if (!arguments.length) return title; + if (title !== x) { title = x; reset(); } + return axis; + }; + + axis.tickCount = function(x) { + if (!arguments.length) return tickCount; + tickCount = x; + return axis; + }; + + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormatString; + if (tickFormatString !== x) { + tickFormatString = x; + reset(); + } + return axis; + }; + + axis.tickFormatType = function(x) { + if (!arguments.length) return tickFormatType; + if (tickFormatType !== x) { + tickFormatType = x; + reset(); + } + return axis; + }; + + axis.tickSize = function(x, y) { + if (!arguments.length) return tickMajorSize; + var n = arguments.length - 1, + major = +x, + minor = n > 1 ? +y : tickMajorSize, + end = n > 0 ? +arguments[n] : tickMajorSize; + + if (tickMajorSize !== major || + tickMinorSize !== minor || + tickEndSize !== end) { + reset(); + } + + tickMajorSize = major; + tickMinorSize = minor; + tickEndSize = end; + return axis; + }; + + axis.tickSubdivide = function(x) { + if (!arguments.length) return tickSubdivide; + tickSubdivide = +x; + return axis; + }; + + axis.offset = function(x) { + if (!arguments.length) return offset; + offset = dl.isObject(x) ? x : +x; + return axis; + }; + + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + if (tickPadding !== +x) { tickPadding = +x; reset(); } + return axis; + }; + + axis.titleOffset = function(x) { + if (!arguments.length) return titleOffset; + if (titleOffset !== x) { titleOffset = x; reset(); } + return axis; + }; + + axis.layer = function(x) { + if (!arguments.length) return layer; + if (layer !== x) { layer = x; reset(); } + return axis; + }; + + axis.grid = function(x) { + if (!arguments.length) return grid; + if (grid !== x) { grid = x; reset(); } + return axis; + }; + + axis.gridLineProperties = function(x) { + if (!arguments.length) return gridLineStyle; + if (gridLineStyle !== x) { gridLineStyle = x; } + return axis; + }; + + axis.majorTickProperties = function(x) { + if (!arguments.length) return majorTickStyle; + if (majorTickStyle !== x) { majorTickStyle = x; } + return axis; + }; + + axis.minorTickProperties = function(x) { + if (!arguments.length) return minorTickStyle; + if (minorTickStyle !== x) { minorTickStyle = x; } + return axis; + }; + + axis.tickLabelProperties = function(x) { + if (!arguments.length) return tickLabelStyle; + if (tickLabelStyle !== x) { tickLabelStyle = x; } + return axis; + }; + + axis.titleProperties = function(x) { + if (!arguments.length) return titleStyle; + if (titleStyle !== x) { titleStyle = x; } + return axis; + }; + + axis.domainProperties = function(x) { + if (!arguments.length) return domainStyle; + if (domainStyle !== x) { domainStyle = x; } + return axis; + }; + + axis.reset = function() { + reset(); + return axis; + }; + + return axis; + } + + var axisOrients = {top: 1, right: 1, bottom: 1, left: 1}; + + function axisSubdivide(scale, ticks, m) { + var subticks = []; + if (m && ticks.length > 1) { + var extent = axisScaleExtent(scale.domain()), + i = -1, + n = ticks.length, + d = (ticks[1] - ticks[0]) / ++m, + j, + v; + while (++i < n) { + for (j = m; --j > 0;) { + if ((v = +ticks[i] - j * d) >= extent[0]) { + subticks.push(v); + } + } + } + for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) { + subticks.push(v); + } + } + return subticks; + } + + function axisScaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start]; + } + + function axisScaleRange(scale) { + return scale.rangeExtent ? + scale.rangeExtent() : + axisScaleExtent(scale.range()); + } + + var axisAlign = { + bottom: 'center', + top: 'center', + left: 'right', + right: 'left' + }; + + var axisBaseline = { + bottom: 'top', + top: 'bottom', + left: 'middle', + right: 'middle' + }; + + function axisLabelExtend(orient, labels, oldScale, newScale, size, pad) { + size = Math.max(size, 0) + pad; + if (orient === 'left' || orient === 'top') { + size *= -1; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(labels.properties.enter, { + x: oldScale, + y: {value: size}, + }); + dl.extend(labels.properties.update, { + x: newScale, + y: {value: size}, + align: {value: 'center'}, + baseline: {value: axisBaseline[orient]} + }); + } else { + dl.extend(labels.properties.enter, { + x: {value: size}, + y: oldScale, + }); + dl.extend(labels.properties.update, { + x: {value: size}, + y: newScale, + align: {value: axisAlign[orient]}, + baseline: {value: 'middle'} + }); + } + } + + function axisTicksExtend(orient, ticks, oldScale, newScale, size) { + var sign = (orient === 'left' || orient === 'top') ? -1 : 1; + if (size === Infinity) { + size = (orient === 'top' || orient === 'bottom') ? + {field: {group: 'height', level: 2}, mult: -sign} : + {field: {group: 'width', level: 2}, mult: -sign}; + } else { + size = {value: sign * size}; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(ticks.properties.enter, { + x: oldScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.update, { + x: newScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.exit, { + x: newScale, + }); + } else { + dl.extend(ticks.properties.enter, { + x: {value: 0}, + x2: size, + y: oldScale + }); + dl.extend(ticks.properties.update, { + x: {value: 0}, + x2: size, + y: newScale + }); + dl.extend(ticks.properties.exit, { + y: newScale, + }); + } + } + + function axisTitleExtend(orient, title, range, offset) { + var update = title.properties.update, + mid = ~~((range[0] + range[1]) / 2), + sign = (orient === 'top' || orient === 'left') ? -1 : 1; + + if (orient === 'bottom' || orient === 'top') { + update.x = {value: mid}; + update.angle = {value: 0}; + if (offset >= 0) update.y = sign * offset; + } else { + update.y = {value: mid}; + update.angle = {value: orient === 'left' ? -90 : 90}; + if (offset >= 0) update.x = sign * offset; + } + } + + function axisDomainExtend(orient, domain, range, size) { + var path; + if (orient === 'top' || orient === 'left') { + size = -1 * size; + } + if (orient === 'bottom' || orient === 'top') { + path = 'M' + range[0] + ',' + size + 'V0H' + range[1] + 'V' + size; + } else { + path = 'M' + size + ',' + range[0] + 'H0V' + range[1] + 'H' + size; + } + domain.properties.update.path = {value: path}; + } + + function axisUpdate(item, group, trans) { + var o = trans ? {} : item, + offset = item.mark.def.offset, + orient = item.mark.def.orient, + width = group.width, + height = group.height; // TODO fallback to global w,h? + + if (dl.isArray(offset)) { + var ofx = offset[0], + ofy = offset[1]; + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -ofx); Tuple.set(o, 'y', ofy); break; } + case 'right': { Tuple.set(o, 'x', width + ofx); Tuple.set(o, 'y', ofy); break; } + case 'bottom': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', height + ofy); break; } + case 'top': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', -ofy); break; } + default: { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', ofy); } + } + } else { + if (dl.isObject(offset)) { + offset = -group.scale(offset.scale)(offset.value); + } + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -offset); Tuple.set(o, 'y', 0); break; } + case 'right': { Tuple.set(o, 'x', width + offset); Tuple.set(o, 'y', 0); break; } + case 'bottom': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', height + offset); break; } + case 'top': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', -offset); break; } + default: { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', 0); } + } + } + + if (trans) trans.interpolate(item, o); + return true; + } + + function axisTicks(config) { + return { + type: 'rule', + interactive: false, + key: 'data', + properties: { + enter: { + stroke: {value: config.tickColor}, + strokeWidth: {value: config.tickWidth}, + opacity: {value: 1e-6} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTickLabels(config) { + return { + type: 'text', + interactive: true, + key: 'data', + properties: { + enter: { + fill: {value: config.tickLabelColor}, + font: {value: config.tickLabelFont}, + fontSize: {value: config.tickLabelFontSize}, + opacity: {value: 1e-6}, + text: {field: 'label'} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTitle(config) { + return { + type: 'text', + interactive: true, + properties: { + enter: { + font: {value: config.titleFont}, + fontSize: {value: config.titleFontSize}, + fontWeight: {value: config.titleFontWeight}, + fill: {value: config.titleColor}, + align: {value: 'center'}, + baseline: {value: 'middle'}, + text: {field: 'data'} + }, + update: {} + } + }; + } + + function axisDomain(config) { + return { + type: 'path', + interactive: false, + properties: { + enter: { + x: {value: 0.5}, + y: {value: 0.5}, + stroke: {value: config.axisColor}, + strokeWidth: {value: config.axisWidth} + }, + update: {} + } + }; + } + + module.exports = axs; +},{"../parse/mark":99,"datalib":26,"vega-dataflow":41,"vega-scenegraph":48}],116:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Gradient = require('vega-scenegraph').Gradient, + parseProperties = require('../parse/properties'), + parseMark = require('../parse/mark'); + + function lgnd(model) { + var size = null, + shape = null, + fill = null, + stroke = null, + spacing = null, + values = null, + format = null, + formatString = null, + config = model.config().legend, + title, + orient = config.orient, + offset = config.offset, + padding = config.padding, + tickArguments = [5], + legendStyle = {}, + symbolStyle = {}, + gradientStyle = {}, + titleStyle = {}, + labelStyle = {}, + m = { // Legend marks as references for updates + titles: {}, + symbols: {}, + labels: {}, + gradient: {} + }; + + var legend = {}, + legendDef = {}; + + function reset() { legendDef.type = null; } + function ingest(d, i) { return {data: d, index: i}; } + + legend.def = function() { + var scale = size || shape || fill || stroke; + + format = !formatString ? null : ((scale.type === 'time') ? + dl.format.time(formatString) : dl.format.number(formatString)); + + if (!legendDef.type) { + legendDef = (scale===fill || scale===stroke) && !discrete(scale.type) ? + quantDef(scale) : ordinalDef(scale); + } + legendDef.orient = orient; + legendDef.offset = offset; + legendDef.padding = padding; + legendDef.margin = config.margin; + return legendDef; + }; + + function discrete(type) { + return type==='ordinal' || type==='quantize' || + type==='quantile' || type==='threshold'; + } + + function ordinalDef(scale) { + var def = o_legend_def(size, shape, fill, stroke); + + // generate data + var data = (values == null ? + (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : + values).map(ingest); + var fmt = format==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : format; + + // determine spacing between legend entries + var fs, range, offset, pad=5, domain = d3.range(data.length); + if (size) { + range = data.map(function(x) { return Math.sqrt(size(x.data)); }); + offset = d3.max(range); + range = range.reduce(function(a,b,i,z) { + if (i > 0) a[i] = a[i-1] + z[i-1]/2 + pad; + return (a[i] += b/2, a); }, [0]).map(Math.round); + } else { + offset = Math.round(Math.sqrt(config.symbolSize)); + range = spacing || + (fs = labelStyle.fontSize) && (fs.value + pad) || + (config.labelFontSize + pad); + range = domain.map(function(d,i) { + return Math.round(offset/2 + i*range); + }); + } + + // account for padding and title size + var sz = padding, ts; + if (title) { + ts = titleStyle.fontSize; + sz += 5 + ((ts && ts.value) || config.titleFontSize); + } + for (var i=0, n=range.length; i'}, + summarize: { + type: 'custom', + set: function(summarize) { + var signalDeps = {}, + tx = this._transform, + i, len, f, fields, name, ops; + + if (!dl.isArray(fields = summarize)) { // Object syntax from dl + fields = []; + for (name in summarize) { + ops = dl.array(summarize[name]); + fields.push({field: name, ops: ops}); + } + } + + function sg(x) { if (x.signal) signalDeps[x.signal] = 1; } + + for (i=0, len=fields.length; i', default: [5, 2]} + }); + + this._output = { + start: 'bin_start', + end: 'bin_end', + mid: 'bin_mid' + }; + return this.mutates(true); + } + + var prototype = (Bin.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Bin; + + prototype.extent = function(data) { + // TODO only recompute extent upon data or field change? + var e = [this.param('min'), this.param('max')], d; + if (e[0] == null || e[1] == null) { + d = dl.extent(data, this.param('field').accessor); + if (e[0] == null) e[0] = d[0]; + if (e[1] == null) e[1] = d[1]; + } + return e; + }; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['binning']); + + var extent = this.extent(data), + output = this._output, + step = this.param('step'), + steps = this.param('steps'), + minstep = this.param('minstep'), + get = this.param('field').accessor, + opt = { + min: extent[0], + max: extent[1], + base: this.param('base'), + maxbins: this.param('maxbins'), + div: this.param('div') + }; + + if (step) opt.step = step; + if (steps) opt.steps = steps; + if (minstep) opt.minstep = minstep; + var b = dl.bins(opt), + s = b.step; + + function update(d) { + var v = get(d); + v = v == null ? null + : b.start + s * ~~((v - b.start) / s); + Tuple.set(d, output.start, v); + Tuple.set(d, output.end, v + s); + Tuple.set(d, output.mid, v + s/2); + } + input.add.forEach(update); + input.mod.forEach(update); + input.rem.forEach(update); + + input.fields[output.start] = 1; + input.fields[output.end] = 1; + input.fields[output.mid] = 1; + return input; + }; + + module.exports = Bin; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],121:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function CountPattern(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + field: {type: 'field', default: 'data'}, + pattern: {type: 'value', default: '[\\w\']+'}, + case: {type: 'value', default: 'lower'}, + stopwords: {type: 'value', default: ''} + }); + + this._output = {text: 'text', count: 'count'}; + + return this.router(true).produces(true); + } + + var prototype = (CountPattern.prototype = Object.create(Transform.prototype)); + prototype.constructor = CountPattern; + + prototype.transform = function(input, reset) { + log.debug(input, ['countpattern']); + + var get = this.param('field').accessor, + pattern = this.param('pattern'), + stop = this.param('stopwords'), + rem = false; + + // update parameters + if (this._stop !== stop) { + this._stop = stop; + this._stop_re = new RegExp('^' + stop + '$', 'i'); + reset = true; + } + + if (this._pattern !== pattern) { + this._pattern = pattern; + this._match = new RegExp(this._pattern, 'g'); + reset = true; + } + + if (reset) this._counts = {}; + + function curr(t) { return (Tuple.prev_init(t), get(t)); } + function prev(t) { return get(Tuple.prev(t)); } + + this._add(input.add, curr); + if (!reset) this._rem(input.rem, prev); + if (reset || (rem = input.fields[get.field])) { + if (rem) this._rem(input.mod, prev); + this._add(input.mod, curr); + } + + // generate output tuples + return this._changeset(input); + }; + + prototype._changeset = function(input) { + var counts = this._counts, + tuples = this._tuples || (this._tuples = {}), + change = df.ChangeSet.create(input), + out = this._output, w, t, c; + + for (w in counts) { + t = tuples[w]; + c = counts[w] || 0; + if (!t && c) { + tuples[w] = (t = Tuple.ingest({})); + t[out.text] = w; + t[out.count] = c; + change.add.push(t); + } else if (c === 0) { + if (t) change.rem.push(t); + delete counts[w]; + delete tuples[w]; + } else if (t[out.count] !== c) { + Tuple.set(t, out.count, c); + change.mod.push(t); + } + } + return change; + }; + + prototype._tokenize = function(text) { + switch (this.param('case')) { + case 'upper': text = text.toUpperCase(); break; + case 'lower': text = text.toLowerCase(); break; + } + return text.match(this._match); + }; + + prototype._add = function(tuples, get) { + var counts = this._counts, + stop = this._stop_re, + tok, i, j, t; + + for (j=0; j cross.s, + fltrd = !cross || cross.f, + omod = output.mod, + orem = output.rem, + i, t, y; + + // If we have cached values, iterate through them for lazy + // removal, and to re-run the filter. + if (tpls) { + if (lazy || test) { + for (i=tpls.length-1; i>=0; --i) { + t = tpls[i]; + y = t[other]; + + if (lazy && !cache[y._id]) { + tpls.splice(i, 1); + continue; + } + + if (!test || test(t)) { + omod.push(t); + } else { + orem.push.apply(orem, tpls.splice(i, 1)); + cross.f = true; + } + } + + cross.s = this._lastRem; + } else { + omod.push.apply(omod, tpls); + } + } + + // If we have a filter param, call add to catch any tuples that may + // have previously been filtered. + if (test && fltrd) add.call(this, output, left, data, diag, test, x); + } + + function rem(output, x) { + var cross = this._cache[x._id]; + if (!cross) return; + output.rem.push.apply(output.rem, cross.c); + this._cache[x._id] = null; + this._lastRem = this._stamp; + } + + function purge(output) { + var cache = this._cache, + keys = dl.keys(cache), + rem = output.rem, + ids = {}, + i, len, j, jlen, cross, t; + + for (i=0, len=keys.length; i this._lastWith) { + woutput.rem.forEach(r); + woutput.add.forEach(add.bind(this, output, false, data, diag, test)); + woutput.mod.forEach(mod.bind(this, output, false, data, diag, test)); + this._lastWith = woutput.stamp; + } + + // Mods need to come after all removals have been run. + input.mod.forEach(mod.bind(this, output, true, wdata, diag, test)); + } + + output.fields[as.left] = 1; + output.fields[as.right] = 1; + return output; + }; + + module.exports = Cross; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],123:[function(require,module,exports){ + var Transform = require('./Transform'), + Aggregate = require('./Aggregate'); + + function Facet(graph) { + Transform.addParameters(this, { + transform: { + type: "custom", + set: function(pipeline) { + return (this._transform._pipeline = pipeline, this._transform); + }, + get: function() { + var parse = require('../parse/transforms'), + facet = this._transform; + return facet._pipeline.map(function(t) { + return parse(facet._graph, t); + }); + } + } + }); + + this._pipeline = []; + return Aggregate.call(this, graph); + } + + var prototype = (Facet.prototype = Object.create(Aggregate.prototype)); + prototype.constructor = Facet; + + prototype.aggr = function() { + return Aggregate.prototype.aggr.call(this).facet(this); + }; + + prototype.transform = function(input, reset) { + var output = Aggregate.prototype.transform.call(this, input, reset); + + // New facet cells should trigger a re-ranking of the dataflow graph. + // This ensures facet datasources are computed before scenegraph nodes. + // We rerank the Facet's first listener, which is the next node in the + // datasource's pipeline. + if (input.add.length) { + this.listeners()[0].rerank(); + } + + return output; + }; + + module.exports = Facet; +},{"../parse/transforms":108,"./Aggregate":118,"./Transform":139}],124:[function(require,module,exports){ + var dl = require('datalib'), + Aggregator = dl.Aggregator, + Base = Aggregator.prototype, + df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + facetID = 0; + + function Facetor() { + Aggregator.call(this); + this._facet = null; + this._facetID = ++facetID; + } + + var prototype = (Facetor.prototype = Object.create(Base)); + prototype.constructor = Facetor; + + prototype.facet = function(f) { + return arguments.length ? (this._facet = f, this) : this._facet; + }; + + prototype._ingest = function(t) { + return Tuple.ingest(t, null); + }; + + prototype._assign = Tuple.set; + + function disconnect_cell(facet) { + log.debug({}, ['disconnecting cell', this.tuple._id]); + var pipeline = this.ds.pipeline(); + facet.removeListener(pipeline[0]); + facet._graph.removeListener(pipeline[0]); + facet._graph.disconnect(pipeline); + } + + prototype._newcell = function(x, key) { + var cell = Base._newcell.call(this, x, key), + facet = this._facet; + + if (facet) { + var graph = facet._graph, + tuple = cell.tuple, + pipeline = facet.param('transform'); + cell.ds = graph.data(tuple._facetID, pipeline, tuple); + cell.disconnect = disconnect_cell; + facet.addListener(pipeline[0]); + } + + return cell; + }; + + prototype._newtuple = function(x, key) { + var t = Base._newtuple.call(this, x); + if (this._facet) { + Tuple.set(t, 'key', key); + Tuple.set(t, '_facetID', this._facetID + '_' + key); + } + return t; + }; + + prototype.clear = function() { + if (this._facet) { + for (var k in this._cells) { + this._cells[k].disconnect(this._facet); + } + } + return Base.clear.call(this); + }; + + prototype._on_add = function(x, cell) { + if (this._facet) cell.ds._input.add.push(x); + }; + + prototype._on_rem = function(x, cell) { + if (this._facet) cell.ds._input.rem.push(x); + }; + + prototype._on_mod = function(x, prev, cell0, cell1) { + if (this._facet) { // Propagate tuples + if (cell0 === cell1) { + cell0.ds._input.mod.push(x); + } else { + cell0.ds._input.rem.push(x); + cell1.ds._input.add.push(x); + } + } + }; + + prototype._on_drop = function(cell) { + if (this._facet) cell.disconnect(this._facet); + }; + + prototype._on_keep = function(cell) { + // propagate sort, signals, fields, etc. + if (this._facet) df.ChangeSet.copy(this._input, cell.ds._input); + }; + + module.exports = Facetor; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],125:[function(require,module,exports){ + var df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Filter(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, {test: {type: 'expr'}}); + + this._skip = {}; + return this.router(true); + } + + var prototype = (Filter.prototype = Object.create(Transform.prototype)); + prototype.constructor = Filter; + + prototype.transform = function(input) { + log.debug(input, ['filtering']); + + var output = df.ChangeSet.create(input), + graph = this._graph, + skip = this._skip, + test = this.param('test'), + signals = graph.values(SIGNALS, this.dependency(SIGNALS)); + + input.rem.forEach(function(x) { + if (skip[x._id] !== 1) output.rem.push(x); + else skip[x._id] = 0; + }); + + input.add.forEach(function(x) { + if (test(x, null, signals)) output.add.push(x); + else skip[x._id] = 1; + }); + + input.mod.forEach(function(x) { + var b = test(x, null, signals), + s = (skip[x._id] === 1); + if (b && s) { + skip[x._id] = 0; + output.add.push(x); + } else if (b && !s) { + output.mod.push(x); + } else if (!b && s) { + // do nothing, keep skip true + } else { // !b && !s + output.rem.push(x); + skip[x._id] = 1; + } + }); + + return output; + }; + + module.exports = Filter; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],126:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Fold(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + fields: {type: 'array'} + }); + + this._output = {key: 'key', value: 'value'}; + this._cache = {}; + + return this.router(true).produces(true); + } + + var prototype = (Fold.prototype = Object.create(Transform.prototype)); + prototype.constructor = Fold; + + prototype._reset = function(input, output) { + for (var id in this._cache) { + output.rem.push.apply(output.rem, this._cache[id]); + } + this._cache = {}; + }; + + prototype._tuple = function(x, i, len) { + var list = this._cache[x._id] || (this._cache[x._id] = Array(len)); + return list[i] ? Tuple.rederive(x, list[i]) : (list[i] = Tuple.derive(x)); + }; + + prototype._fn = function(data, on, out) { + var i, j, n, m, d, t; + for (i=0, n=data.length; i', default: require('./screen').size}, + bound: {type: 'value', default: true}, + links: {type: 'data'}, + + // TODO: for now force these to be value params only (pun-intended) + // Can update to include fields after Parameter refactoring. + linkStrength: {type: 'value', default: 1}, + linkDistance: {type: 'value', default: 20}, + charge: {type: 'value', default: -30}, + + chargeDistance: {type: 'value', default: Infinity}, + friction: {type: 'value', default: 0.9}, + theta: {type: 'value', default: 0.8}, + gravity: {type: 'value', default: 0.1}, + alpha: {type: 'value', default: 0.1}, + iterations: {type: 'value', default: 500}, + + interactive: {type: 'value', default: this._interactive}, + active: {type: 'value', default: this._prev}, + fixed: {type: 'data'} + }); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y' + }; + + return this.mutates(true); + } + + var prototype = (Force.prototype = Object.create(Transform.prototype)); + prototype.constructor = Force; + + prototype.transform = function(nodeInput, reset) { + log.debug(nodeInput, ['force']); + reset = reset - (nodeInput.signals.active ? 1 : 0); + + // get variables + var interactive = this.param('interactive'), + linkSource = this.param('links').source, + linkInput = linkSource.last(), + active = this.param('active'), + output = this._output, + layout = this._layout, + nodes = this._nodes, + links = this._links; + + // configure nodes, links and layout + if (linkInput.stamp < nodeInput.stamp) linkInput = null; + this.configure(nodeInput, linkInput, interactive, reset); + + // run batch layout + if (!interactive) { + var iterations = this.param('iterations'); + for (var i=0; i'}, + translate: {type: 'array', default: require('./screen').center}, + rotate: {type: 'array'}, + scale: {type: 'value'}, + precision: {type: 'value'}, + clipAngle: {type: 'value'}, + clipExtent: {type: 'value'} + }; + + Geo.d3Projection = function() { + var p = this.param('projection'), + param = Geo.Parameters, + proj, name, value; + + if (p !== this._mode) { + this._mode = p; + this._projection = d3.geo[p](); + } + proj = this._projection; + + for (name in param) { + if (name === 'projection' || !proj[name]) continue; + value = this.param(name); + if (value === undefined || (dl.isArray(value) && value.length === 0)) { + continue; + } + if (value !== proj[name]()) { + proj[name](value); + } + } + + return proj; + }; + + var prototype = (Geo.prototype = Object.create(Transform.prototype)); + prototype.constructor = Geo; + + prototype.transform = function(input) { + log.debug(input, ['geo']); + + var output = this._output, + lon = this.param('lon').accessor, + lat = this.param('lat').accessor, + proj = Geo.d3Projection.call(this); + + function set(t) { + var ll = [lon(t), lat(t)]; + var xy = proj(ll) || [null, null]; + Tuple.set(t, output.x, xy[0]); + Tuple.set(t, output.y, xy[1]); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + return input; + }; + + module.exports = Geo; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],130:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Geo = require('./Geo'), + Transform = require('./Transform'); + + function GeoPath(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, Geo.Parameters); + Transform.addParameters(this, { + field: {type: 'field', default: null}, + }); + + this._output = { + 'path': 'layout_path' + }; + return this.mutates(true); + } + + var prototype = (GeoPath.prototype = Object.create(Transform.prototype)); + prototype.constructor = GeoPath; + + prototype.transform = function(input) { + log.debug(input, ['geopath']); + + var output = this._output, + geojson = this.param('field').accessor || dl.identity, + proj = Geo.d3Projection.call(this), + path = d3.geo.path().projection(proj); + + function set(t) { + Tuple.set(t, output.path, path(geojson(t))); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = GeoPath; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Geo":129,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],131:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Hierarchy(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + // hierarchy parameters + sort: {type: 'array', default: null}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'value', default: null}, + // layout parameters + mode: {type: 'value', default: 'tidy'}, // tidy, cluster, partition + size: {type: 'array', default: require('./screen').size}, + nodesize: {type: 'array', default: null}, + orient: {type: 'value', default: 'cartesian'} + }); + + this._mode = null; + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth' + }; + return this.mutates(true); + } + + var PARTITION = 'partition'; + + var SEPARATION = { + cartesian: function(a, b) { return (a.parent === b.parent ? 1 : 2); }, + radial: function(a, b) { return (a.parent === b.parent ? 1 : 2) / a.depth; } + }; + + var prototype = (Hierarchy.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Hierarchy; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['hierarchy layout']); + + // get variables + var layout = this._layout, + output = this._output, + mode = this.param('mode'), + sort = this.param('sort'), + nodesz = this.param('nodesize'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + if (mode !== this._mode) { + this._mode = mode; + if (mode === 'tidy') mode = 'tree'; + layout = (this._layout = d3.layout[mode]()); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.depth] = 1; + if (mode === PARTITION) { + input.fields[output.width] = 1; + input.fields[output.height] = 1; + layout.value(this.param('field').accessor); + } else { + layout.separation(SEPARATION[this.param('orient')]); + } + + if (nodesz.length && mode !== PARTITION) { + layout.nodeSize(nodesz); + } else { + layout.size(this.param('size')); + } + + layout + .sort(sort.field.length ? dl.comparator(sort.field) : null) + .children(this.param('children').accessor) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.depth, n.depth); + if (mode === PARTITION) { + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + } + }); + + // return changeset + return input; + }; + + module.exports = Hierarchy; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],132:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple, + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Impute(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + orderby: {type: 'array'}, + field: {type: 'field'}, + method: {type: 'value', default: 'value'}, + value: {type: 'value', default: 0} + }); + + return this.router(true).produces(true); + } + + var prototype = (Impute.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Impute; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['imputing']); + + var groupby = this.param('groupby'), + orderby = this.param('orderby'), + method = this.param('method'), + value = this.param('value'), + field = this.param('field'), + get = field.accessor, + name = field.field, + prev = this._imputed || [], curr = [], + groups = partition(data, groupby.accessor, orderby.accessor), + domain = groups.domain, + group, i, j, n, m, t; + + function getval(x) { + return x == null ? null : get(x); + } + + for (j=0, m=groups.length; j Math.PI ? ta <= sa : ta > sa; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'A' + sr + ',' + sr + ' 0 0,' + (sf?1:0) + + ' ' + (sr*tc) + ',' + (sr*ts) + + 'L' + (tr*tc) + ',' + (tr*ts); + } + + function diagonalX(sx, sy, tx, ty) { + var m = (sx + tx) / 2; + return 'M' + sx + ',' + sy + + 'C' + m + ',' + sy + + ' ' + m + ',' + ty + + ' ' + tx + ',' + ty; + } + + function diagonalY(sx, sy, tx, ty) { + var m = (sy + ty) / 2; + return 'M' + sx + ',' + sy + + 'C' + sx + ',' + m + + ' ' + tx + ',' + m + + ' ' + tx + ',' + ty; + } + + function diagonalR(sa, sr, ta, tr) { + var sc = Math.cos(sa), + ss = Math.sin(sa), + tc = Math.cos(ta), + ts = Math.sin(ta), + mr = (sr + tr) / 2; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'C' + (mr*sc) + ',' + (mr*ss) + + ' ' + (mr*tc) + ',' + (mr*ts) + + ' ' + (tr*tc) + ',' + (tr*ts); + } + + var shapes = { + line: line, + curve: curve, + cornerX: cornerX, + cornerY: cornerY, + cornerR: cornerR, + diagonalX: diagonalX, + diagonalY: diagonalY, + diagonalR: diagonalR + }; + + prototype.transform = function(input) { + log.debug(input, ['linkpath']); + + var output = this._output, + shape = shapes[this.param('shape')] || shapes.line, + sourceX = this.param('sourceX').accessor, + sourceY = this.param('sourceY').accessor, + targetX = this.param('targetX').accessor, + targetY = this.param('targetY').accessor, + tension = this.param('tension'); + + function set(t) { + var path = shape(sourceX(t), sourceY(t), targetX(t), targetY(t), tension); + Tuple.set(t, output.path, path); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = LinkPath; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],134:[function(require,module,exports){ + var Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Lookup(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + on: {type: 'data'}, + onKey: {type: 'field', default: null}, + as: {type: 'array'}, + keys: {type: 'array', default: ['data']}, + default: {type: 'value'} + }); + + return this.mutates(true); + } + + var prototype = (Lookup.prototype = Object.create(Transform.prototype)); + prototype.constructor = Lookup; + + prototype.transform = function(input, reset) { + log.debug(input, ['lookup']); + + var on = this.param('on'), + onLast = on.source.last(), + onData = on.source.values(), + onKey = this.param('onKey'), + onF = onKey.field, + keys = this.param('keys'), + get = keys.accessor, + as = this.param('as'), + defaultValue = this.param('default'), + lut = this._lut, + i, v; + + // build lookup table on init, withKey modified, or tuple add/rem + if (lut == null || this._on !== onF || onF && onLast.fields[onF] || + onLast.add.length || onLast.rem.length) + { + if (onF) { // build hash from withKey field + onKey = onKey.accessor; + for (lut={}, i=0; i'} }); + this.router(true); + } + + var prototype = (Sort.prototype = Object.create(Transform.prototype)); + prototype.constructor = Sort; + + prototype.transform = function(input) { + log.debug(input, ['sorting']); + + if (input.add.length || input.mod.length || input.rem.length) { + input.sort = dl.comparator(this.param('by').field); + } + return input; + }; + + module.exports = Sort; +},{"./Transform":139,"datalib":26,"vega-logging":47}],138:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Stack(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + sortby: {type: 'array'}, + field: {type: 'field'}, + offset: {type: 'value', default: 'zero'} + }); + + this._output = { + 'start': 'layout_start', + 'end': 'layout_end', + 'mid': 'layout_mid' + }; + return this.mutates(true); + } + + var prototype = (Stack.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Stack; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['stacking']); + + var groupby = this.param('groupby').accessor, + sortby = dl.comparator(this.param('sortby').field), + field = this.param('field').accessor, + offset = this.param('offset'), + output = this._output; + + // partition, sum, and sort the stack groups + var groups = partition(data, groupby, sortby, field); + + // compute stack layouts per group + for (var i=0, max=groups.max; i max) max = s; + if (sortby != null) g.sort(sortby); + } + groups.max = max; + + return groups; + } + + module.exports = Stack; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],139:[function(require,module,exports){ + var df = require('vega-dataflow'), + Base = df.Node.prototype, // jshint ignore:line + Deps = df.Dependencies, + Parameter = require('./Parameter'); + + function Transform(graph) { + if (graph) Base.init.call(this, graph); + } + + Transform.addParameters = function(proto, params) { + proto._parameters = proto._parameters || {}; + for (var name in params) { + var p = params[name], + param = new Parameter(name, p.type, proto); + + proto._parameters[name] = param; + + if (p.type === 'custom') { + if (p.set) param.set = p.set.bind(param); + if (p.get) param.get = p.get.bind(param); + } + + if (p.hasOwnProperty('default')) param.set(p.default); + } + }; + + var prototype = (Transform.prototype = Object.create(Base)); + prototype.constructor = Transform; + + prototype.param = function(name, value) { + var param = this._parameters[name]; + return (param === undefined) ? this : + (arguments.length === 1) ? param.get() : param.set(value); + }; + +// Perform transformation. Subclasses should override. + prototype.transform = function(input/*, reset */) { + return input; + }; + + prototype.evaluate = function(input) { + // Many transforms store caches that must be invalidated if + // a signal value has changed. + var reset = this._stamp < input.stamp && + this.dependency(Deps.SIGNALS).reduce(function(c, s) { + return c += input.signals[s] ? 1 : 0; + }, 0); + return this.transform(input, reset); + }; + + prototype.output = function(map) { + for (var key in this._output) { + if (map[key] !== undefined) { + this._output[key] = map[key]; + } + } + return this; + }; + + module.exports = Transform; +},{"./Parameter":135,"vega-dataflow":41}],140:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Treeify(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'} + }); + + this._output = { + 'children': 'children', + 'parent': 'parent' + }; + return this.router(true).produces(true); + } + + var prototype = (Treeify.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treeify; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treeifying']); + + var fields = this.param('groupby').field, + childField = this._output.children, + parentField = this._output.parent, + summary = [{name:'*', ops: ['values'], as: [childField]}], + aggrs = fields.map(function(f) { + return dl.groupby(f).summarize(summary); + }), + prev = this._internal || [], curr = [], i, n; + + function level(index, node, values) { + var vals = aggrs[index].execute(values); + + node[childField] = vals; + vals.forEach(function(n) { + n[parentField] = node; + curr.push(Tuple.ingest(n)); + if (index+1 < fields.length) level(index+1, n, n[childField]); + else n[childField].forEach(function(c) { c[parentField] = n; }); + }); + } + + var root = Tuple.ingest({}); + root[parentField] = null; + curr.push(root); + level(0, root, data); + + // update changeset with internal nodes + for (i=0, n=curr.length; i', default: ['-value']}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'field', default: 'value'}, + // treemap parameters + size: {type: 'array', default: require('./screen').size}, + round: {type: 'value', default: true}, + sticky: {type: 'value', default: false}, + ratio: {type: 'value', default: defaultRatio}, + padding: {type: 'value', default: null}, + mode: {type: 'value', default: 'squarify'} + }); + + this._layout = d3.layout.treemap(); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth', + }; + return this.mutates(true); + } + + var prototype = (Treemap.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treemap; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treemap']); + + // get variables + var layout = this._layout, + output = this._output, + sticky = this.param('sticky'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + // layout.sticky resets state _regardless_ of input value + // so, we perform out own check first + if (layout.sticky() !== sticky) { layout.sticky(sticky); } + + // configure layout + layout + .sort(dl.comparator(this.param('sort').field)) + .children(this.param('children').accessor) + .value(this.param('field').accessor) + .size(this.param('size')) + .round(this.param('round')) + .ratio(this.param('ratio')) + .padding(this.param('padding')) + .mode(this.param('mode')) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + Tuple.set(n, output.depth, n.depth); + }); + + // return changeset + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.width] = 1; + input.fields[output.height] = 1; + input.fields[output.depth] = 1; + return input; + }; + + module.exports = Treemap; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],142:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + Tuple = require('vega-dataflow/src/Tuple'), + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Voronoi(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + clipExtent: {type: 'array', default: require('./screen').extent}, + x: {type: 'field', default: 'layout_x'}, + y: {type: 'field', default: 'layout_y'} + }); + + this._layout = d3.geom.voronoi(); + this._output = {'path': 'layout_path'}; + + return this.mutates(true); + } + + var prototype = (Voronoi.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Voronoi; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['voronoi']); + + // get variables + var pathname = this._output.path; + + // configure layout + var polygons = this._layout + .clipExtent(this.param('clipExtent')) + .x(this.param('x').accessor) + .y(this.param('y').accessor) + (data); + + // build and assign path strings + for (var i=0; i', default: require('./screen').size}, + text: {type: 'field', default: 'data'}, + rotate: {type: 'field|value', default: 0}, + font: {type: 'field|value', default: {value: 'sans-serif'}}, + fontSize: {type: 'field|value', default: 14}, + fontStyle: {type: 'field|value', default: {value: 'normal'}}, + fontWeight: {type: 'field|value', default: {value: 'normal'}}, + fontScale: {type: 'array', default: [10, 50]}, + padding: {type: 'value', default: 1}, + spiral: {type: 'value', default: 'archimedean'} + }); + + this._layout = d3_cloud().canvas(canvas.instance); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'font': 'layout_font', + 'fontSize': 'layout_fontSize', + 'fontStyle': 'layout_fontStyle', + 'fontWeight': 'layout_fontWeight', + 'rotate': 'layout_rotate', + }; + + return this.mutates(true); + } + + var prototype = (Wordcloud.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Wordcloud; + + function get(p) { + return (p && p.accessor) || p; + } + + function wrap(tuple) { + var x = Object.create(tuple); + x._tuple = tuple; + return x; + } + + prototype.batchTransform = function(input, data) { + log.debug(input, ['wordcloud']); + + // get variables + var layout = this._layout, + output = this._output, + fontSize = this.param('fontSize'), + range = fontSize.accessor && this.param('fontScale'), + size, scale; + fontSize = fontSize.accessor || d3.functor(fontSize); + + // create font size scaling function as needed + if (range.length) { + scale = d3.scale.sqrt() + .domain(dl.extent(data, size=fontSize)) + .range(range); + fontSize = function(x) { return scale(size(x)); }; + } + + // configure layout + layout + .size(this.param('size')) + .text(get(this.param('text'))) + .padding(this.param('padding')) + .spiral(this.param('spiral')) + .rotate(get(this.param('rotate'))) + .font(get(this.param('font'))) + .fontStyle(get(this.param('fontStyle'))) + .fontWeight(get(this.param('fontWeight'))) + .fontSize(fontSize) + .words(data.map(wrap)) // wrap to avoid tuple writes + .on('end', function(words) { + var size = layout.size(), + dx = size[0] >> 1, + dy = size[1] >> 1, + w, t, i, len; + + for (i=0, len=words.length; i.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;} +.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;} +input,textarea,.uneditable-input{margin-left:0;} +.controls-row [class*="span"]+[class*="span"]{margin-left:20px;} +input.span12, textarea.span12, .uneditable-input.span12{width:926px;} +input.span11, textarea.span11, .uneditable-input.span11{width:846px;} +input.span10, textarea.span10, .uneditable-input.span10{width:766px;} +input.span9, textarea.span9, .uneditable-input.span9{width:686px;} +input.span8, textarea.span8, .uneditable-input.span8{width:606px;} +input.span7, textarea.span7, .uneditable-input.span7{width:526px;} +input.span6, textarea.span6, .uneditable-input.span6{width:446px;} +input.span5, textarea.span5, .uneditable-input.span5{width:366px;} +input.span4, textarea.span4, .uneditable-input.span4{width:286px;} +input.span3, textarea.span3, .uneditable-input.span3{width:206px;} +input.span2, textarea.span2, .uneditable-input.span2{width:126px;} +input.span1, textarea.span1, .uneditable-input.span1{width:46px;} +.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;} +.controls-row:after{clear:both;} +.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;} +.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;} +input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;} +.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;} +.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;} +.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;} +.form-actions:after{clear:both;} +.help-block,.help-inline{color:#595959;} +.help-block{display:block;margin-bottom:10px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px;} +.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;} +.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;} +.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;} +.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .btn-group:first-child{margin-left:0;} +input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;} +.control-group{margin-bottom:10px;} +legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;} +.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;} +.form-horizontal .help-block{margin-bottom:0;} +.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;} +.form-horizontal .form-actions{padding-left:180px;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:2px;} +.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;} +.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.btn-block+.btn-block{margin-top:5px;} +input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn{border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);} +.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;} +.btn-primary:active,.btn-primary.active{background-color:#003399 \9;} +.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;} +.btn-link[disabled]:hover{color:#333333;text-decoration:none;} +.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px;} +.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group>.btn+.btn{margin-left:-1px;} +.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px;} +.btn-group>.btn-mini{font-size:11px;} +.btn-group>.btn-small{font-size:12px;} +.btn-group>.btn-large{font-size:16px;} +.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;} +.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;} +.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;} +.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;} +.btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;} +.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;} +.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;} +.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;} +.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;} +.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;} +.btn .caret{margin-top:8px;margin-left:0;} +.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px;} +.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;} +.dropup .btn-large .caret{border-bottom-width:5px;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;} +.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group-vertical .btn+.btn{margin-left:0;margin-top:-1px;} +.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;} +.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav{margin-left:0;margin-bottom:20px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav>.pull-right{float:right;} +.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px;} +.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .dropdown-toggle .caret{margin-top:8px;} +.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;} +.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.nav>.dropdown.active>a:hover{cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0;} +.tabbable:after{clear:both;} +.tab-content{overflow:auto;} +.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below>.nav-tabs{border-top:1px solid #ddd;} +.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;} +.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left>.nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right>.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.nav>.disabled>a{color:#999999;} +.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;} +.navbar{overflow:visible;margin-bottom:20px;color:#777777;*position:relative;*z-index:2;} +.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;} +.navbar-inner:after{clear:both;} +.navbar .container{width:auto;} +.nav-collapse.collapse{height:auto;overflow:visible;} +.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover{text-decoration:none;} +.navbar-text{margin-bottom:0;line-height:40px;} +.navbar-link{color:#777777;}.navbar-link:hover{color:#333333;} +.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;} +.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);} +.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;margin-right:0;} +.navbar .nav>li{float:left;} +.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;} +.navbar .nav .dropdown-toggle .caret{margin-top:8px;} +.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;} +.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);} +.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;} +.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;} +.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;} +.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;} +.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;} +.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.navbar-inverse{color:#999999;}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;} +.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#ffffff;} +.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;} +.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;} +.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;} +.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;} +.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;} +.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;} +.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#ccc;} +.breadcrumb .active{color:#999999;} +.pagination{margin:20px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination ul>li{display:inline;} +.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;} +.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;} +.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;} +.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px;} +.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;} +.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;} +.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px;} +.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:1px 6px;font-size:10.5px;} +.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager li>a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next>a,.pager .next>span{float:right;} +.pager .previous>a,.pager .previous>span{float:left;} +.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;} +.thumbnails:after{clear:both;} +.row-fluid .thumbnails{margin-left:0;} +.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;} +.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;color:#555555;} +.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert h4{margin:0;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);} +.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);} +.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);} +.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);} +.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit li{line-height:30px;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-3px;} +.tooltip.right{margin-left:3px;} +.tooltip.bottom{margin-top:3px;} +.tooltip.left{margin-left:-3px;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);}.popover.top{margin-top:-10px;} +.popover.right{margin-left:10px;} +.popover.bottom{margin-top:10px;} +.popover.left{margin-left:-10px;} +.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;} +.popover-content{padding:9px 14px;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid;} +.popover .arrow:after{content:"";z-index:-1;} +.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-width:10px 10px 0;border-top-color:#ffffff;}.popover.top .arrow:after{border-width:11px 11px 0;border-top-color:rgba(0, 0, 0, 0.25);bottom:-1px;left:-11px;} +.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-width:10px 10px 10px 0;border-right-color:#ffffff;}.popover.right .arrow:after{border-width:11px 11px 11px 0;border-right-color:rgba(0, 0, 0, 0.25);bottom:-11px;left:-1px;} +.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-width:0 10px 10px;border-bottom-color:#ffffff;}.popover.bottom .arrow:after{border-width:0 11px 11px;border-bottom-color:rgba(0, 0, 0, 0.25);top:-1px;left:-11px;} +.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-width:10px 0 10px 10px;border-left-color:#ffffff;}.popover.left .arrow:after{border-width:11px 0 11px 11px;border-left-color:rgba(0, 0, 0, 0.25);bottom:-11px;right:-1px;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-header h3{margin:0;line-height:30px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.modal-footer .btn-block+.btn-block{margin-left:0;} +.dropup,.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#ffffff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#333333;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999999;} +.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;cursor:default;} +.open{*z-index:1000;}.open >.dropdown-menu{display:block;} +.pull-right>.dropdown-menu{right:0;left:auto;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.dropdown-submenu{position:relative;} +.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;} +.dropdown-submenu:hover>.dropdown-menu{display:block;} +.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;} +.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;} +.dropdown-submenu:hover>a:after{border-left-color:#ffffff;} +.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion{margin-bottom:20px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-toggle{cursor:pointer;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:20px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;} +.carousel-caption h4{margin:0 0 5px;} +.carousel-caption p{margin-bottom:0;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);} +button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} +.affix{position:fixed;} +.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;} +.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;} +.hidden{display:none;visibility:hidden;} +.visible-phone{display:none !important;} +.visible-tablet{display:none !important;} +.hidden-desktop{display:none !important;} +.visible-desktop{display:inherit !important;} +@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*="offset"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12, textarea.span12, .uneditable-input.span12{width:710px;} input.span11, textarea.span11, .uneditable-input.span11{width:648px;} input.span10, textarea.span10, .uneditable-input.span10{width:586px;} input.span9, textarea.span9, .uneditable-input.span9{width:524px;} input.span8, textarea.span8, .uneditable-input.span8{width:462px;} input.span7, textarea.span7, .uneditable-input.span7{width:400px;} input.span6, textarea.span6, .uneditable-input.span6{width:338px;} input.span5, textarea.span5, .uneditable-input.span5{width:276px;} input.span4, textarea.span4, .uneditable-input.span4{width:214px;} input.span3, textarea.span3, .uneditable-input.span3{width:152px;} input.span2, textarea.span2, .uneditable-input.span2{width:90px;} input.span1, textarea.span1, .uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12, textarea.span12, .uneditable-input.span12{width:1156px;} input.span11, textarea.span11, .uneditable-input.span11{width:1056px;} input.span10, textarea.span10, .uneditable-input.span10{width:956px;} input.span9, textarea.span9, .uneditable-input.span9{width:856px;} input.span8, textarea.span8, .uneditable-input.span8{width:756px;} input.span7, textarea.span7, .uneditable-input.span7{width:656px;} input.span6, textarea.span6, .uneditable-input.span6{width:556px;} input.span5, textarea.span5, .uneditable-input.span5{width:456px;} input.span4, textarea.span4, .uneditable-input.span4{width:356px;} input.span3, textarea.span3, .uneditable-input.span3{width:256px;} input.span2, textarea.span2, .uneditable-input.span2{width:156px;} input.span1, textarea.span1, .uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}} diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css new file mode 100644 index 00000000..ff005b50 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css @@ -0,0 +1,29 @@ +/*! + * d3.geomap + * https://github.com/yaph/d3-geomap/blob/master/LICENSE + * MIT licensed + * Copyright (C) 2015 by Ramiro Gómez (http://ramiro.org/) + */ +text { + fill: #333; + font-size: 12px; } + +.background { + fill: none; + pointer-events: all; } + +.unit { + cursor: pointer; + fill: #ccc; + stroke: #000; + stroke-width: 0.4px; } + +.legend-bg { + fill: #fff; + fill-opacity: 0.8; } + +.legend-bar { + stroke: #333; + stroke-width: 1px; } + +/*# sourceMappingURL=geomap.css.map */ diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css new file mode 100644 index 00000000..0fa42f15 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css @@ -0,0 +1,80 @@ +#rect { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 2; +} + +#rectCurve { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 0.5; +} + +.axis path, +.axis line { + fill: none; + shape-rendering: crispEdges; + stroke: grey; + stroke-width: 2; +} + +.line { + fill: none; + stroke: steelblue; + stroke-width: 1.5px; +} + + +.label{ + font-size: 16.844px !important; +} + +/* arc tween shit*/ +.background { + fill: #FFFFFF; + fill-opacity: 0.01; +} + +.component { + fill: #e1e1e1; +} + +.component .label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.arc { + stroke-weight:0.1; + fill: #4e8fff; +} + + +.arc2 { + stroke-weight:0.1; + fill: #3660b0; +} + + +.label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; +} + +.labelArc { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.tooltipClass { + background-color: #e5f2ff; + padding: 4px 8px; + +} +.tooltipClass p{ + margin: 0; + padding: 0; + +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json new file mode 100644 index 00000000..958b9364 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "TemperatureChart", + "title": "TemperatureChart", + "type": "gadget", + "thumbnail": "local://images/gadgetIcon.png", + "data": { + "url": "local://store/carbon.super/gadget/TemperatureChart/index.xml" + } +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml new file mode 100644 index 00000000..9cc11d51 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + Bar Chart + + + + + + + + + + + + + + + + + +
+ + + + ]]> +
+
+ + diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js new file mode 100644 index 00000000..b7d10b77 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License./ + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function getPieMark(a,b){var c;if("donut"==a.mode)var c=a.width/5;else var c=0;var d={type:"arc",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},startAngle:{field:"layout_start"},endAngle:{field:"layout_end"},innerRadius:{value:c},outerRadius:{value:.4*a.width},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.8}}}};return d}function getPieText(a,b){var c={type:"text",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:.5*a.width},theta:{field:"layout_mid"},fill:{value:"#000"},align:{value:"center"},baseline:{value:"middle"},text:{field:b.names[a.x],mult:.5}}}};return c}function getAreaMark(a,b){var c={type:"area",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},strokeWidth:{value:2},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getBarMark(a,b){var c={type:"rect",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:"steelblue"},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getStackBarMark(a,b){var c={type:"rect",from:{data:"table",transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:"layout_start"},y2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getLineMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"line",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"line",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{value:a.markColor},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}}function getTopoJson(a,b){var c,d=a.width,e=a.height,f=a.charts[0].mapType,g="mercator";"usa"==f?(d=a.width-160,e=a.height-130,c=a.height+270,g="albersUsa"):"europe"==f?(d=(a.width/2+100)/2,e=a.height+150,c=a.height+50):(c=a.width/640*120,d=a.width/2+10,e=a.height/2+40);var h=a.geoCodesUrl,i={name:"geoData",url:h,format:{type:"topojson",feature:"units"},transform:[{type:"geopath",value:"data",scale:c,translate:[d,e],projection:g},{type:"lookup",keys:["id"],on:a.title,onKey:b.names[a.x],as:["zipped"],"default":{v:null,country:"No data"}}]};return i}function getMapMark(a,b){var c=[{name:"map",type:"path",from:{data:"geoData"},properties:{enter:{path:{field:"layout_path"}},update:{fill:{rule:[{predicate:{name:"isNotNull",id:{field:"zipped.v"}},scale:"color",field:"zipped.v"},{value:"grey"}]}},hover:{fill:{value:"#989898"}}}},{type:"group",from:{data:a.title,transform:[{type:"filter",test:"datum."+b.names[a.x]+" == tooltipSignal.datum."+b.names[a.x]}]},properties:{update:{x:{signal:"tooltipSignal.x",offset:-5},y:{signal:"tooltipSignal.y",offset:20},width:{value:a.toolTip.width},height:{value:a.toolTip.height},fill:{value:a.toolTip.color}}},marks:[{type:"text",properties:{update:{x:{value:6},y:{value:14},text:{template:"{{tooltipSignal.datum.unitName}} {{tooltipSignal.datum.v}}"},fill:{value:"black"}}}}]}];return c}function getMapSignals(){var a=[{name:"tooltipSignal",init:{expr:"{x: 0, y: 0, datum: {} }"},streams:[{type:"@map:mouseover",expr:"{x: eventX(), y: eventY(), datum: eventItem().datum.zipped}"},{type:"@map:mouseout",expr:"{x: 0, y: 0, datum: {} }"}]}];return a}function getMapPredicates(){var a={name:"isNotNull",type:"!=",operands:[{value:null},{arg:"id"}]};return a}function getMapLegends(a,b){var c={fill:"color",title:b.names[a.y],properties:{gradient:{stroke:{value:"transparent"}},title:{fontSize:{value:14}},legend:{x:{value:0},y:{value:a.height-40}}}};return c}function loadGeoMapCodes(a){var b,c=new XMLHttpRequest;return c.overrideMimeType("application/json"),c.open("GET",a,!1),c.onreadystatechange=function(){4==c.readyState&&"200"==c.status&&(b=JSON.parse(c.responseText))},c.send(null),b}function getMapCode(a,b,c){if("world"==b||"europe"==b)for(d=0;d
"),$("#wrapper").append("
"),$tip=$("#tip"),$tip.empty();var i=g.datum,j="";for(var k in i)if(i.hasOwnProperty(k))if(void 0!=f){for(var l=0;l"+f[l]+" ("+k+"):"+i[k]+"

";break}}else e.names[d.x]==k&&(j+="

X ("+k+"):"+i[k]+"

"),e.names[d.y]==k&&(j+="

Y ("+k+"):"+i[k]+"

");$tip.append(j);var n=h.width,o=h.height,p=$('.marks[style*="width"]');p.length>0&&(n=parseFloat($(".marks")[0].style.width),o=parseFloat($(".marks")[0].style.height));var q,r=$tip.width(),s=$tip.height(),t=g.bounds.x2+d.padding.left+r,u=o-g.bounds.y2-d.padding.top+s,v=g.bounds.y2+d.padding.top-s;q=t>n?g.bounds.x2+d.padding.left-r:g.bounds.x2+d.padding.left,u>o&&(v=g.bounds.y2+d.padding.top),$tip.css({left:q,top:v}).show()}else $("#wrapper #tip").length&&$tip.remove(),$(a).closest("#wrapper").length&&$(a).unwrap()})}var arc=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title,a[0].transform=[{type:"pie",field:this.metadata.names[b.x]}];var d=[];null==b.colorDomain&&(b.colorDomain={data:b.title,field:this.metadata.names[b.color]});var e={name:"color",type:"ordinal",domain:b.colorDomain,range:b.colorScale};d.push(e),c.push(getPieMark(b,this.metadata)),c.push(getPieText(b,this.metadata));var f="Legend";"table"!=b.title&&(f=b.title);var g=[{fill:"color",title:"Legend",offset:20,properties:{symbols:{fillOpacity:{value:.5},stroke:{value:"transparent"}}}}];this.spec.legends=g,this.spec.width=b.width,this.spec.height=b.height,this.spec.data=a,this.spec.scales=d,this.spec.padding=b.padding,this.spec.marks=c};arc.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;i=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h

"+c+"

";document.getElementById(a).innerHTML=d,this.view=b},number.prototype.insert=function(a){document.getElementById(this.view).innerHTML=a[a.length-1][this.metadata.names[this.config.x]]};var scatter=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title;var d={name:"x",type:this.metadata.types[b.x],range:"width",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.x]}},e={name:"y",type:this.metadata.types[b.y],range:"height",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.y]}},f={name:"size",type:"linear",range:[0,576],domain:{data:b.title,field:this.metadata.names[b.size]}},g={name:"color",type:"linear",range:[b.minColor,b.maxColor],domain:{data:b.title,field:this.metadata.names[b.color]}},h=[d,e,f,g],i=[{type:"x",scale:"x",grid:b.grid,title:b.xTitle},{type:"y",scale:"y",grid:b.grid,title:b.yTitle}];c.push(getScatterMark(b,this.metadata)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=i,this.spec.data=a,this.spec.scales=h,this.spec.padding=b.padding,this.spec.marks=c};scatter.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),0!=this.config.tooltip&&bindTooltip(a,"symbol",this.view,this.config,this.metadata,["x","y","size"]),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(j=!0,g.splice(k,1)),j||g.splice(g.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var l,m=function(a){return a[b]==l};for(i=0;ib.maxLength){var k=d3.select("tbody").selectAll("tr").data().slice(d3.select("tbody").selectAll("tr").data().length-b.maxLength,b.maxLength);d3.select("tbody").selectAll("tr").data(k,function(a){return a}).remove()}}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/d3.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/d3.min.js new file mode 100644 index 00000000..e3ee0f91 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null===n?0/0:+n}function e(n){return!isNaN(n)}function r(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===da||n[0]===ma?ma+n:n}function l(n){return(n+="")[0]===ma?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=ya.length;r>e;++e){var u=ya[e]+t;if(u in n)return u}}function y(){}function M(){}function x(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function O(n){return xa(n,Aa),n}function Y(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var l=Ca.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++qa,t="click"+n,e=ta.select(oa).on("touchmove"+n,b).on("dragstart"+n,b).on("selectstart"+n,b);if(za){var r=ia.style,u=r[za];r[za]="none"}return function(i){if(e.on(n,null),za&&(r[za]=u),i){var o=function(){e.on(t,null)};e.on(t,function(){b(),o()},!0),setTimeout(o,0)}}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>La&&(oa.scrollX||oa.scrollY)){e=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();La=!(u.f||u.e),e.remove()}return La?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function B(){return ta.event.changedTouches[0].identifier}function W(){return ta.event.target}function J(){return oa}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Da:Math.acos(n)}function nt(n){return n>1?ja:-1>n?-ja:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):xt(""+n,bt,ot):new ot(n,t,e)}function at(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=_t((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=Fa)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):_t((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ja,r=gt(r)*Ga,i=gt(i)*Ka,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ha,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):xt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function Mt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function xt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(St(u[0]),St(u[1]),St(u[2]))}return(i=tc.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function bt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new ot(r,u,c)}function _t(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ja),u=pt((.2126729*n+.7151522*t+.072175*e)/Ga),i=pt((.0193339*n+.119192*t+.9503041*e)/Ka);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!oa.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(ic),ic=setTimeout(qt,t)),uc=0):(uc=1,ac(qt))}function Lt(){var n=Date.now();for(oc=ec;oc;)n>=oc.t&&(oc.f=oc.c(n-oc.t)),oc=oc.n;return n}function Tt(){for(var n,t=ec,e=1/0;t;)t.f?t=n?n.n=t.n:ec=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=lc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=sc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new hc(e-1)),1),e}function i(n,e){return t(n=new hc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{hc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{hc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{hc=jt;var r=new jt;return r._=t,n(r,e)._}finally{hc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in pc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{hc=jt;var t=new hc;return t._=n,r(t)}finally{hc=Date}}var r=t(n);return e.parse=function(n){try{hc=jt;var t=r.parse(n);return t&&t._}finally{hc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=It(v),b=Zt(v),_=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+fc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(fc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(fc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function It(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|va(t)/60,u=va(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){dc.lastIndex=0;var r=dc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);_c.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;wc.point=function(o,a){wc.point=n,r=(t=o)*Fa,u=Math.cos(a=(e=a)*Fa/2+Da/4),i=Math.sin(a)},wc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function be(n,t){return va(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-ja-Ta:ja-n[1])-((t=t.x)[0]<0?t[1]-ja-Ta:ja-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Da:-Da,c=va(i-e);va(c-Da)0?ja:-ja),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Da&&(va(e-u)Ta?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*ja,r.point(-Da,u),r.point(0,u),r.point(Da,u),r.point(Da,0),r.point(Da,-u),r.point(0,-u),r.point(-Da,-u),r.point(-Da,0),r.point(-Da,u);else if(va(n[0]-t[0])>Ta){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Da/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Da/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>Da,k=p*M;if(_c.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Pa:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*nt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ta>i||Ta>i&&0>_c)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Da:-Da),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ta,p[1]+=Ta,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=va(A-Da)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(va(b[0]-w)Da^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:Da-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=va(i)>Ta,c=gr(n,6*Fa);return Le(t,e,c,o?[0,-n]:[-Da,n-Da])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ye(n,t,e,r){function u(r,u){return va(r[0]-n)0?0:3:va(r[0]-e)0?2:1:va(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Uc,Math.min(Uc,n)),t=Math.max(-Uc,Math.min(Uc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ie(n){var t=0,e=Da/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Da/180,e=n[1]*Da/180):[180*(t/Da),180*(e/Da)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Fc+=u*n-r*t,r=n,u=t}var t,e,r,u;Zc.point=function(i,o){Zc.point=n,t=r=i,e=u=o},Zc.lineEnd=function(){n(t,e)}}function Xe(n,t){Hc>n&&(Hc=n),n>Yc&&(Yc=n),Oc>t&&(Oc=t),t>Ic&&(Ic=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){Ec+=n,Ac+=t,++Nc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Cc+=o*(t+n)/2,zc+=o*(e+r)/2,qc+=o,We(t=n,e=r)}var t,e;Xc.point=function(r,u){Xc.point=n,We(t=r,e=u)}}function Ge(){Xc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Cc+=o*(r+n)/2,zc+=o*(u+t)/2,qc+=o,o=u*n-r*t,Lc+=o*(r+n),Tc+=o*(u+t),Rc+=3*o,We(r=n,u=t)}var t,e,r,u;Xc.point=function(i,o){Xc.point=n,We(t=r=i,e=u=o)},Xc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Pa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=va(va(w)-1)i||va((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Fa),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ha,e*Ha])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Fa,n[1]*Fa),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ha,n[1]*Ha]}function r(){a=Ae(o=lr(m,y,M),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,M=0,x=Pc,b=Et,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(x(o,f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Pc):He((_=+n)*Fa),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?Ye(n[0][0],n[0][1],n[1][0],n[1][1]):Et,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Fa,d=n[1]%360*Fa,r()):[v*Ha,d*Ha]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Fa,y=n[1]%360*Fa,M=n.length>2?n[2]%360*Fa:0,r()):[m*Ha,y*Ha,M*Ha]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Fa,e*Fa)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Da?n-Pa:-Da>n?n+Pa:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Da?t-Pa:-Da>t?t+Pa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Pa)):(u=n+o*Pa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ta)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ha,Math.atan2(o,Math.sqrt(r*r+u*u))*Ha]}:function(){return[n*Ha,t*Ha]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Fa),o=Math.cos(u),a=va((n*=Fa)-t),c=Math.cos(a);$c+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Bc.point=function(u,i){t=u*Fa,e=Math.sin(i*=Fa),r=Math.cos(i),Bc.point=n},Bc.lineEnd=function(){Bc.point=Bc.lineEnd=y}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-ja+Ta>t&&(t=-ja+Ta):t>ja-Ta&&(t=ja-Ta);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Da/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-ja]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return va(u)u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=ol.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),rl.remove(n),ol.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&va(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=rl._;a;)if(r=Fr(a,o)-i,r>Ta)a=a.L;else{if(u=i-Hr(a,o),!(u>Ta)){r>-Ta?(t=a.P,e=a):u>-Ta?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(rl.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),rl.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=el,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(va(r-t)>Ta||va(u-e)>Ta)&&(a.splice(o,0,new Qr(Gr(i.site,s,va(r-f)Ta?{x:f,y:va(t-f)Ta?{x:va(e-p)Ta?{x:h,y:va(t-h)Ta?{x:va(e-g)=-Ra)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=al.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=il._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi||f>o||r>h||u>g)){if(p=n.point){var p,v=t-p[0],d=e-p[1],m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+Mt(Math.round(e+i*n))+Mt(Math.round(r+o*n))+Mt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=ll.lastIndex=sl.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=ll.exec(n))&&(r=sl.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=sl.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*ja)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Pa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Pa/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return at(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ft(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:bl}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Yu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Yi(n,t,e,r)},u()}function Ii(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=lc.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(va(r[0]),va(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in _l?Math.abs(e-Bi(Math.max(va(t[0]),va(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:Sl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return wl;arguments.length<2?t=wl:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Ii(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Ii(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++on?[0/0,0/0]:[n>0?a[n-1]:r[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,c)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=oc,v=[];return p.t=g+c,u>=g?a(u-g):(p.c=a,void 0)},0,c)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Wl,u);return i==Wl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Wl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Ii(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.3"};Date.now||(Date.now=function(){return+new Date});var ea=[].slice,ra=function(n){return ea.call(n)},ua=document,ia=ua.documentElement,oa=window;try{ra(ia.childNodes)[0].nodeType}catch(aa){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{ua.createElement("div").style.setProperty("opacity",0,"")}catch(ca){var la=oa.Element.prototype,sa=la.setAttribute,fa=la.setAttributeNS,ha=oa.CSSStyleDeclaration.prototype,ga=ha.setProperty;la.setAttribute=function(n,t){sa.call(this,n,t+"")},la.setAttributeNS=function(n,t,e){fa.call(this,n,t,e+"")},ha.setProperty=function(n,t,e){ga.call(this,n,t+"",e)}}ta.ascending=n,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var pa=r(n);ta.bisectLeft=pa.left,ta.bisect=ta.bisectRight=pa.right,ta.bisector=function(t){return r(1===t.length?function(e,r){return n(t(e),r)}:t)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=0|Math.random()*i--,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,u),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var va=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,u=[],o=i(va(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(Ma,"\\$&")};var Ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,xa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ba=function(n,t){return t.querySelector(n)},_a=function(n,t){return t.querySelectorAll(n)},wa=ia.matches||ia[m(ia,"matchesSelector")],Sa=function(n,t){return wa.call(n,t)};"function"==typeof Sizzle&&(ba=function(n,t){return Sizzle(n,t)[0]||null},_a=Sizzle,Sa=Sizzle.matchesSelector),ta.selection=function(){return Na};var ka=ta.selection.prototype=[];ka.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),Ea.hasOwnProperty(e)?{space:Ea[e],local:n}:n}},ka.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ka.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(T(e,n[e],t));return this}if(2>r)return oa.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(T(n,t,e))},ka.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ka.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},ka.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},ka.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ka.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ka.remove=function(){return this.each(P)},ka.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++rr;++r)p[r]=U(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return S(u)},ka.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},ka.sort=function(n){n=F.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},ka.size=function(){var n=0;return H(this,function(){++n}),n};var Aa=[];ta.selection.enter=O,ta.selection.enter.prototype=Aa,Aa.append=ka.append,Aa.empty=ka.empty,Aa.node=ka.node,Aa.call=ka.call,Aa.size=ka.size,Aa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var Ca=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ca.forEach(function(n){"on"+n in ua&&Ca.remove(n)});var za="onselectstart"in ua?null:m(ia.style,"userSelect"),qa=0;ta.mouse=function(n){return $(n,_())};var La=/WebKit/.test(oa.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=_().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(u()).on(i+d,a).on(o+d,c),y=X(),M=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,ta.mouse,J,"mousemove","mouseup"),i=t(B,ta.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},ta.rebind(n,e,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=_().touches),t?ra(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ta=1e-6,Ra=Ta*Ta,Da=Math.PI,Pa=2*Da,Ua=Pa-Ta,ja=Da/2,Fa=Da/180,Ha=180/Da,Oa=Math.SQRT2,Ya=2,Ia=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ya*h)*(e*rt(Oa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(Oa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Oa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Ia*f)/(2*i*Ya*h),p=(c*c-i*i-Ia*f)/(2*c*Ya*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Oa;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(z,s).on(Xa+".zoom",h).on("dblclick.zoom",g).on(T,f)}function t(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function e(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function r(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=e(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function i(t,e,i,o){t.__chart__={x:k.x,y:k.y,k:k.k},r(Math.pow(2,o)),u(v=e,i),t=ta.select(t),N>0&&(t=t.transition().duration(N)),t.call(n.event)}function o(){x&&x.domain(M.range().map(function(n){return(n-k.x)/k.k}).map(M.invert)),S&&S.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function a(n){C++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function l(n){--C||n({type:"zoomend"}),v=null}function s(){function n(){s=1,u(ta.mouse(r),h),c(o)}function e(){f.on(q,null).on(L,null),g(s&&ta.event.target===i),l(o)}var r=this,i=ta.event.target,o=R.of(r,arguments),s=0,f=ta.select(oa).on(q,n).on(L,e),h=t(ta.mouse(r)),g=X();Fl.call(r),a(o)}function f(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=t(n))}),n}function e(){var t=ta.event.target;ta.select(t).on(x,o).on(_,h),w.push(t);for(var e=ta.event.changedTouches,r=0,u=e.length;u>r;++r)d[e[r].identifier]=null;var a=n(),c=Date.now();if(1===a.length){if(500>c-y){var l=a[0];i(p,l,d[l.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),b()}y=c}else if(a.length>1){var l=a[0],s=a[1],f=l[0]-s[0],g=l[1]-s[1];m=f*f+g*g}}function o(){var n,t,e,i,o=ta.touches(p);Fl.call(p);for(var a=0,l=o.length;l>a;++a,i=null)if(e=o[a],i=d[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}y=null,u(n,t),c(v)}function h(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(w).on(M,null),S.on(z,s).on(T,f),E(),l(v)}var g,p=this,v=R.of(p,arguments),d={},m=0,M=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+M,_="touchend"+M,w=[],S=ta.select(p),E=X();e(),a(v),S.on(z,null).on(T,e)}function h(){var n=R.of(this,arguments);m?clearTimeout(m):(p=t(v=d||ta.mouse(this)),Fl.call(this),a(n)),m=setTimeout(function(){m=null,l(n)},50),b(),r(Math.pow(2,.002*Za())*k.k),u(v,p),c(n)}function g(){var n=ta.mouse(this),e=Math.log(k.k)/Math.LN2;i(this,n,t(n),ta.event.shiftKey?Math.ceil(e)-1:Math.floor(e)+1)}var p,v,d,m,y,M,x,_,S,k={x:0,y:0,k:1},E=[960,500],A=Va,N=250,C=0,z="mousedown.zoom",q="mousemove.zoom",L="mouseup.zoom",T="touchstart.zoom",R=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=R.of(this,arguments),t=k;Ul?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},a(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=v?v[0]:e/2,i=v?v[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){l(n)}).each("end.zoom",function(){l(n)}):(this.__chart__=k,a(n),c(n),l(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Va:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(d=t&&[+t[0],+t[1]],n):d},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(N=+t,n):N},n.x=function(t){return arguments.length?(x=t,M=t.copy(),k={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(S=t,_=t.copy(),k={x:0,y:0,k:1},n):S},ta.rebind(n,R,"on")};var Za,Va=[0,1/0],Xa="onwheel"in ua?(Za=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Za=function(){return ta.event.wheelDelta},"mousewheel"):(Za=function(){return-ta.event.detail},"MozMousePixelScroll");ta.color=it,it.prototype.toString=function(){return this.rgb()+""},ta.hsl=ot;var $a=ot.prototype=new it;$a.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},$a.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},$a.rgb=function(){return at(this.h,this.s,this.l)},ta.hcl=ct;var Ba=ct.prototype=new it;Ba.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Wa*(arguments.length?n:1)))},Ba.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Wa*(arguments.length?n:1)))},Ba.rgb=function(){return lt(this.h,this.c,this.l).rgb()},ta.lab=st;var Wa=18,Ja=.95047,Ga=1,Ka=1.08883,Qa=st.prototype=new it;Qa.brighter=function(n){return new st(Math.min(100,this.l+Wa*(arguments.length?n:1)),this.a,this.b)},Qa.darker=function(n){return new st(Math.max(0,this.l-Wa*(arguments.length?n:1)),this.a,this.b)},Qa.rgb=function(){return ft(this.l,this.a,this.b)},ta.rgb=dt;var nc=dt.prototype=new it;nc.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},nc.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},nc.hsl=function(){return bt(this.r,this.g,this.b)},nc.toString=function(){return"#"+Mt(this.r)+Mt(this.g)+Mt(this.b)};var tc=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});tc.forEach(function(n,t){tc.set(n,mt(t))}),ta.functor=kt,ta.xhr=At(Et),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new v,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var ec,rc,uc,ic,oc,ac=oa[m(oa,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};rc?rc.n=i:ec=i,rc=i,uc||(ic=clearTimeout(ic),uc=1,ac(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var cc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),cc[8+e/3]};var lc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,sc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),fc=ta.time={},hc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){gc.setUTCDate.apply(this._,arguments)},setDay:function(){gc.setUTCDay.apply(this._,arguments)},setFullYear:function(){gc.setUTCFullYear.apply(this._,arguments)},setHours:function(){gc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){gc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){gc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){gc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){gc.setUTCSeconds.apply(this._,arguments)},setTime:function(){gc.setTime.apply(this._,arguments)}};var gc=Date.prototype;fc.year=Ft(function(n){return n=fc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),fc.years=fc.year.range,fc.years.utc=fc.year.utc.range,fc.day=Ft(function(n){var t=new hc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),fc.days=fc.day.range,fc.days.utc=fc.day.utc.range,fc.dayOfYear=function(n){var t=fc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=fc[n]=Ft(function(n){return(n=fc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});fc[n+"s"]=e.range,fc[n+"s"].utc=e.utc.range,fc[n+"OfYear"]=function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)}}),fc.week=fc.sunday,fc.weeks=fc.sunday.range,fc.weeks.utc=fc.sunday.utc.range,fc.weekOfYear=fc.sundayOfYear;var pc={"-":"",_:" ",0:"0"},vc=/^\s*\d+/,dc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var mc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=mc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,yc),le(yc.s,this.s,this),this.s?this.t+=yc.t:this.s=yc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var yc=new ce;ta.geo.stream=function(n,t){n&&Mc.hasOwnProperty(n.type)?Mc[n.type](n,t):se(n,t)};var Mc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Da+n:n,wc.lineStart=wc.lineEnd=wc.point=y}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Fa,e*Fa]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ha*l,d=va(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ha;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ha;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=va(r)>180?r+(r>0?360:-360):r}else v=n,d=e;wc.point(n,e),t(n,e)}function i(){wc.lineStart()}function o(){u(v,d),wc.lineEnd(),va(y)>Ta&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n_c?(s=-(h=180),f=-(g=90)):y>Ta?g=90:-Ta>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){Sc=kc=Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,Dc);var t=Lc,e=Tc,r=Rc,u=t*t+e*e+r*r;return Ra>u&&(t=Cc,e=zc,r=qc,Ta>kc&&(t=Ec,e=Ac,r=Nc),u=t*t+e*e+r*r,Ra>u)?[0/0,0/0]:[Math.atan2(e,t)*Ha,nt(r/Math.sqrt(u))*Ha]};var Sc,kc,Ec,Ac,Nc,Cc,zc,qc,Lc,Tc,Rc,Dc={sphere:y,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){Dc.lineStart=Ee},polygonEnd:function(){Dc.lineStart=Se}},Pc=Le(Ne,Pe,je,[-Da,-Da/2]),Uc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ye(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ta,f+.12*l+Ta],[s-.214*l-Ta,f+.234*l-Ta]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ta,f+.166*l+Ta],[s-.115*l-Ta,f+.234*l-Ta]]).stream(c).point,n},n.scale(1070)};var jc,Fc,Hc,Oc,Yc,Ic,Zc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Fc=0,Zc.lineStart=Ve},polygonEnd:function(){Zc.lineStart=Zc.lineEnd=Zc.point=y,jc+=va(Fc/2)}},Vc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},Xc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Xc.lineStart=Ke},polygonEnd:function(){Xc.point=We,Xc.lineStart=Je,Xc.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return jc=0,ta.geo.stream(n,u(Zc)),jc},n.centroid=function(n){return Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,u(Xc)),Rc?[Lc/Rc,Tc/Rc]:qc?[Cc/qc,zc/qc]:Nc?[Ec/Nc,Ac/Nc]:[0/0,0/0]},n.bounds=function(n){return Yc=Ic=-(Hc=Oc=1/0),ta.geo.stream(n,u(Vc)),[[Hc,Oc],[Yc,Ic]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t}return n=lr(n[0]%360*Fa,n[1]*Fa,n.length>2?n[2]*Fa:0),t.invert=function(t){return t=n.invert(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Fa,-n[1]*Fa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ha,n[1]*=Ha}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Fa,u*Fa),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Fa,(u=+r)*Fa),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Fa,u=n[1]*Fa,i=t[1]*Fa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return va(n%d)>Ta}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return va(n%m)>Ta}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ta],[180,90-Ta]]).minorExtent([[-180,-80-Ta],[180,80+Ta]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Fa,n[1]*Fa,t[0]*Fa,t[1]*Fa)},ta.geo.length=function(n){return $c=0,ta.geo.stream(n,Bc),$c};var $c,Bc={sphere:y,point:y,lineStart:xr,lineEnd:y,polygonStart:y,polygonEnd:y},Wc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Wc)}).raw=Wc;var Jc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(ta.geo.azimuthalEquidistant=function(){return ur(Jc)}).raw=Jc,(ta.geo.conicConformal=function(){return Ie(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Gc=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur(Gc)}).raw=Gc,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-ja]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Kc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Kc)}).raw=Kc;var Qc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Qc)}).raw=Qc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-ja]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ta)*Ta,y:Math.round(o(n,t)/Ta)*Ta,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=cl;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=kt(a),x=kt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=hl.get(e)||fl,r=gl.get(r)||Et,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:pl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var pl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=vl,h=dl,g=-30,p=ml,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,M,x,b=m.length,_=y.length;for(e=0;_>e;++e)a=y[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(p=M*M+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,M*=p,x*=p,h.x-=M*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=M*(d=1-d),f.y+=x*d);if((d=r*v)&&(M=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;l>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(Et).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?(this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e),void 0):e},ta.rebind(a,c,"on")};var vl=20,dl=1,ml=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===yl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=yl,r=0,u=Pa,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var yl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Ml.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:xl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var Ml=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),xl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var bl={floor:Et,ceil:Et};ta.scale.linear=function(){return Yi([0,1],[0,1],mu,!1)};var _l={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var wl=ta.format(".0e"),Sl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(kl)},ta.scale.category20=function(){return ta.scale.ordinal().range(El)},ta.scale.category20b=function(){return ta.scale.ordinal().range(Al)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Nl)};var kl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),El=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),Al=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Nl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-ja,f=a.apply(this,arguments)-ja,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ua)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===Cl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=nt(d/l*Math.sin(m))),n&&(E=nt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=Da?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=Da?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),Y=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],Y[1][0],Y[1][1]),",",g," ",Y[1],"A",H,",",H," 0 0,",v," ",Y[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",Y[0])}else N.push("M",y,",",M);if(null!=S){var I=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-I,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-I,g);p===I?N.push("L",V[0],"A",I,",",I," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",I,",",I," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",I,",",I," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=Cl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.outerRadius=function(t){return arguments.length?(r=kt(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=kt(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==Cl?Cl:kt(t),n):i},n.startAngle=function(t){return arguments.length?(o=kt(t),n):o},n.endAngle=function(t){return arguments.length?(a=kt(t),n):a},n.padAngle=function(t){return arguments.length?(c=kt(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-ja;return[Math.cos(t)*n,Math.sin(t)*n]},n};var Cl="auto";ta.svg.line=function(){return ho(Et)};var zl=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});zl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var ql=[0,2/3,1/3,0],Ll=[0,1/3,2/3,0],Tl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(Et)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-ja,s=l.call(n,u,r)-ja;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Da)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(Rl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Rl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Pl)),e=t*Pl;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=Rl.keys();var Dl=Math.sqrt(3),Pl=Math.tan(30*Fa);ka.transition=function(n){for(var t,e,r=Ul||++Ol,u=Xo(n),i=[],o=jl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Io(u,this.namespace,this.id)},Hl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):H(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Hl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Hl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Hl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=oa.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=mu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Zo(this,"style."+n,t,u)},Hl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,oa.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Hl.text=function(n){return Zo(this,"text",n,Vo)},Hl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Hl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),H(this,function(r){r[e][t].ease=n}))},Hl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:H(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Hl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:H(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Hl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=jl,i=Ul;try{Ul=e,H(this,function(t,u,i){jl=t[r][e],n.call(t,t.__data__,u,i)})}finally{jl=u,Ul=i}}else H(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Hl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ol,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Io(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ta),d=ta.transition(p.exit()).style("opacity",Ta).remove(),m=ta.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,M=Ui(f),x=l.selectAll(".domain").data([0]),b=(x.enter().append("path").attr("class","domain"),ta.transition(x));v.append("line"),v.append("text");var _,w,S,k,E=v.select("line"),A=m.select("line"),N=p.select("text").text(g),C=v.select("text"),z=m.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,_="x",S="y",w="x2",k="y2",N.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),b.attr("d","M"+M[0]+","+q*i+"V0H"+M[1]+"V"+q*i)):(n=Wo,_="y",S="x",w="y2",k="x2",N.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),b.attr("d","M"+q*i+","+M[0]+"H0V"+M[1]+"H"+q*i)),E.attr(k,q*u),C.attr(S,q*y),A.attr(w,0).attr(k,q*u),z.attr(_,0).attr(S,q*y),f.rangeBand){var L=f,T=L.rangeBand()/2;s=f=function(n){return L(n)+T}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=Yl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Il?t+"":Yl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Yl="bottom",Il={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(i){i.each(function(){var i=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Zl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=ta.transition(i),h=ta.transition(o);c&&(s=Ui(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Ui(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==ta.event.keyCode&&(N||(y=null,z[0]-=s[1],z[1]-=f[1],N=2),b())}function p(){32==ta.event.keyCode&&2==N&&(z[0]+=s[1],z[1]+=f[1],N=0,b())}function v(){var n=ta.mouse(x),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),N||(ta.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),C(),w({type:"brushend"})}var y,M,x=this,_=ta.select(ta.event.target),w=a.of(x,arguments),S=ta.select(x),k=_.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,N=_.classed("extent"),C=X(),z=ta.mouse(x),q=ta.select(oa).on("keydown.brush",u).on("keyup.brush",p);if(ta.event.changedTouches?q.on("touchmove.brush",v).on("touchend.brush",m):q.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),N)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var L=+/w$/.test(k),T=+/^n/.test(k);M=[s[1-L]-z[0],f[1-T]-z[1]],z[0]=s[L],z[1]=f[T]}else ta.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Vl[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ul?ta.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(s,t.x),r=yu(f,t.y);return i=o=null,function(u){s=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Vl[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Vl[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},ta.rebind(n,a,"on")};var Zl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Vl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Xl=fc.format=mc.timeFormat,$l=Xl.utc,Bl=$l("%Y-%m-%dT%H:%M:%S.%LZ");Xl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Bl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Bl.toString,fc.second=Ft(function(n){return new hc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),fc.seconds=fc.second.range,fc.seconds.utc=fc.second.utc.range,fc.minute=Ft(function(n){return new hc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),fc.minutes=fc.minute.range,fc.minutes.utc=fc.minute.utc.range,fc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new hc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),fc.hours=fc.hour.range,fc.hours.utc=fc.hour.utc.range,fc.month=Ft(function(n){return n=fc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),fc.months=fc.month.range,fc.months.utc=fc.month.utc.range;var Wl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Jl=[[fc.second,1],[fc.second,5],[fc.second,15],[fc.second,30],[fc.minute,1],[fc.minute,5],[fc.minute,15],[fc.minute,30],[fc.hour,1],[fc.hour,3],[fc.hour,6],[fc.hour,12],[fc.day,1],[fc.day,2],[fc.week,1],[fc.month,1],[fc.month,3],[fc.year,1]],Gl=Xl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Kl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:Et,ceil:Et};Jl.year=fc.year,fc.scale=function(){return Go(ta.scale.linear(),Jl,Gl)};var Ql=Jl.map(function(n){return[n[0].utc,n[1]]}),ns=$l.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Ql.year=fc.year.utc,fc.scale.utc=function(){return Go(ta.scale.linear(),Ql,ns)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js new file mode 100644 index 00000000..2a5250fb --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js @@ -0,0 +1,48 @@ +if(navigator.appVersion.indexOf("MSIE")!=-1&&parseFloat(navigator.appVersion.split("MSIE")[1])<=8&&!document.createElement("canvas").getContext)(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var abs=m.abs;var sqrt=m.sqrt;var Z=10;var Z2=Z/2;var IE_VERSION=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function getContext(){return this.context_||(this.context_=new CanvasRenderingContext2D_(this))}var slice=Array.prototype.slice;function bind(f,obj,var_args){var a=slice.call(arguments, +2);return function(){return f.apply(obj,a.concat(slice.call(arguments)))}}function encodeHtmlAttribute(s){return String(s).replace(/&/g,"&").replace(/"/g,""")}function addNamespace(doc,prefix,urn){if(!doc.namespaces[prefix])doc.namespaces.add(prefix,urn,"#default#VML")}function addNamespacesAndStylesheet(doc){addNamespace(doc,"g_vml_","urn:schemas-microsoft-com:vml");addNamespace(doc,"g_o_","urn:schemas-microsoft-com:office:office");if(!doc.styleSheets["ex_canvas_"]){var ss=doc.createStyleSheet(); +ss.owningElement.id="ex_canvas_";ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"}}addNamespacesAndStylesheet(document);var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;doc.createElement("canvas");doc.attachEvent("onreadystatechange",bind(this.init_,this,doc))},init_:function(doc){var els=doc.getElementsByTagName("canvas");for(var i=0;i1)h--;if(6*h<1)return m1+(m2-m1)*6*h;else if(2*h<1)return m2;else if(3*h<2)return m1+(m2-m1)*(2/3-h)*6;else return m1}var processStyleCache={};function processStyle(styleString){if(styleString in processStyleCache)return processStyleCache[styleString];var str,alpha=1;styleString=String(styleString);if(styleString.charAt(0)=="#")str=styleString;else if(/^rgb/.test(styleString)){var parts= +getRgbHslContent(styleString);var str="#",n;for(var i=0;i<3;i++){if(parts[i].indexOf("%")!=-1)n=Math.floor(percent(parts[i])*255);else n=+parts[i];str+=decToHex[clamp(n,0,255)]}alpha=+parts[3]}else if(/^hsl/.test(styleString)){var parts=getRgbHslContent(styleString);str=hslToRgb(parts);alpha=parts[3]}else str=colorData[styleString]||styleString;return processStyleCache[styleString]={color:str,alpha:alpha}}var DEFAULT_STYLE={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"}; +var fontStyleCache={};function processFontStyle(styleString){if(fontStyleCache[styleString])return fontStyleCache[styleString];var el=document.createElement("div");var style=el.style;try{style.font=styleString}catch(ex){}return fontStyleCache[styleString]={style:style.fontStyle||DEFAULT_STYLE.style,variant:style.fontVariant||DEFAULT_STYLE.variant,weight:style.fontWeight||DEFAULT_STYLE.weight,size:style.fontSize||DEFAULT_STYLE.size,family:style.fontFamily||DEFAULT_STYLE.family}}function getComputedStyle(style, +element){var computedStyle={};for(var p in style)computedStyle[p]=style[p];var canvasFontSize=parseFloat(element.currentStyle.fontSize),fontSize=parseFloat(style.size);if(typeof style.size=="number")computedStyle.size=style.size;else if(style.size.indexOf("px")!=-1)computedStyle.size=fontSize;else if(style.size.indexOf("em")!=-1)computedStyle.size=canvasFontSize*fontSize;else if(style.size.indexOf("%")!=-1)computedStyle.size=canvasFontSize/100*fontSize;else if(style.size.indexOf("pt")!=-1)computedStyle.size= +fontSize/0.75;else computedStyle.size=canvasFontSize;computedStyle.size*=0.981;return computedStyle}function buildStyle(style){return style.style+" "+style.variant+" "+style.weight+" "+style.size+"px "+style.family}var lineCapMap={"butt":"flat","round":"round"};function processLineCap(lineCap){return lineCapMap[lineCap]||"square"}function CanvasRenderingContext2D_(canvasElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle= +"#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=canvasElement;var cssText="width:"+canvasElement.clientWidth+"px;height:"+canvasElement.clientHeight+"px;overflow:hidden;position:absolute";var el=canvasElement.ownerDocument.createElement("div");el.style.cssText=cssText;canvasElement.appendChild(el);var overlayEl=el.cloneNode(false);overlayEl.style.backgroundColor= +"red";overlayEl.style.filter="alpha(opacity=0)";canvasElement.appendChild(overlayEl);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"moveTo", +x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.lineTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"lineTo",x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){var p=getCoords(this,aX,aY);var cp1=getCoords(this,aCP1x,aCP1y);var cp2=getCoords(this,aCP2x,aCP2y);bezierCurveTo(this,cp1,cp2,p)};function bezierCurveTo(self,cp1,cp2,p){self.currentPath_.push({type:"bezierCurveTo",cp1x:cp1.x, +cp1y:cp1.y,cp2x:cp2.x,cp2y:cp2.y,x:p.x,y:p.y});self.currentX_=p.x;self.currentY_=p.y}contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp=getCoords(this,aCPx,aCPy);var p=getCoords(this,aX,aY);var cp1={x:this.currentX_+2/3*(cp.x-this.currentX_),y:this.currentY_+2/3*(cp.y-this.currentY_)};var cp2={x:cp1.x+(p.x-this.currentX_)/3,y:cp1.y+(p.y-this.currentY_)/3};bezierCurveTo(this,cp1,cp2,p)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType= +aClockwise?"at":"wa";var xStart=aX+mc(aStartAngle)*aRadius-Z2;var yStart=aY+ms(aStartAngle)*aRadius-Z2;var xEnd=aX+mc(aEndAngle)*aRadius-Z2;var yEnd=aY+ms(aEndAngle)*aRadius-Z2;if(xStart==xEnd&&!aClockwise)xStart+=0.125;var p=getCoords(this,aX,aY);var pStart=getCoords(this,xStart,yStart);var pEnd=getCoords(this,xEnd,yEnd);this.currentPath_.push({type:arcType,x:p.x,y:p.y,radius:aRadius,xStart:pStart.x,yStart:pStart.y,xEnd:pEnd.x,yEnd:pEnd.y})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX, +aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke();this.currentPath_=oldPath};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY); +this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill();this.currentPath_=oldPath};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");gradient.x0_=aX0;gradient.y0_=aY0;gradient.x1_=aX1;gradient.y1_=aY1;return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.x0_=aX0;gradient.y0_=aY0;gradient.r0_= +aR0;gradient.x1_=aX1;gradient.y1_=aY1;gradient.r1_=aR1;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width="auto";image.runtimeStyle.height="auto";var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w; +sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else throw Error("Invalid number of arguments");var d=getCoords(this,dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var W= +10;var H=10;var chunkSize=5E3;var min={x:null,y:null};var max={x:null,y:null};for(var j=0;jmax.x)max.x=p.x;if(min.y==null||p.ymax.y)max.y=p.y}}lineStr.push(' ">');if(!aFill)appendStroke(this,lineStr);else appendFill(this,lineStr,min,max);lineStr.push("");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))}};function appendStroke(ctx, +lineStr){var a=processStyle(ctx.strokeStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;var lineWidth=ctx.lineScale_*ctx.lineWidth;if(lineWidth<1)opacity*=lineWidth;lineStr.push("')}function appendFill(ctx,lineStr,min,max){var fillStyle=ctx.fillStyle;var arcScaleX=ctx.arcScaleX_;var arcScaleY= +ctx.arcScaleY_;var width=max.x-min.x;var height=max.y-min.y;if(fillStyle instanceof CanvasGradient_){var angle=0;var focus={x:0,y:0};var shift=0;var expansion=1;if(fillStyle.type_=="gradient"){var x0=fillStyle.x0_/arcScaleX;var y0=fillStyle.y0_/arcScaleY;var x1=fillStyle.x1_/arcScaleX;var y1=fillStyle.y1_/arcScaleY;var p0=getCoords(ctx,x0,y0);var p1=getCoords(ctx,x1,y1);var dx=p1.x-p0.x;var dy=p1.y-p0.y;angle=Math.atan2(dx,dy)*180/Math.PI;if(angle<0)angle+=360;if(angle<1E-6)angle=0}else{var p0=getCoords(ctx, +fillStyle.x0_,fillStyle.y0_);focus={x:(p0.x-min.x)/width,y:(p0.y-min.y)/height};width/=arcScaleX*Z;height/=arcScaleY*Z;var dimension=m.max(width,height);shift=2*fillStyle.r0_/dimension;expansion=2*fillStyle.r1_/dimension-shift}var stops=fillStyle.colors_;stops.sort(function(cs1,cs2){return cs1.offset-cs2.offset});var length=stops.length;var color1=stops[0].color;var color2=stops[length-1].color;var opacity1=stops[0].alpha*ctx.globalAlpha;var opacity2=stops[length-1].alpha*ctx.globalAlpha;var colors= +[];for(var i=0;i')}else if(fillStyle instanceof CanvasPattern_){if(width&&height){var deltaLeft=-min.x;var deltaTop=-min.y;lineStr.push("')}}else{var a=processStyle(ctx.fillStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;lineStr.push('')}}contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};function getCoords(ctx,aX,aY){var m=ctx.m_;return{x:Z*(aX*m[0][0]+ +aY*m[1][0]+m[2][0])-Z2,y:Z*(aX*m[0][1]+aY*m[1][1]+m[2][1])-Z2}}contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){if(this.aStack_.length){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function matrixIsFinite(m){return isFinite(m[0][0])&&isFinite(m[0][1])&&isFinite(m[1][0])&&isFinite(m[1][1])&&isFinite(m[2][0])&&isFinite(m[2][1])}function setM(ctx, +m,updateLineScale){if(!matrixIsFinite(m))return;ctx.m_=m;if(updateLineScale){var det=m[0][0]*m[1][1]-m[0][1]*m[1][0];ctx.lineScale_=sqrt(abs(det))}}contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1= +[[aX,0,0],[0,aY,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.transform=function(m11,m12,m21,m22,dx,dy){var m1=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.setTransform=function(m11,m12,m21,m22,dx,dy){var m=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,m,true)};contextPrototype.drawText_=function(text,x,y,maxWidth,stroke){var m=this.m_,delta=1E3,left=0,right=delta,offset={x:0,y:0},lineStr=[];var fontStyle=getComputedStyle(processFontStyle(this.font), +this.element_);var fontStyleString=buildStyle(fontStyle);var elementStyle=this.element_.currentStyle;var textAlign=this.textAlign.toLowerCase();switch(textAlign){case "left":case "center":case "right":break;case "end":textAlign=elementStyle.direction=="ltr"?"right":"left";break;case "start":textAlign=elementStyle.direction=="rtl"?"right":"left";break;default:textAlign="left"}switch(this.textBaseline){case "hanging":case "top":offset.y=fontStyle.size/1.75;break;case "middle":break;default:case null:case "alphabetic":case "ideographic":case "bottom":offset.y= +-fontStyle.size/2.25;break}switch(textAlign){case "right":left=delta;right=0.05;break;case "center":left=right=delta/2;break}var d=getCoords(this,x+offset.x,y+offset.y);lineStr.push('');if(stroke)appendStroke(this,lineStr);else appendFill(this,lineStr,{x:-left,y:0},{x:right,y:fontStyle.size});var skewM=m[0][0].toFixed(3)+ +","+m[1][0].toFixed(3)+","+m[0][1].toFixed(3)+","+m[1][1].toFixed(3)+",0,0";var skewOffset=mr(d.x/Z)+","+mr(d.y/Z);lineStr.push('','','');this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fillText= +function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,false)};contextPrototype.strokeText=function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,true)};contextPrototype.measureText=function(text){if(!this.textMeasureEl_){var s='';this.element_.insertAdjacentHTML("beforeEnd",s);this.textMeasureEl_=this.element_.lastChild}var doc=this.element_.ownerDocument;this.textMeasureEl_.innerHTML= +"";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(doc.createTextNode(text));return{width:this.textMeasureEl_.offsetWidth}};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(image,repetition){return new CanvasPattern_(image,repetition)};function CanvasGradient_(aType){this.type_=aType;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}CanvasGradient_.prototype.addColorStop=function(aOffset, +aColor){aColor=processStyle(aColor);this.colors_.push({offset:aOffset,color:aColor.color,alpha:aColor.alpha})};function CanvasPattern_(image,repetition){assertImageIsValid(image);switch(repetition){case "repeat":case null:case "":this.repetition_="repeat";break;case "repeat-x":case "repeat-y":case "no-repeat":this.repetition_=repetition;break;default:throwException("SYNTAX_ERR")}this.src_=image.src;this.width_=image.width;this.height_=image.height}function throwException(s){throw new DOMException_(s); +}function assertImageIsValid(img){if(!img||img.nodeType!=1||img.tagName!="IMG")throwException("TYPE_MISMATCH_ERR");if(img.readyState!="complete")throwException("INVALID_STATE_ERR")}function DOMException_(s){this.code=this[s];this.message=s+": DOM Exception "+this.code}var p=DOMException_.prototype=new Error;p.INDEX_SIZE_ERR=1;p.DOMSTRING_SIZE_ERR=2;p.HIERARCHY_REQUEST_ERR=3;p.WRONG_DOCUMENT_ERR=4;p.INVALID_CHARACTER_ERR=5;p.NO_DATA_ALLOWED_ERR=6;p.NO_MODIFICATION_ALLOWED_ERR=7;p.NOT_FOUND_ERR=8;p.NOT_SUPPORTED_ERR= +9;p.INUSE_ATTRIBUTE_ERR=10;p.INVALID_STATE_ERR=11;p.SYNTAX_ERR=12;p.INVALID_MODIFICATION_ERR=13;p.NAMESPACE_ERR=14;p.INVALID_ACCESS_ERR=15;p.VALIDATION_ERR=16;p.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_;DOMException=DOMException_})(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js new file mode 100644 index 00000000..7b851f57 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js @@ -0,0 +1,22 @@ +var gadgetConfig = { + "id": "TemperatureChart", + "title": "TemperatureChart", + "datasource": "org.wso2.iot.devices.temperature:1.0.0", + "type": "realtime", + "columns": [ + {"name": "TIMESTAMP", "type": "time"}, + {"name": "owner", "type": "string"}, + {"name": "deviceType", "type": "string"}, + {"name": "deviceId", "type": "string"}, + {"name": "time", "type": "long"}, + {"name": "temperature", "type": "float"} + ], + "chartConfig": { + "x": "TIMESTAMP", + "maxLength": "10", + "padding": {"top": 30, "left": 45, "bottom": 38, "right": 55}, + "charts": [{"type": "line", "y": "temperature"}] + }, + "domain": "carbon.super", + "params": ["owner", "deviceId"] +}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js new file mode 100644 index 00000000..14ba6362 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js @@ -0,0 +1,9472 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + return jQuery.merge( this, selector ); + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.8.3", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ), + "slice", core_slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && core_rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, + ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + input.setAttribute( "checked", "checked" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea|)$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + if ( (value && typeof value === "string") || value === undefined ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( className ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + 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( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = value + "" ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + 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( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.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( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

"; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, l, length, n, r, ret, + self = this; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
", "
" ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( e ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js new file mode 100644 index 00000000..1d7bd128 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js @@ -0,0 +1,568 @@ +var datasource, type, columns, filter, maxUpdateValue, paramsToFilterBy; + +var REFRESH_INTERVAL = 5000; + +//this needs to be loaded from an autogenerated +datasource = gadgetConfig.datasource; +filter = gadgetConfig.filter; +type = gadgetConfig.type; +maxUpdateValue = gadgetConfig.maxUpdateValue; +columns = gadgetConfig.columns; +paramsToFilterBy = gadgetConfig.params; + +var counter = 0; +var TYPE_GET_BY_RANGE = 8; +var TYPE_SEARCH = 13; +var TYPE_SEARCH_COUNT = 14; + +var TIME_FROM_STRING = "timeFrom"; +var TIME_TO_STRING = "timeTo"; +var UNIX_TIME_MAX_VALUE = "9007199254740992"; +var UNIX_TIME_MIN_VALUE = "-9007199254740992"; +var META_TAG = "meta_"; +var initialConfig, urlQueryParams, queryParamValPair, queryString; +var dataTable, chart; + +executeDataFetchForGadget(); + +/** + * The main execution logic of the gadget is implemented in this function. + */ +function executeDataFetchForGadget() { + var urlQueryString; + + // fetch all queryParams from the URL. + urlQueryParams = getAllQueryParamsFromURL(); + + // check if params config exists in the gadgetConf. + if (typeof paramsToFilterBy != "undefined" && paramsToFilterBy.length != 0) { + + if (urlQueryParams != null) { + // get the values corresponding to the query "params" given in the gadgetConf + queryParamValPair = getValuesOfQueryFilter(); + + // if at-least one of the given params in the conf are missing from the URL params then returns null. + if (queryParamValPair == null) { + console.log("Incomplete set of Query Params were found in the URL."); + return; + } + + // construct the Lucene query string based on the params given in the gadget-conf + // and the values parsed from the URL Query String. + queryString = constructQueryString(); + + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe( + datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, + location.hostname, location.port, 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataOnQuery(fetchDataWithCount); + // then start periodic polling + setInterval(function () { + fetchDataOnQuery(fetchDataWithCount); + }, REFRESH_INTERVAL); + break; + } + + } else { + // if there are NO queryParams in the URL then exit. + console.log("No Query Params were found in the URL to match the given filter-parameters."); + } + } else { + // if no params to filter by are given in the gadget-conf, then fetch all info available + // based on date range(if given). + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe(datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, location.hostname, location.port, + 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataWithoutQuery(drawBatchChart); + + // then start periodic polling + setInterval(function () { + fetchDataWithoutQuery(drawBatchChart); + }, REFRESH_INTERVAL); + break; + } + } +} + +/** + * Reads the page's URL Query-Params and returns them as an associative array. + * @returns {*} an associative array containing the URL QueryParams and corresponding values. + * If no such Query-Params exists then returns null. + */ +function getAllQueryParamsFromURL() { + var queryParamList = [], qParam; + var urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + if (urlQueryString) { + var queryStringPairs = urlQueryString.split('&'); + for (var i = 0; i < queryStringPairs.length; i++) { + qParam = queryStringPairs[i].split('='); + queryParamList[qParam[0]] = qParam[1]; + } + return queryParamList; + } else { + return null; + } +} + +/** + * Retrieves the values from the URL-QueryString corresponding to the given QueryParams in the gadget-conf file. + * The parameters "timeTo" & "timeFrom" (if found in the query string) are added to the returned object regardless + * of whether they are listed in the gadget-conf. + * @returns {*} an associative array of the given params in the conf and corresponding value fetched from the + * URL string. + */ +function getValuesOfQueryFilter() { + var queryValues = []; + + if (TIME_FROM_STRING in urlQueryParams) { + queryValues[TIME_FROM_STRING] = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + queryValues[TIME_TO_STRING] = urlQueryParams[TIME_TO_STRING]; + } + + for (var i = 0; i < paramsToFilterBy.length; i++) { + var queryV = urlQueryParams[paramsToFilterBy[i]]; + + // if atleast one of the queryParams given in the gadgetConf is missing then return "null". + if (typeof queryV != "undefined" && queryV != null && queryV != "") { + queryValues[paramsToFilterBy[i]] = queryV; + } else { + return null; + } + } + return queryValues; +} + +/** + * Constructs the Lucene Query String to be sent to DAS API. + * @returns {string} a fully constructed query string from the params given in gadget-conf and + * the query string of the URL. + */ +function constructQueryString() { + var queryString = "'"; + for (var a = 0; a < paramsToFilterBy.length; a++) { + if (queryString.length == 1) { + queryString += META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } else { + queryString += " AND " + META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } + } + + if (TIME_FROM_STRING in queryParamValPair && TIME_TO_STRING in queryParamValPair) { + // both ends of the time-range (From What Date - To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + + } else if (TIME_FROM_STRING in queryParamValPair && !(TIME_TO_STRING in queryParamValPair)) { + // Only the start of the time-range (From What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + UNIX_TIME_MAX_VALUE + "]"; + + } else if (!(TIME_FROM_STRING in queryParamValPair) && TIME_TO_STRING in queryParamValPair) { + // Only the end of the time-range (To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + UNIX_TIME_MIN_VALUE + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + } + //queryString += " AND meta_time:[1456467843079 TO 1456468494817]'"; + queryString += "'"; + return queryString; +} + +/** + * Utility method to fetch columns of the datasource provided for a Batch-Type Gadget. + * @param table the name of the datasource table whose columns needs to be extracted. + */ +function getColumns(table) { + console.log("Fetching table schema for table: " + table); + var url = "/portal/apis/analytics?type=10&tableName=" + table; + $.getJSON(url, function (data) { + if (data) { + columns = parseColumns(JSON.parse(data.message)); + } + + }); +} + +/** Constructs an associative array containing the columns and the corresponding data-type ("String", "Long", etc) + * from the returned object as a result of the "getColumns" method above. + * @param data the response object returned from the "getColumns(table)" call to the DAS API. + * @returns {Array|*} an array containing the column names as keys and their type as values. + */ +function parseColumns(data) { + if (data.columns) { + var keys = Object.getOwnPropertyNames(data.columns); + columns = keys.map(function (key, i) { + return column = { + name: key, + type: data.columns[key].type + }; + }); + return columns; + } +} + +/** + * Makes the initial call to the DAS APIs to get the count of all matching indexes based on a given query. + * Upon receiving a response (count), a subsequent method is called to fetch the given "count" amount of data from + * DAS that matches the query. + * @param callback the subsequent method to be called using the "count" response value received from the API call. + */ +function fetchDataOnQuery(callback) { + var request = { + type: TYPE_SEARCH_COUNT, // DAS API type corresponding to fetching data-count for "query" + tableName: datasource, + query: queryString + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(drawBatchChart, data.message); + } + } + }); +} + +/** + * Makes an API call to the DAS to fetch the "count" number of data matching the queryString constructed from the + * query-string and the param-list provided in the gadget-conf. The fetched data are passed into the provided + * "callback" method which further processes and draws the chart against this data. + * @param callback the method to which the fetched data are to be passed in for further processing. + * @param totalCount the count of all matching data available against the queryString. + */ +function fetchDataWithCount(callback, totalCount) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + var request = { + type: TYPE_SEARCH, // DAS API type corresponding to fetching data for "query" + tableName: datasource, + filter: filter, + query: queryString, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0, + count: totalCount + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + var sortedData = sortData(data.message); + callback(makeRows(sortedData)); + } + } + }); +} + +/** + * Retrieves all data available in a datasource irrespective of any query filters. However, the API call incorporates + * a data range to be submitted whilst fetching this info. If such date range related query strings + * ("timeFrom" or "timeTo") are found in the URL, then they are used. + * @param callback the method to which the fetched data are to be passed in for further processing. + */ +function fetchDataWithoutQuery(callback) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + + if (urlQueryParams != null) { + if (TIME_FROM_STRING in urlQueryParams) { + timeFrom = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + timeTo = urlQueryParams[TIME_TO_STRING]; + } + } + + var request = { + type: TYPE_GET_BY_RANGE, // DAS API type corresponding to fetching data by date range. + tableName: datasource, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0 + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(makeRows(JSON.parse(data.message))); + } + } + }); +} + +/** + * This is a utility method to convert Unix-Timestamp values to Epoch Time + * @param unix_timestamp the unix time to be converted + * @returns {string} the formatted epoch-time of the given unix-timestamp + */ +function convertToEpoch(unix_timestamp) { + // Create a new JavaScript Date object based on the timestamp + // multiplied by 1000 so that the argument is in milliseconds, not seconds. + var date = new Date(unix_timestamp * 1000); + // Hours part from the timestamp + var hours = date.getHours(); + // Minutes part from the timestamp + var minutes = "0" + date.getMinutes(); + // Seconds part from the timestamp + var seconds = "0" + date.getSeconds(); + + var thisDate = date.getDate(); + var thisMonth = date.getMonth(); + var thisYear = date.getUTCFullYear(); + + var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2); + + // Will display time in 10:30:23 format + return (formattedTime); +} + +/** + * Sorts the given data array according to the values of its "timestamp" key. + * @param payload a JSON string with multiple data-arrays having a "timestamp" key-value pair. + * @returns {*} JSON Object with multiple sorted by "timestamp" + */ +function sortData(payload) { + var dataFromDAS = JSON.parse(payload); + sortedData = dataFromDAS.sort(function (a, b) { + return a.timestamp - b.timestamp; + }); + return sortedData; +} + +/** + * Fetches the values corresponding to the keys in the "columns" (either provided in the gadget-conf or fetched via the + * "getColumns(table)" method) array from the data object passed in. + * @param data a JSON Object containing multiple data values fetched from the datasource with column-name:value pairs. + * @returns {Array} an array with objects that contain the columns from the fetched "columns" and their corresponding + * values. + */ +function makeRows(data) { + var rows = []; + for (var i = 0; i < data.length; i++) { + var record = data[i]; + var keys = Object.getOwnPropertyNames(record.values); + keys.push(); + + var row = columns.map(function (column, i) { + var colName = column.name; + var recordVal = record.values[colName]; + + if (typeof recordVal == 'undefined') { + if (column.name.toUpperCase() === "TIMESTAMP" && (record.timestamp || record.TIMESTAMP)) { + recordVal = record.timestamp; + } else { + recordVal = record.values[META_TAG + colName]; + } + } + return recordVal; + }); + rows.push(row); + } + return rows; +} + +function makeDataTable(data) { + var dataTable = new igviz.DataTable(); + if (columns.length > 0) { + columns.forEach(function (column, i) { + var type = "N"; + if (column.type == "STRING" || column.type == "string") { + type = "C"; + } else if (column.type == "TIME" || column.type == "time") { + type = "T"; + } + dataTable.addColumn(column.name, type); + }); + } + data.forEach(function (row, index) { + for (var i = 0; i < row.length; i++) { + if (dataTable.metadata.types[i] == "N") { + data[index][i] = parseInt(data[index][i]); + } + } + }); + dataTable.addRows(data); + return dataTable; +} + +function drawChart(data) { + var dataTable = makeDataTable(data); + gadgetConfig.chartConfig.width = $("#placeholder").width(); + gadgetConfig.chartConfig.height = $("#placeholder").height() - 65; + var chartType = gadgetConfig.chartConfig.chartType; + var xAxis = gadgetConfig.chartConfig.xAxis; + jQuery("#noChart").html(""); + if (chartType === "bar" && dataTable.metadata.types[xAxis] === "N") { + dataTable.metadata.types[xAxis] = "C"; + } + + if (gadgetConfig.chartConfig.chartType === "table" || gadgetConfig.chartConfig.chartType === "singleNumber") { + gadgetConfig.chartConfig.height = $("#placeholder").height(); + chart = igviz.draw("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.plot(dataTable.data); + + } else { + chart = igviz.setUp("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.setXAxis({ + "labelAngle": -35, + "labelAlign": "right", + "labelDy": 0, + "labelDx": 0, + "titleDy": 25 + }) + .setYAxis({ + "titleDy": -30 + }); + chart.plot(dataTable.data); + } +} + + +//stuff required for realtime charting +function onRealTimeEventSuccessRecieval(streamId, data) { + drawRealtimeChart(data); +} + +function onRealTimeEventErrorRecieval(dataError) { + console.log("Error occurred " + dataError); +} + +/** + * Draws the real-time chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawRealtimeChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); + } else { + chart.insert(convertData(data)); + } +} + +/** + * Draws the batch-chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawBatchChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + + } else { + gadgetConfig.chartConfig = initialConfig; + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); +} + + +function convertData(data) { + for (var i = 0; i < data.length; i++) { + for (var x = 0; x < data[i].length; x++) { + var type = gadgetConfig.columns[x]["type"].toUpperCase(); + if (type != "STRING" && type != "BOOLEAN") { + data[i][x] = parseFloat(data[i][x]); + } + } + } + return data; +} + +function createDataTable(data) { + var names = []; + var types = []; + + for (var i = 0; i < gadgetConfig.columns.length; i++) { + var name = gadgetConfig.columns[i]["name"]; + names.push(name); + var type = columns[i]["type"].toUpperCase(); + + if (type === "INT" || type === "INTEGER" || type === "FLOAT" || type === "DOUBLE") { + type = "linear"; + } else if (gadgetConfig.columns[i]["type"].toUpperCase() == "TIME" || name.toUpperCase() == "TIME") { + type = "time"; + } else { + type = "ordinal"; + } + types.push(type); + } + + datatable = [ + { + "metadata": { + "names": names, + "types": types + }, + "data": data + } + ]; + return datatable; +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js new file mode 100644 index 00000000..2cda2727 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js @@ -0,0 +1,285 @@ +/* + * + * + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +var CONSTANTS = { + webAppName: 'outputui', + urlSeperator: '/', + urlGetParameter : '?lastUpdatedTime=', + urlQueryStringBegin : '?', + tenantUrlAttribute: 't', + urlUnsecureTransportHttp : 'http://', + urlUnsecureTransportWebsocket : 'ws://', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultUserDomain : 'carbon.super', + defaultHostName : 'localhost', + defaultNonsecurePortNumber : '9763', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + domain : 'carbon.super', + numThousand : 1000, + websocketTimeAppender : 400, + secureMode : 'SECURED' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var userDomainUrl = ""; +var terminateWebsocketInstance = false; +var pollingContinue = true; +var transportToBeUsedHttp; +var transportToBeUsedWebsocket; + +function subscribe(streamName,version,intervalTime,domain, + listeningFuncSuccessData,listeningFuncErrorData, + cepHost,cepPort,mode,secureMode, queryParams){ + + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(secureMode == CONSTANTS.secureMode){ + transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket; + } else { + transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket; + } + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(domain == null || domain == ""){ + domain = CONSTANTS.defaultUserDomain; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + if(secureMode == CONSTANTS.secureMode){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = CONSTANTS.defaultNonsecurePortNumber; + } + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + if(domain != CONSTANTS.domain){ + userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator; + + } + + if (queryParams == null) { + queryParams = ""; + } else if (queryParams != "") { + queryParams = CONSTANTS.urlQueryStringBegin + queryParams; + } + + webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream + + CONSTANTS.urlSeperator + streamVersion + queryParams; + + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + // alert("Successfully connected to "+webSocketUrl); + //onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n"); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator + + CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator + + streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime; + + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i 1) { + var geomsByArc = [], + geom; + + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } + + function line(arcs) { + arcs.forEach(arc); + } + + function polygon(arcs) { + arcs.forEach(line); + } + + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs) { arcs.forEach(polygon); } + }; + + geometry(o); + + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + } + + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } + + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; + + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); + + function register(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); + }); + }); + polygons.push(polygon); + } + + function exterior(ring) { + return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? + } + + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); + + polygons.forEach(function(polygon) { + delete polygon._; + }); + + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = []; + + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); + + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // this exterior ring has the same winding order + // as any exterior ring in the original polygons. + if ((n = arcs.length) > 1) { + var sgn = exterior(polygons[0][0]); + for (var i = 0, t; i < n; ++i) { + if (sgn === exterior(arcs[i])) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; + break; + } + } + } + + return arcs; + }) + }; + } + + function featureOrCollection(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature(topology, o); }) + } : feature(topology, o); + } + + function feature(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } + + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; + + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); + } + + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; + } + + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; + } + + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; + } + + function polygon(arcs) { + return arcs.map(ring); + } + + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; + } + + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; + + return geometry(o); + } + + function reverse(array, n) { + var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } + + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); + + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } + + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } + + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; + + objects.forEach(geometry); + + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); + } + } + } + + return neighbors; + } + + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); + + if (!triangleArea) triangleArea = cartesianTriangleArea; + + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle; + + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (var i = 0, n = arc.length, p; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } + + for (var i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); + triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); + heap.push(triangle); + } + + for (var i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } + + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; + + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; + + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); + } + + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } + + arc.forEach(relative); + }); + + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); + } + + return topology; + }; + + function cartesianRingArea(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; + + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; + } + + return area * .5; + } + + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } + + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } + + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; + + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; + + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; + }; + + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; + + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } + + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } + } + + return heap; + } + + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; + }; + } + + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = (point[0] - dx) / kx | 0, + y1 = (point[1] - dy) / ky | 0; + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } + + function noop() {} + + if (typeof define === "function" && define.amd) define(topojson); + else if (typeof module === "object" && module.exports) module.exports = topojson; + else this.topojson = topojson; +}(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js new file mode 100644 index 00000000..c6b8b0af --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js @@ -0,0 +1,20654 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vg = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 5, + ch = 1 << 11; + + module.exports = function() { + var size = [256, 256], + text = cloudText, + font = cloudFont, + fontSize = cloudFontSize, + fontStyle = cloudFontNormal, + fontWeight = cloudFontNormal, + rotate = cloudRotate, + padding = cloudPadding, + spiral = archimedeanSpiral, + words = [], + timeInterval = Infinity, + event = dispatch("word", "end"), + timer = null, + random = Math.random, + cloud = {}, + canvas = cloudCanvas; + + cloud.canvas = function(_) { + return arguments.length ? (canvas = functor(_), cloud) : canvas; + }; + + cloud.start = function() { + var contextAndRatio = getContext(canvas()), + board = zeroArray((size[0] >> 5) * size[1]), + bounds = null, + n = words.length, + i = -1, + tags = [], + data = words.map(function(d, i) { + d.text = text.call(this, d, i); + d.font = font.call(this, d, i); + d.style = fontStyle.call(this, d, i); + d.weight = fontWeight.call(this, d, i); + d.rotate = rotate.call(this, d, i); + d.size = ~~fontSize.call(this, d, i); + d.padding = padding.call(this, d, i); + return d; + }).sort(function(a, b) { return b.size - a.size; }); + + if (timer) clearInterval(timer); + timer = setInterval(step, 0); + step(); + + return cloud; + + function step() { + var start = Date.now(); + while (Date.now() - start < timeInterval && ++i < n && timer) { + var d = data[i]; + d.x = (size[0] * (random() + .5)) >> 1; + d.y = (size[1] * (random() + .5)) >> 1; + cloudSprite(contextAndRatio, d, data, i); + if (d.hasText && place(board, d, bounds)) { + tags.push(d); + event.word(d); + if (bounds) cloudBounds(bounds, d); + else bounds = [{x: d.x + d.x0, y: d.y + d.y0}, {x: d.x + d.x1, y: d.y + d.y1}]; + // Temporary hack + d.x -= size[0] >> 1; + d.y -= size[1] >> 1; + } + } + if (i >= n) { + cloud.stop(); + event.end(tags, bounds); + } + } + } + + cloud.stop = function() { + if (timer) { + clearInterval(timer); + timer = null; + } + return cloud; + }; + + function getContext(canvas) { + canvas.width = canvas.height = 1; + var ratio = Math.sqrt(canvas.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2); + canvas.width = (cw << 5) / ratio; + canvas.height = ch / ratio; + + var context = canvas.getContext("2d"); + context.fillStyle = context.strokeStyle = "red"; + context.textAlign = "center"; + + return {context: context, ratio: ratio}; + } + + function place(board, tag, bounds) { + var perimeter = [{x: 0, y: 0}, {x: size[0], y: size[1]}], + startX = tag.x, + startY = tag.y, + maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]), + s = spiral(size), + dt = random() < .5 ? 1 : -1, + t = -dt, + dxdy, + dx, + dy; + + while (dxdy = s(t += dt)) { + dx = ~~dxdy[0]; + dy = ~~dxdy[1]; + + if (Math.min(Math.abs(dx), Math.abs(dy)) >= maxDelta) break; + + tag.x = startX + dx; + tag.y = startY + dy; + + if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 || + tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue; + // TODO only check for collisions within current bounds. + if (!bounds || !cloudCollide(tag, board, size[0])) { + if (!bounds || collideRects(tag, bounds)) { + var sprite = tag.sprite, + w = tag.width >> 5, + sw = size[0] >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0); + } + x += sw; + } + delete tag.sprite; + return true; + } + } + } + return false; + } + + cloud.timeInterval = function(_) { + return arguments.length ? (timeInterval = _ == null ? Infinity : _, cloud) : timeInterval; + }; + + cloud.words = function(_) { + return arguments.length ? (words = _, cloud) : words; + }; + + cloud.size = function(_) { + return arguments.length ? (size = [+_[0], +_[1]], cloud) : size; + }; + + cloud.font = function(_) { + return arguments.length ? (font = functor(_), cloud) : font; + }; + + cloud.fontStyle = function(_) { + return arguments.length ? (fontStyle = functor(_), cloud) : fontStyle; + }; + + cloud.fontWeight = function(_) { + return arguments.length ? (fontWeight = functor(_), cloud) : fontWeight; + }; + + cloud.rotate = function(_) { + return arguments.length ? (rotate = functor(_), cloud) : rotate; + }; + + cloud.text = function(_) { + return arguments.length ? (text = functor(_), cloud) : text; + }; + + cloud.spiral = function(_) { + return arguments.length ? (spiral = spirals[_] || _, cloud) : spiral; + }; + + cloud.fontSize = function(_) { + return arguments.length ? (fontSize = functor(_), cloud) : fontSize; + }; + + cloud.padding = function(_) { + return arguments.length ? (padding = functor(_), cloud) : padding; + }; + + cloud.random = function(_) { + return arguments.length ? (random = _, cloud) : random; + }; + + cloud.on = function() { + var value = event.on.apply(event, arguments); + return value === event ? cloud : value; + }; + + return cloud; + }; + + function cloudText(d) { + return d.text; + } + + function cloudFont() { + return "serif"; + } + + function cloudFontNormal() { + return "normal"; + } + + function cloudFontSize(d) { + return Math.sqrt(d.value); + } + + function cloudRotate() { + return (~~(Math.random() * 6) - 3) * 30; + } + + function cloudPadding() { + return 1; + } + +// Fetches a monochrome sprite bitmap for the specified text. +// Load in batches for speed. + function cloudSprite(contextAndRatio, d, data, di) { + if (d.sprite) return; + var c = contextAndRatio.context, + ratio = contextAndRatio.ratio; + + c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio); + var x = 0, + y = 0, + maxh = 0, + n = data.length; + --di; + while (++di < n) { + d = data[di]; + c.save(); + c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font; + var w = c.measureText(d.text + "m").width * ratio, + h = d.size << 1; + if (d.rotate) { + var sr = Math.sin(d.rotate * cloudRadians), + cr = Math.cos(d.rotate * cloudRadians), + wcr = w * cr, + wsr = w * sr, + hcr = h * cr, + hsr = h * sr; + w = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5; + h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr)); + } else { + w = (w + 0x1f) >> 5 << 5; + } + if (h > maxh) maxh = h; + if (x + w >= (cw << 5)) { + x = 0; + y += maxh; + maxh = 0; + } + if (y + h >= ch) break; + c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio); + if (d.rotate) c.rotate(d.rotate * cloudRadians); + c.fillText(d.text, 0, 0); + if (d.padding) c.lineWidth = 2 * d.padding, c.strokeText(d.text, 0, 0); + c.restore(); + d.width = w; + d.height = h; + d.xoff = x; + d.yoff = y; + d.x1 = w >> 1; + d.y1 = h >> 1; + d.x0 = -d.x1; + d.y0 = -d.y1; + d.hasText = true; + x += w; + } + var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data, + sprite = []; + while (--di >= 0) { + d = data[di]; + if (!d.hasText) continue; + var w = d.width, + w32 = w >> 5, + h = d.y1 - d.y0; + // Zero the buffer + for (var i = 0; i < h * w32; i++) sprite[i] = 0; + x = d.xoff; + if (x == null) return; + y = d.yoff; + var seen = 0, + seenRow = -1; + for (var j = 0; j < h; j++) { + for (var i = 0; i < w; i++) { + var k = w32 * j + (i >> 5), + m = pixels[((y + j) * (cw << 5) + (x + i)) << 2] ? 1 << (31 - (i % 32)) : 0; + sprite[k] |= m; + seen |= m; + } + if (seen) seenRow = j; + else { + d.y0++; + h--; + j--; + y++; + } + } + d.y1 = d.y0 + seenRow; + d.sprite = sprite.slice(0, (d.y1 - d.y0) * w32); + } + } + +// Use mask-based collision detection. + function cloudCollide(tag, board, sw) { + sw >>= 5; + var sprite = tag.sprite, + w = tag.width >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + if (((last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0)) + & board[x + i]) return true; + } + x += sw; + } + return false; + } + + function cloudBounds(bounds, d) { + var b0 = bounds[0], + b1 = bounds[1]; + if (d.x + d.x0 < b0.x) b0.x = d.x + d.x0; + if (d.y + d.y0 < b0.y) b0.y = d.y + d.y0; + if (d.x + d.x1 > b1.x) b1.x = d.x + d.x1; + if (d.y + d.y1 > b1.y) b1.y = d.y + d.y1; + } + + function collideRects(a, b) { + return a.x + a.x1 > b[0].x && a.x + a.x0 < b[1].x && a.y + a.y1 > b[0].y && a.y + a.y0 < b[1].y; + } + + function archimedeanSpiral(size) { + var e = size[0] / size[1]; + return function(t) { + return [e * (t *= .1) * Math.cos(t), t * Math.sin(t)]; + }; + } + + function rectangularSpiral(size) { + var dy = 4, + dx = dy * size[0] / size[1], + x = 0, + y = 0; + return function(t) { + var sign = t < 0 ? -1 : 1; + // See triangular numbers: T_n = n * (n + 1) / 2. + switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3) { + case 0: x += dx; break; + case 1: y += dy; break; + case 2: x -= dx; break; + default: y -= dy; break; + } + return [x, y]; + }; + } + +// TODO reuse arrays? + function zeroArray(n) { + var a = [], + i = -1; + while (++i < n) a[i] = 0; + return a; + } + + function cloudCanvas() { + return document.createElement("canvas"); + } + + function functor(d) { + return typeof d === "function" ? d : function() { return d; }; + } + + var spirals = { + archimedean: archimedeanSpiral, + rectangular: rectangularSpiral + }; + +},{"d3-dispatch":4}],4:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dispatch', ['exports'], factory) : + factory((global.d3_dispatch = {})); + }(this, function (exports) { 'use strict'; + + function dispatch() { + return new Dispatch(arguments); + } + + function Dispatch(types) { + var i = -1, + n = types.length, + callbacksByType = {}, + callbackByName = {}, + type, + that = this; + + that.on = function(type, callback) { + type = parseType(type); + + // Return the current callback, if any. + if (arguments.length < 2) { + return (callback = callbackByName[type.name]) && callback.value; + } + + // If a type was specified… + if (type.type) { + var callbacks = callbacksByType[type.type], + callback0 = callbackByName[type.name], + i; + + // Remove the current callback, if any, using copy-on-remove. + if (callback0) { + callback0.value = null; + i = callbacks.indexOf(callback0); + callbacksByType[type.type] = callbacks = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[type.name]; + } + + // Add the new callback, if any. + if (callback) { + callback = {value: callback}; + callbackByName[type.name] = callback; + callbacks.push(callback); + } + } + + // Otherwise, if a null callback was specified, remove all callbacks with the given name. + else if (callback == null) { + for (var otherType in callbacksByType) { + if (callback = callbackByName[otherType + type.name]) { + callback.value = null; + var callbacks = callbacksByType[otherType], i = callbacks.indexOf(callback); + callbacksByType[otherType] = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[callback.name]; + } + } + } + + return that; + }; + + while (++i < n) { + type = types[i] + ""; + if (!type || (type in that)) throw new Error("illegal or duplicate type: " + type); + callbacksByType[type] = []; + that[type] = applier(type); + } + + function parseType(type) { + var i = (type += "").indexOf("."), name = type; + if (i >= 0) type = type.slice(0, i); else name += "."; + if (type && !callbacksByType.hasOwnProperty(type)) throw new Error("unknown type: " + type); + return {type: type, name: name}; + } + + function applier(type) { + return function() { + var callbacks = callbacksByType[type], // Defensive reference; copy-on-remove. + callback, + callbackValue, + i = -1, + n = callbacks.length; + + while (++i < n) { + if (callbackValue = (callback = callbacks[i]).value) { + callbackValue.apply(this, arguments); + } + } + + return that; + }; + } + } + + dispatch.prototype = Dispatch.prototype; + + var version = "0.2.4"; + + exports.version = version; + exports.dispatch = dispatch; + + })); +},{}],5:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dsv', ['exports'], factory) : + factory((global.d3_dsv = {})); + }(this, function (exports) { 'use strict'; + + function dsv(delimiter) { + return new Dsv(delimiter); + } + + function Dsv(delimiter) { + var reFormat = new RegExp("[\"" + delimiter + "\n]"), + delimiterCode = delimiter.charCodeAt(0); + + this.parse = function(text, f) { + var o; + return this.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { return f(a(row), i); } : a; + }); + }; + + this.parseRows = function(text, f) { + var EOL = {}, // sentinel value for end-of-line + EOF = {}, // sentinel value for end-of-file + rows = [], // output rows + N = text.length, + I = 0, // current character index + n = 0, // the current line number + t, // the current token + eol; // is the current token followed by EOL? + + function token() { + if (I >= N) return EOF; // special case: end of file + if (eol) return eol = false, EOL; // special case: end of line + + // special case: quotes + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.slice(j + 1, i).replace(/""/g, "\""); + } + + // common case: find next delimiter or newline + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; // \n + else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n + else if (c !== delimiterCode) continue; + return text.slice(j, I - k); + } + + // special case: last token before EOF + return text.slice(j); + } + + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && (a = f(a, n++)) == null) continue; + rows.push(a); + } + + return rows; + } + + this.format = function(rows) { + if (Array.isArray(rows[0])) return this.formatRows(rows); // deprecated; use formatRows + var fieldSet = Object.create(null), fields = []; + + // Compute unique fields in order of discovery. + rows.forEach(function(row) { + for (var field in row) { + if (!((field += "") in fieldSet)) { + fields.push(fieldSet[field] = field); + } + } + }); + + return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + + this.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + + function formatValue(text) { + return reFormat.test(text) ? "\"" + text.replace(/\"/g, "\"\"") + "\"" : text; + } + }; + + dsv.prototype = Dsv.prototype; + + var csv = dsv(","); + var tsv = dsv("\t"); + + var version = "0.1.9"; + + exports.version = version; + exports.dsv = dsv; + exports.csv = csv; + exports.tsv = tsv; + + })); +},{}],6:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-format', ['exports'], factory) : + factory((global.d3_format = {})); + }(this, function (exports) { 'use strict'; + + var zhCn = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["¥", ""] + }; + + var svSe = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "SEK"] + }; + + var ruRu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0руб."] + }; + + var ptBr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["R$", ""] + }; + + var plPl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "zł"] + }; + + var nlNl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€\xa0", ""] + }; + + var mkMk = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0ден."] + }; + + var koKr = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₩", ""] + }; + + var jaJp = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["", "円"] + }; + + var itIt = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€", ""] + }; + + var huHu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0Ft"] + }; + + var heIl = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₪", ""] + }; + + var frFr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var frCa = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "$"] + }; + + var fiFi = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var esEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var enUs = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var enGb = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["£", ""] + }; + + var enCa = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var deDe = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var deCh = { + decimal: ",", + thousands: "'", + grouping: [3], + currency: ["", "\xa0CHF"] + }; + + var caEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + // Computes the decimal coefficient and exponent of the specified number x with + // significant digits p, where x is positive and p is in [1, 21] or undefined. + // For example, formatDecimal(1.23) returns ["123", 0]. + function formatDecimal(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); + + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; + }; + + function exponent(x) { + return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; + }; + + function formatGroup(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; + + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } + + return t.reverse().join(thousands); + }; + }; + + var prefixExponent; + + function formatPrefixAuto(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! + }; + + function formatRounded(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); + }; + + function formatDefault(x, p) { + x = x.toPrecision(p); + + out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (x[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + case "e": break out; + default: if (i0 > 0) i0 = 0; break; + } + } + + return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; + }; + + var formatTypes = { + "": formatDefault, + "%": function(x, p) { return (x * 100).toFixed(p); }, + "b": function(x) { return Math.round(x).toString(2); }, + "c": function(x) { return x + ""; }, + "d": function(x) { return Math.round(x).toString(10); }, + "e": function(x, p) { return x.toExponential(p); }, + "f": function(x, p) { return x.toFixed(p); }, + "g": function(x, p) { return x.toPrecision(p); }, + "o": function(x) { return Math.round(x).toString(8); }, + "p": function(x, p) { return formatRounded(x * 100, p); }, + "r": formatRounded, + "s": formatPrefixAuto, + "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, + "x": function(x) { return Math.round(x).toString(16); } + }; + + // [[fill]align][sign][symbol][0][width][,][.precision][type] + var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; + + function formatSpecifier(specifier) { + return new FormatSpecifier(specifier); + }; + + function FormatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + + var match, + fill = match[1] || " ", + align = match[2] || ">", + sign = match[3] || "-", + symbol = match[4] || "", + zero = !!match[5], + width = match[6] && +match[6], + comma = !!match[7], + precision = match[8] && +match[8].slice(1), + type = match[9] || ""; + + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; + + // Map invalid types to the default format. + else if (!formatTypes[type]) type = ""; + + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + + this.fill = fill; + this.align = align; + this.sign = sign; + this.symbol = symbol; + this.zero = zero; + this.width = width; + this.comma = comma; + this.precision = precision; + this.type = type; + } + + FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width == null ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + + this.type; + }; + + var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; + + function identity(x) { + return x; + } + + function locale(locale) { + var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity, + currency = locale.currency, + decimal = locale.decimal; + + function format(specifier) { + specifier = formatSpecifier(specifier); + + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + type = specifier.type; + + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; + + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = !type || /[defgprs%]/.test(type); + + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision == null ? (type ? 6 : 12) + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); + + return function(value) { + var valuePrefix = prefix, + valueSuffix = suffix; + + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; + + // Convert negative to positive, and compute the prefix. + // Note that -0 is not less than 0, but 1 / -0 is! + var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true); + + // Perform the initial formatting. + value = formatType(value, precision); + + // If the original value was negative, it may be rounded to zero during + // formatting; treat this as (positive) zero. + if (valueNegative) { + var i = -1, n = value.length, c; + valueNegative = false; + while (++i < n) { + if (c = value.charCodeAt(i), (48 < c && c < 58) + || (type === "x" && 96 < c && c < 103) + || (type === "X" && 64 < c && c < 71)) { + valueNegative = true; + break; + } + } + } + + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); + + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + var i = -1, n = value.length, c; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } + + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); + + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; + + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": return valuePrefix + value + valueSuffix + padding; + case "=": return valuePrefix + padding + value + valueSuffix; + case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); + } + return padding + valuePrefix + value + valueSuffix; + }; + } + + function formatPrefix(specifier, value) { + var f = format((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; + } + + return { + format: format, + formatPrefix: formatPrefix + }; + }; + + function precisionFixed(step) { + return Math.max(0, -exponent(Math.abs(step))); + }; + + function precisionPrefix(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); + }; + + function precisionRound(step, max) { + return Math.max(0, exponent(Math.abs(max)) - exponent(Math.abs(step))) + 1; + }; + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": enUs, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(enUs); + var format = defaultLocale.format; + var formatPrefix = defaultLocale.formatPrefix; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.3.6"; + + exports.version = version; + exports.format = format; + exports.formatPrefix = formatPrefix; + exports.localeFormat = localeFormat; + exports.formatSpecifier = formatSpecifier; + exports.precisionFixed = precisionFixed; + exports.precisionPrefix = precisionPrefix; + exports.precisionRound = precisionRound; + + })); +},{}],7:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-time')) : + typeof define === 'function' && define.amd ? define('d3-time-format', ['exports', 'd3-time'], factory) : + factory((global.d3_time_format = {}),global.d3_time); + }(this, function (exports,d3Time) { 'use strict'; + + var zhCn = { + dateTime: "%a %b %e %X %Y", + date: "%Y/%-m/%-d", + time: "%H:%M:%S", + periods: ["上午", "下午"], + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + shortMonths: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] + }; + + var svSe = { + dateTime: "%A den %d %B %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["fm", "em"], + days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"], + shortDays: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"], + months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] + }; + + var ruRu = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"], + shortDays: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"], + months: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"], + shortMonths: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"] + }; + + var ptBr = { + dateTime: "%A, %e de %B de %Y. %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"], + shortDays: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"], + months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], + shortMonths: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"] + }; + + var plPl = { + dateTime: "%A, %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"], + shortDays: ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."], + months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"], + shortMonths: ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."]/* In Polish language abbraviated months are not commonly used so there is a dispute about the proper abbraviations. */ + }; + + var nlNl = { + dateTime: "%a %e %B %Y %T", + date: "%d-%m-%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], + shortDays: ["zo", "ma", "di", "wo", "do", "vr", "za"], + months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], + shortMonths: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] + }; + + var mkMk = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"], + shortDays: ["нед", "пон", "вто", "сре", "чет", "пет", "саб"], + months: ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"], + shortMonths: ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"] + }; + + var koKr = { + dateTime: "%Y/%m/%d %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["오전", "오후"], + days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"], + shortDays: ["일", "월", "화", "수", "목", "금", "토"], + months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], + shortMonths: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"] + }; + + var jaJp = { + dateTime: "%Y %b %e %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"], + shortDays: ["日", "月", "火", "水", "木", "金", "土"], + months: ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"], + shortMonths: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"] + }; + + var itIt = { + dateTime: "%A %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"], + shortDays: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"], + months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], + shortMonths: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"] + }; + + var huHu = { + dateTime: "%Y. %B %-e., %A %X", + date: "%Y. %m. %d.", + time: "%H:%M:%S", + periods: ["de.", "du."], // unused + days: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"], + shortDays: ["V", "H", "K", "Sze", "Cs", "P", "Szo"], + months: ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"], + shortMonths: ["jan.", "feb.", "már.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec."] + }; + + var heIl = { + dateTime: "%A, %e ב%B %Y %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"], + shortDays: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"], + months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], + shortMonths: ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"] + }; + + var frFr = { + dateTime: "%A, le %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."] + }; + + var frCa = { + dateTime: "%a %e %b %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["", ""], + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"] + }; + + var fiFi = { + dateTime: "%A, %-d. %Bta %Y klo %X", + date: "%-d.%-m.%Y", + time: "%H:%M:%S", + periods: ["a.m.", "p.m."], + days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"], + shortDays: ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"], + months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], + shortMonths: ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"] + }; + + var esEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], + shortDays: ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], + months: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], + shortMonths: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] + }; + + var locale$1 = { + dateTime: "%a %b %e %X %Y", + date: "%m/%d/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }; + + var enGb = { + dateTime: "%a %e %b %X %Y", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }; + + var enCa = { + dateTime: "%a %b %e %X %Y", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }; + + var deDe = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var deCh = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var caEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"], + shortDays: ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."], + months: ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"], + shortMonths: ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."] + }; + + function localDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); + date.setFullYear(d.y); + return date; + } + return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); + } + + function utcDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); + date.setUTCFullYear(d.y); + return date; + } + return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); + } + + function newYear(y) { + return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; + } + + function locale(locale) { + var locale_dateTime = locale.dateTime, + locale_date = locale.date, + locale_time = locale.time, + locale_periods = locale.periods, + locale_weekdays = locale.days, + locale_shortWeekdays = locale.shortDays, + locale_months = locale.months, + locale_shortMonths = locale.shortMonths; + + var periodLookup = formatLookup(locale_periods), + weekdayRe = formatRe(locale_weekdays), + weekdayLookup = formatLookup(locale_weekdays), + shortWeekdayRe = formatRe(locale_shortWeekdays), + shortWeekdayLookup = formatLookup(locale_shortWeekdays), + monthRe = formatRe(locale_months), + monthLookup = formatLookup(locale_months), + shortMonthRe = formatRe(locale_shortMonths), + shortMonthLookup = formatLookup(locale_shortMonths); + + var formats = { + "a": formatShortWeekday, + "A": formatWeekday, + "b": formatShortMonth, + "B": formatMonth, + "c": null, + "d": formatDayOfMonth, + "e": formatDayOfMonth, + "H": formatHour24, + "I": formatHour12, + "j": formatDayOfYear, + "L": formatMilliseconds, + "m": formatMonthNumber, + "M": formatMinutes, + "p": formatPeriod, + "S": formatSeconds, + "U": formatWeekNumberSunday, + "w": formatWeekdayNumber, + "W": formatWeekNumberMonday, + "x": null, + "X": null, + "y": formatYear, + "Y": formatFullYear, + "Z": formatZone, + "%": formatLiteralPercent + }; + + var utcFormats = { + "a": formatUTCShortWeekday, + "A": formatUTCWeekday, + "b": formatUTCShortMonth, + "B": formatUTCMonth, + "c": null, + "d": formatUTCDayOfMonth, + "e": formatUTCDayOfMonth, + "H": formatUTCHour24, + "I": formatUTCHour12, + "j": formatUTCDayOfYear, + "L": formatUTCMilliseconds, + "m": formatUTCMonthNumber, + "M": formatUTCMinutes, + "p": formatUTCPeriod, + "S": formatUTCSeconds, + "U": formatUTCWeekNumberSunday, + "w": formatUTCWeekdayNumber, + "W": formatUTCWeekNumberMonday, + "x": null, + "X": null, + "y": formatUTCYear, + "Y": formatUTCFullYear, + "Z": formatUTCZone, + "%": formatLiteralPercent + }; + + var parses = { + "a": parseShortWeekday, + "A": parseWeekday, + "b": parseShortMonth, + "B": parseMonth, + "c": parseLocaleDateTime, + "d": parseDayOfMonth, + "e": parseDayOfMonth, + "H": parseHour24, + "I": parseHour24, + "j": parseDayOfYear, + "L": parseMilliseconds, + "m": parseMonthNumber, + "M": parseMinutes, + "p": parsePeriod, + "S": parseSeconds, + "U": parseWeekNumberSunday, + "w": parseWeekdayNumber, + "W": parseWeekNumberMonday, + "x": parseLocaleDate, + "X": parseLocaleTime, + "y": parseYear, + "Y": parseFullYear, + "Z": parseZone, + "%": parseLiteralPercent + }; + + // These recursive directive definitions must be deferred. + formats.x = newFormat(locale_date, formats); + formats.X = newFormat(locale_time, formats); + formats.c = newFormat(locale_dateTime, formats); + utcFormats.x = newFormat(locale_date, utcFormats); + utcFormats.X = newFormat(locale_time, utcFormats); + utcFormats.c = newFormat(locale_dateTime, utcFormats); + + function newFormat(specifier, formats) { + return function(date) { + var string = [], + i = -1, + j = 0, + n = specifier.length, + c, + pad, + format; + + while (++i < n) { + if (specifier.charCodeAt(i) === 37) { + string.push(specifier.slice(j, i)); + if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); + if (format = formats[c]) c = format(date, pad == null ? (c === "e" ? " " : "0") : pad); + string.push(c); + j = i + 1; + } + } + + string.push(specifier.slice(j, i)); + return string.join(""); + }; + } + + function newParse(specifier, newDate) { + return function(string) { + var d = newYear(1900), + i = parseSpecifier(d, specifier, string, 0); + if (i != string.length) return null; + + // The am-pm flag is 0 for AM, and 1 for PM. + if ("p" in d) d.H = d.H % 12 + d.p * 12; + + // If a time zone is specified, all fields are interpreted as UTC and then + // offset according to the specified time zone. + if ("Z" in d) { + if ("w" in d && ("W" in d || "U" in d)) { + var day = utcDate(newYear(d.y)).getUTCDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + d.H += d.Z / 100 | 0; + d.M += d.Z % 100; + return utcDate(d); + } + + // Otherwise, all fields are in local time. + if ("w" in d && ("W" in d || "U" in d)) { + var day = newDate(newYear(d.y)).getDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + return newDate(d); + }; + } + + function parseSpecifier(d, specifier, string, j) { + var i = 0, + n = specifier.length, + m = string.length, + c, + parse; + + while (i < n) { + if (j >= m) return -1; + c = specifier.charCodeAt(i++); + if (c === 37) { + c = specifier.charAt(i++); + parse = parses[c in pads ? specifier.charAt(i++) : c]; + if (!parse || ((j = parse(d, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + + return j; + } + + function parseShortWeekday(d, string, i) { + var n = shortWeekdayRe.exec(string.slice(i)); + return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseWeekday(d, string, i) { + var n = weekdayRe.exec(string.slice(i)); + return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseShortMonth(d, string, i) { + var n = shortMonthRe.exec(string.slice(i)); + return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseMonth(d, string, i) { + var n = monthRe.exec(string.slice(i)); + return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseLocaleDateTime(d, string, i) { + return parseSpecifier(d, locale_dateTime, string, i); + } + + function parseLocaleDate(d, string, i) { + return parseSpecifier(d, locale_date, string, i); + } + + function parseLocaleTime(d, string, i) { + return parseSpecifier(d, locale_time, string, i); + } + + function parsePeriod(d, string, i) { + var n = periodLookup[string.slice(i, i += 2).toLowerCase()]; + return n == null ? -1 : (d.p = n, i); + } + + function formatShortWeekday(d) { + return locale_shortWeekdays[d.getDay()]; + } + + function formatWeekday(d) { + return locale_weekdays[d.getDay()]; + } + + function formatShortMonth(d) { + return locale_shortMonths[d.getMonth()]; + } + + function formatMonth(d) { + return locale_months[d.getMonth()]; + } + + function formatPeriod(d) { + return locale_periods[+(d.getHours() >= 12)]; + } + + function formatUTCShortWeekday(d) { + return locale_shortWeekdays[d.getUTCDay()]; + } + + function formatUTCWeekday(d) { + return locale_weekdays[d.getUTCDay()]; + } + + function formatUTCShortMonth(d) { + return locale_shortMonths[d.getUTCMonth()]; + } + + function formatUTCMonth(d) { + return locale_months[d.getUTCMonth()]; + } + + function formatUTCPeriod(d) { + return locale_periods[+(d.getUTCHours() >= 12)]; + } + + return { + format: function(specifier) { + var f = newFormat(specifier += "", formats); + f.parse = newParse(specifier, localDate); + f.toString = function() { return specifier; }; + return f; + }, + utcFormat: function(specifier) { + var f = newFormat(specifier += "", utcFormats); + f.parse = newParse(specifier, utcDate); + f.toString = function() { return specifier; }; + return f; + } + }; + }; + + var pads = {"-": "", "_": " ", "0": "0"}; + var numberRe = /^\s*\d+/; + var percentRe = /^%/; + var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + function pad(value, fill, width) { + var sign = value < 0 ? "-" : "", + string = (sign ? -value : value) + "", + length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); + } + + function requote(s) { + return s.replace(requoteRe, "\\$&"); + } + + function formatRe(names) { + return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); + } + + function formatLookup(names) { + var map = {}, i = -1, n = names.length; + while (++i < n) map[names[i].toLowerCase()] = i; + return map; + } + + function parseWeekdayNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.w = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.U = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.W = +n[0], i + n[0].length) : -1; + } + + function parseFullYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 4)); + return n ? (d.y = +n[0], i + n[0].length) : -1; + } + + function parseYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; + } + + function parseZone(d, string, i) { + var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); + if (n) { + d.Z = n[1] ? 0 // 'Z' for UTC + : n[3] ? -(n[2] + n[3]) // sign differs from getTimezoneOffset! + : -n[2] * 100; + return i + n[0].length; + } + return -1; + } + + function parseMonthNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.m = n[0] - 1, i + n[0].length) : -1; + } + + function parseDayOfMonth(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.d = +n[0], i + n[0].length) : -1; + } + + function parseDayOfYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; + } + + function parseHour24(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.H = +n[0], i + n[0].length) : -1; + } + + function parseMinutes(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.M = +n[0], i + n[0].length) : -1; + } + + function parseSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.S = +n[0], i + n[0].length) : -1; + } + + function parseMilliseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.L = +n[0], i + n[0].length) : -1; + } + + function parseLiteralPercent(d, string, i) { + var n = percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; + } + + function formatDayOfMonth(d, p) { + return pad(d.getDate(), p, 2); + } + + function formatHour24(d, p) { + return pad(d.getHours(), p, 2); + } + + function formatHour12(d, p) { + return pad(d.getHours() % 12 || 12, p, 2); + } + + function formatDayOfYear(d, p) { + return pad(1 + d3Time.day.count(d3Time.year(d), d), p, 3); + } + + function formatMilliseconds(d, p) { + return pad(d.getMilliseconds(), p, 3); + } + + function formatMonthNumber(d, p) { + return pad(d.getMonth() + 1, p, 2); + } + + function formatMinutes(d, p) { + return pad(d.getMinutes(), p, 2); + } + + function formatSeconds(d, p) { + return pad(d.getSeconds(), p, 2); + } + + function formatWeekNumberSunday(d, p) { + return pad(d3Time.sunday.count(d3Time.year(d), d), p, 2); + } + + function formatWeekdayNumber(d) { + return d.getDay(); + } + + function formatWeekNumberMonday(d, p) { + return pad(d3Time.monday.count(d3Time.year(d), d), p, 2); + } + + function formatYear(d, p) { + return pad(d.getFullYear() % 100, p, 2); + } + + function formatFullYear(d, p) { + return pad(d.getFullYear() % 10000, p, 4); + } + + function formatZone(d) { + var z = d.getTimezoneOffset(); + return (z > 0 ? "-" : (z *= -1, "+")) + + pad(z / 60 | 0, "0", 2) + + pad(z % 60, "0", 2); + } + + function formatUTCDayOfMonth(d, p) { + return pad(d.getUTCDate(), p, 2); + } + + function formatUTCHour24(d, p) { + return pad(d.getUTCHours(), p, 2); + } + + function formatUTCHour12(d, p) { + return pad(d.getUTCHours() % 12 || 12, p, 2); + } + + function formatUTCDayOfYear(d, p) { + return pad(1 + d3Time.utcDay.count(d3Time.utcYear(d), d), p, 3); + } + + function formatUTCMilliseconds(d, p) { + return pad(d.getUTCMilliseconds(), p, 3); + } + + function formatUTCMonthNumber(d, p) { + return pad(d.getUTCMonth() + 1, p, 2); + } + + function formatUTCMinutes(d, p) { + return pad(d.getUTCMinutes(), p, 2); + } + + function formatUTCSeconds(d, p) { + return pad(d.getUTCSeconds(), p, 2); + } + + function formatUTCWeekNumberSunday(d, p) { + return pad(d3Time.utcSunday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCWeekdayNumber(d) { + return d.getUTCDay(); + } + + function formatUTCWeekNumberMonday(d, p) { + return pad(d3Time.utcMonday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCYear(d, p) { + return pad(d.getUTCFullYear() % 100, p, 2); + } + + function formatUTCFullYear(d, p) { + return pad(d.getUTCFullYear() % 10000, p, 4); + } + + function formatUTCZone() { + return "+0000"; + } + + function formatLiteralPercent() { + return "%"; + } + + var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; + + function formatIsoNative(date) { + return date.toISOString(); + } + + formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + + formatIsoNative.toString = function() { + return isoSpecifier; + }; + + var formatIso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") + ? formatIsoNative + : locale$1.utcFormat(isoSpecifier); + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": locale$1, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(locale$1); + var format = defaultLocale.format; + var utcFormat = defaultLocale.utcFormat; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.1.5"; + + exports.version = version; + exports.format = format; + exports.utcFormat = utcFormat; + exports.localeFormat = localeFormat; + exports.isoFormat = formatIso; + + })); +},{"d3-time":8}],8:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-time', ['exports'], factory) : + factory((global.d3_time = {})); + }(this, function (exports) { 'use strict'; + + var t0 = new Date; + var t1 = new Date; + function newInterval(floori, offseti, count) { + + function interval(date) { + return floori(date = new Date(+date)), date; + } + + interval.floor = interval; + + interval.round = function(date) { + var d0 = new Date(+date), + d1 = new Date(date - 1); + floori(d0), floori(d1), offseti(d1, 1); + return date - d0 < d1 - date ? d0 : d1; + }; + + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), date; + }; + + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; + + interval.range = function(start, stop, step) { + var range = []; + start = new Date(start - 1); + stop = new Date(+stop); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + offseti(start, 1), floori(start); + if (start < stop) range.push(new Date(+start)); + while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start)); + return range; + }; + + interval.filter = function(test) { + return newInterval(function(date) { + while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + while (--step >= 0) while (offseti(date, 1), !test(date)); + }); + }; + + if (count) interval.count = function(start, end) { + t0.setTime(+start), t1.setTime(+end); + floori(t0), floori(t1); + return Math.floor(count(t0, t1)); + }; + + return interval; + }; + + var millisecond = newInterval(function() { + // noop + }, function(date, step) { + date.setTime(+date + step); + }, function(start, end) { + return end - start; + }); + + var second = newInterval(function(date) { + date.setMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var minute = newInterval(function(date) { + date.setSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var hour = newInterval(function(date) { + date.setMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5; + }); + + function weekday(i) { + return newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5; + }); + } + + var sunday = weekday(0); + var monday = weekday(1); + var tuesday = weekday(2); + var wednesday = weekday(3); + var thursday = weekday(4); + var friday = weekday(5); + var saturday = weekday(6); + + var month = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(1); + }, function(date, step) { + date.setMonth(date.getMonth() + step); + }, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; + }); + + var year = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setMonth(0, 1); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step); + }, function(start, end) { + return end.getFullYear() - start.getFullYear(); + }); + + var utcSecond = newInterval(function(date) { + date.setUTCMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); + }, function(start, end) { + return (end - start) / 864e5; + }); + + function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / 6048e5; + }); + } + + var utcSunday = utcWeekday(0); + var utcMonday = utcWeekday(1); + var utcTuesday = utcWeekday(2); + var utcWednesday = utcWeekday(3); + var utcThursday = utcWeekday(4); + var utcFriday = utcWeekday(5); + var utcSaturday = utcWeekday(6); + + var utcMonth = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(1); + }, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); + }, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; + }); + + var utcYear = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCMonth(0, 1); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); + }, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); + }); + + var milliseconds = millisecond.range; + var seconds = second.range; + var minutes = minute.range; + var hours = hour.range; + var days = day.range; + var sundays = sunday.range; + var mondays = monday.range; + var tuesdays = tuesday.range; + var wednesdays = wednesday.range; + var thursdays = thursday.range; + var fridays = friday.range; + var saturdays = saturday.range; + var weeks = sunday.range; + var months = month.range; + var years = year.range; + + var utcMillisecond = millisecond; + var utcMilliseconds = milliseconds; + var utcSeconds = utcSecond.range; + var utcMinutes = utcMinute.range; + var utcHours = utcHour.range; + var utcDays = utcDay.range; + var utcSundays = utcSunday.range; + var utcMondays = utcMonday.range; + var utcTuesdays = utcTuesday.range; + var utcWednesdays = utcWednesday.range; + var utcThursdays = utcThursday.range; + var utcFridays = utcFriday.range; + var utcSaturdays = utcSaturday.range; + var utcWeeks = utcSunday.range; + var utcMonths = utcMonth.range; + var utcYears = utcYear.range; + + var version = "0.0.7"; + + exports.version = version; + exports.milliseconds = milliseconds; + exports.seconds = seconds; + exports.minutes = minutes; + exports.hours = hours; + exports.days = days; + exports.sundays = sundays; + exports.mondays = mondays; + exports.tuesdays = tuesdays; + exports.wednesdays = wednesdays; + exports.thursdays = thursdays; + exports.fridays = fridays; + exports.saturdays = saturdays; + exports.weeks = weeks; + exports.months = months; + exports.years = years; + exports.utcMillisecond = utcMillisecond; + exports.utcMilliseconds = utcMilliseconds; + exports.utcSeconds = utcSeconds; + exports.utcMinutes = utcMinutes; + exports.utcHours = utcHours; + exports.utcDays = utcDays; + exports.utcSundays = utcSundays; + exports.utcMondays = utcMondays; + exports.utcTuesdays = utcTuesdays; + exports.utcWednesdays = utcWednesdays; + exports.utcThursdays = utcThursdays; + exports.utcFridays = utcFridays; + exports.utcSaturdays = utcSaturdays; + exports.utcWeeks = utcWeeks; + exports.utcMonths = utcMonths; + exports.utcYears = utcYears; + exports.millisecond = millisecond; + exports.second = second; + exports.minute = minute; + exports.hour = hour; + exports.day = day; + exports.sunday = sunday; + exports.monday = monday; + exports.tuesday = tuesday; + exports.wednesday = wednesday; + exports.thursday = thursday; + exports.friday = friday; + exports.saturday = saturday; + exports.week = sunday; + exports.month = month; + exports.year = year; + exports.utcSecond = utcSecond; + exports.utcMinute = utcMinute; + exports.utcHour = utcHour; + exports.utcDay = utcDay; + exports.utcSunday = utcSunday; + exports.utcMonday = utcMonday; + exports.utcTuesday = utcTuesday; + exports.utcWednesday = utcWednesday; + exports.utcThursday = utcThursday; + exports.utcFriday = utcFriday; + exports.utcSaturday = utcSaturday; + exports.utcWeek = utcSunday; + exports.utcMonth = utcMonth; + exports.utcYear = utcYear; + exports.interval = newInterval; + + })); +},{}],9:[function(require,module,exports){ + var util = require('../util'), + Measures = require('./measures'), + Collector = require('./collector'); + + function Aggregator() { + this._cells = {}; + this._aggr = []; + this._stream = false; + } + + var Flags = Aggregator.Flags = { + ADD_CELL: 1, + MOD_CELL: 2 + }; + + var proto = Aggregator.prototype; + +// Parameters + + proto.stream = function(v) { + if (v == null) return this._stream; + this._stream = !!v; + this._aggr = []; + return this; + }; + +// key accessor to use for streaming removes + proto.key = function(key) { + if (key == null) return this._key; + this._key = util.$(key); + return this; + }; + +// Input: array of objects of the form +// {name: string, get: function} + proto.groupby = function(dims) { + this._dims = util.array(dims).map(function(d, i) { + d = util.isString(d) ? {name: d, get: util.$(d)} + : util.isFunction(d) ? {name: util.name(d) || d.name || ('_' + i), get: d} + : (d.name && util.isFunction(d.get)) ? d : null; + if (d == null) throw 'Invalid groupby argument: ' + d; + return d; + }); + return this.clear(); + }; + +// Input: array of objects of the form +// {name: string, ops: [string, ...]} + proto.summarize = function(fields) { + fields = summarize_args(fields); + this._count = true; + var aggr = (this._aggr = []), + m, f, i, j, op, as, get; + + for (i=0; i 0) { + // consolidate collector values + if (cell.collect) { + cell.data.values(); + } + // update tuple properties + for (i=0; i 0) { + m[a[i]] -= 1; + } else { + x[j++] = a[i]; + } + } + } else if (k) { + // has unique key field, so use that + m = util.toMap(r, k); + for (i=0, j=0, n=a.length; i 1 ? this.dev / (this.valid-1) : 0', + req: ['mean'], idx: 1 + }), + 'variancep': measure({ + name: 'variancep', + set: 'this.valid > 1 ? this.dev / this.valid : 0', + req: ['variance'], idx: 2 + }), + 'stdev': measure({ + name: 'stdev', + set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0', + req: ['variance'], idx: 2 + }), + 'stdevp': measure({ + name: 'stdevp', + set: 'this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0', + req: ['variance'], idx: 2 + }), + 'median': measure({ + name: 'median', + set: 'cell.data.q2(this.get)', + req: ['values'], idx: 3 + }), + 'q1': measure({ + name: 'q1', + set: 'cell.data.q1(this.get)', + req: ['values'], idx: 3 + }), + 'q3': measure({ + name: 'q3', + set: 'cell.data.q3(this.get)', + req: ['values'], idx: 3 + }), + 'distinct': measure({ + name: 'distinct', + set: 'this.distinct(cell.data.values(), this.get)', + req: ['values'], idx: 3 + }), + 'argmin': measure({ + name: 'argmin', + add: 'if (v < this.min) this.argmin = t;', + rem: 'if (v <= this.min) this.argmin = null;', + set: 'this.argmin = this.argmin || cell.data.argmin(this.get)', + req: ['min'], str: ['values'], idx: 3 + }), + 'argmax': measure({ + name: 'argmax', + add: 'if (v > this.max) this.argmax = t;', + rem: 'if (v >= this.max) this.argmax = null;', + set: 'this.argmax = this.argmax || cell.data.argmax(this.get)', + req: ['max'], str: ['values'], idx: 3 + }), + 'min': measure({ + name: 'min', + init: 'this.min = +Infinity;', + add: 'if (v < this.min) this.min = v;', + rem: 'if (v <= this.min) this.min = NaN;', + set: 'this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)', + str: ['values'], idx: 4 + }), + 'max': measure({ + name: 'max', + init: 'this.max = -Infinity;', + add: 'if (v > this.max) this.max = v;', + rem: 'if (v >= this.max) this.max = NaN;', + set: 'this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)', + str: ['values'], idx: 4 + }), + 'modeskew': measure({ + name: 'modeskew', + set: 'this.dev===0 ? 0 : (this.mean - cell.data.q2(this.get)) / Math.sqrt(this.dev/(this.valid-1))', + req: ['mean', 'stdev', 'median'], idx: 5 + }) + }; + + function measure(base) { + return function(out) { + var m = util.extend({init:'', add:'', rem:'', idx:0}, base); + m.out = out || base.name; + return m; + }; + } + + function resolve(agg, stream) { + function collect(m, a) { + function helper(r) { if (!m[r]) collect(m, m[r] = types[r]()); } + if (a.req) a.req.forEach(helper); + if (stream && a.str) a.str.forEach(helper); + return m; + } + var map = agg.reduce( + collect, + agg.reduce(function(m, a) { return (m[a.name] = a, m); }, {}) + ); + return util.vals(map).sort(function(a, b) { return a.idx - b.idx; }); + } + + function create(agg, stream, accessor, mutator) { + var all = resolve(agg, stream), + ctr = 'this.cell = cell; this.tuple = t; this.valid = 0; this.missing = 0;', + add = 'if (v==null) this.missing++; if (!this.isValid(v)) return; ++this.valid;', + rem = 'if (v==null) this.missing--; if (!this.isValid(v)) return; --this.valid;', + set = 'var t = this.tuple; var cell = this.cell;'; + + all.forEach(function(a) { + if (a.idx < 0) { + ctr = a.init + ctr; + add = a.add + add; + rem = a.rem + rem; + } else { + ctr += a.init; + add += a.add; + rem += a.rem; + } + }); + agg.slice() + .sort(function(a, b) { return a.idx - b.idx; }) + .forEach(function(a) { + set += 'this.assign(t,\''+a.out+'\','+a.set+');'; + }); + set += 'return t;'; + + /* jshint evil: true */ + ctr = Function('cell', 't', ctr); + ctr.prototype.assign = mutator; + ctr.prototype.add = Function('t', 'var v = this.get(t);' + add); + ctr.prototype.rem = Function('t', 'var v = this.get(t);' + rem); + ctr.prototype.set = Function(set); + ctr.prototype.get = accessor; + ctr.prototype.distinct = require('../stats').count.distinct; + ctr.prototype.isValid = util.isValid; + ctr.fields = agg.map(util.$('out')); + return ctr; + } + + types.create = create; + module.exports = types; + +},{"../stats":28,"../util":31}],13:[function(require,module,exports){ + var util = require('../util'), + time = require('../time'), + EPSILON = 1e-15; + + function bins(opt) { + if (!opt) { throw Error("Missing binning options."); } + + // determine range + var maxb = opt.maxbins || 15, + base = opt.base || 10, + logb = Math.log(base), + div = opt.div || [5, 2], + min = opt.min, + max = opt.max, + span = max - min, + step, level, minstep, precision, v, i, eps; + + if (opt.step) { + // if step size is explicitly given, use that + step = opt.step; + } else if (opt.steps) { + // if provided, limit choice to acceptable step sizes + step = opt.steps[Math.min( + opt.steps.length - 1, + bisect(opt.steps, span/maxb, 0, opt.steps.length) + )]; + } else { + // else use span to determine step size + level = Math.ceil(Math.log(maxb) / logb); + minstep = opt.minstep || 0; + step = Math.max( + minstep, + Math.pow(base, Math.round(Math.log(span) / logb) - level) + ); + + // increase step size if too many bins + do { step *= base; } while (Math.ceil(span/step) > maxb); + + // decrease step size if allowed + for (i=0; i= minstep && span / v <= maxb) step = v; + } + } + + // update precision, min and max + v = Math.log(step); + precision = v >= 0 ? 0 : ~~(-v / logb) + 1; + eps = Math.pow(base, -precision - 1); + min = Math.min(min, Math.floor(min / step + eps) * step); + max = Math.ceil(max / step) * step; + + return { + start: min, + stop: max, + step: step, + unit: {precision: precision}, + value: value, + index: index + }; + } + + function bisect(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (util.cmp(a[mid], x) < 0) { lo = mid + 1; } + else { hi = mid; } + } + return lo; + } + + function value(v) { + return this.step * Math.floor(v / this.step + EPSILON); + } + + function index(v) { + return Math.floor((v - this.start) / this.step + EPSILON); + } + + function date_value(v) { + return this.unit.date(value.call(this, v)); + } + + function date_index(v) { + return index.call(this, this.unit.unit(v)); + } + + bins.date = function(opt) { + if (!opt) { throw Error("Missing date binning options."); } + + // find time step, then bin + var units = opt.utc ? time.utc : time, + dmin = opt.min, + dmax = opt.max, + maxb = opt.maxbins || 20, + minb = opt.minbins || 4, + span = (+dmax) - (+dmin), + unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb), + spec = bins({ + min: unit.min != null ? unit.min : unit.unit(dmin), + max: unit.max != null ? unit.max : unit.unit(dmax), + maxbins: maxb, + minstep: unit.minstep, + steps: unit.step + }); + + spec.unit = unit; + spec.index = date_index; + if (!opt.raw) spec.value = date_value; + return spec; + }; + + module.exports = bins; + +},{"../time":30,"../util":31}],14:[function(require,module,exports){ + var bins = require('./bins'), + gen = require('../generate'), + type = require('../import/type'), + util = require('../util'), + stats = require('../stats'); + + var qtype = { + 'integer': 1, + 'number': 1, + 'date': 1 + }; + + function $bin(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return !b ? (opt.accessor || util.identity) : + util.$func('bin', b.unit.unit ? + function(x) { return b.value(b.unit.unit(x)); } : + function(x) { return b.value(x); } + )(opt.accessor); + } + + function histogram(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return b ? + numerical(values, opt.accessor, b) : + categorical(values, opt.accessor, opt && opt.sort); + } + + function spec(opt) { + var t = opt.type, b = null; + if (t == null || qtype[t]) { + if (t === 'integer' && opt.minstep == null) opt.minstep = 1; + b = (t === 'date') ? bins.date(opt) : bins(opt); + } + return b; + } + + function options() { + var a = arguments, + i = 0, + values = util.isArray(a[i]) ? a[i++] : null, + f = util.isFunction(a[i]) || util.isString(a[i]) ? util.$(a[i++]) : null, + opt = util.extend({}, a[i]); + + if (values) { + opt.type = opt.type || type(values, f); + if (qtype[opt.type]) { + var ext = stats.extent(values, f); + opt = util.extend({min: ext[0], max: ext[1]}, opt); + } + } + if (f) { opt.accessor = f; } + return opt; + } + + function numerical(values, f, b) { + var h = gen.range(b.start, b.stop + b.step/2, b.step) + .map(function(v) { return {value: b.value(v), count: 0}; }); + + for (var i=0, v, j; i= h.length || !isFinite(j)) continue; + h[j].count += 1; + } + } + h.bins = b; + return h; + } + + function categorical(values, f, sort) { + var u = stats.unique(values, f), + c = stats.count.map(values, f); + return u.map(function(k) { return {value: k, count: c[k]}; }) + .sort(util.comparator(sort ? '-count' : '+value')); + } + + module.exports = { + $bin: $bin, + histogram: histogram + }; + +},{"../generate":16,"../import/type":25,"../stats":28,"../util":31,"./bins":13}],15:[function(require,module,exports){ + var d3_time = require('d3-time'), + d3_timeF = require('d3-time-format'), + d3_numberF = require('d3-format'), + numberF = d3_numberF, // defaults to EN-US + timeF = d3_timeF; // defaults to EN-US + + function numberLocale(l) { + var f = d3_numberF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + numberF = f; + } + + function timeLocale(l) { + var f = d3_timeF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + timeF = f; + } + + module.exports = { + // Update number formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-format + numberLocale: numberLocale, + number: function(f) { return numberF.format(f); }, + numberPrefix: function(f, v) { return numberF.formatPrefix(f, v); }, + + // Update time formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-time-format + timeLocale: timeLocale, + time: function(f) { return timeF.format(f); }, + utc: function(f) { return timeF.utcFormat(f); }, + + // Set number and time locale simultaneously. + locale: function(l) { numberLocale(l); timeLocale(l); }, + + // automatic formatting functions + auto: { + number: numberAutoFormat, + time: function() { return timeAutoFormat(); }, + utc: function() { return utcAutoFormat(); } + } + }; + + var e10 = Math.sqrt(50), + e5 = Math.sqrt(10), + e2 = Math.sqrt(2); + + function intervals(domain, count) { + if (!domain.length) domain = [0]; + if (count == null) count = 10; + + var start = domain[0], + stop = domain[domain.length - 1]; + + if (stop < start) { error = stop; stop = start; start = error; } + + var span = (stop - start) || (count = 1, start || stop || 1), + step = Math.pow(10, Math.floor(Math.log(span / count) / Math.LN10)), + error = span / count / step; + + // Filter ticks to get closer to the desired count. + if (error >= e10) step *= 10; + else if (error >= e5) step *= 5; + else if (error >= e2) step *= 2; + + // Round start and stop values to step interval. + return [ + Math.ceil(start / step) * step, + Math.floor(stop / step) * step + step / 2, // inclusive + step + ]; + } + + function significantDigits(domain) { + return domain.map(function(x) { + // determine significant digits based on exponential format + var s = x.toExponential(), + e = s.indexOf('e'), + d = s.indexOf('.'); + return d < 0 ? 1 : (e-d); + }).reduce(function(max, p) { + // return the maximum sig digit count + return Math.max(max, p); + }, 0); + } + + function numberAutoFormat(domain, count, f) { + var range = intervals(domain, count); + if (f == null) { + f = ',.' + d3_numberF.precisionFixed(range[2]) + 'f'; + } else { + switch (f = d3_numberF.formatSpecifier(f), f.type) { + case 's': { + if (f.precision == null) f.precision = significantDigits(domain); + return numberF.format(f); + } + case '': + case 'e': + case 'g': + case 'p': + case 'r': { + if (f.precision == null) f.precision = d3_numberF.precisionRound(range[2], Math.max(Math.abs(range[0]), Math.abs(range[1]))) - (f.type === 'e'); + break; + } + case 'f': + case '%': { + if (f.precision == null) f.precision = d3_numberF.precisionFixed(range[2]) - (f.type === '%') * 2; + break; + } + } + } + return numberF.format(f); + } + + function timeAutoFormat() { + var f = timeF.format, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.second(date) < d ? formatMillisecond + : d3_time.minute(date) < d ? formatSecond + : d3_time.hour(date) < d ? formatMinute + : d3_time.day(date) < d ? formatHour + : d3_time.month(date) < d ? + (d3_time.week(date) < d ? formatDay : formatWeek) + : d3_time.year(date) < d ? formatMonth + : formatYear)(date); + }; + } + + function utcAutoFormat() { + var f = timeF.utcFormat, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.utcSecond(date) < d ? formatMillisecond + : d3_time.utcMinute(date) < d ? formatSecond + : d3_time.utcHour(date) < d ? formatMinute + : d3_time.utcDay(date) < d ? formatHour + : d3_time.utcMonth(date) < d ? + (d3_time.utcWeek(date) < d ? formatDay : formatWeek) + : d3_time.utcYear(date) < d ? formatMonth + : formatYear)(date); + }; + } + +},{"d3-format":6,"d3-time":8,"d3-time-format":7}],16:[function(require,module,exports){ + var gen = module.exports = {}; + + gen.repeat = function(val, n) { + var a = Array(n), i; + for (i=0; i stop) range.push(j); + else while ((j = start + step * ++i) < stop) range.push(j); + return range; + }; + + gen.random = {}; + + gen.random.uniform = function(min, max) { + if (max === undefined) { + max = min === undefined ? 1 : min; + min = 0; + } + var d = max - min; + var f = function() { + return min + d * Math.random(); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.integer = function(a, b) { + if (b === undefined) { + b = a; + a = 0; + } + var d = b - a; + var f = function() { + return a + Math.floor(d * Math.random()); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.normal = function(mean, stdev) { + mean = mean || 0; + stdev = stdev || 1; + var next; + var f = function() { + var x = 0, y = 0, rds, c; + if (next !== undefined) { + x = next; + next = undefined; + return x; + } + do { + x = Math.random()*2-1; + y = Math.random()*2-1; + rds = x*x + y*y; + } while (rds === 0 || rds > 1); + c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform + next = mean + y*c*stdev; + return mean + x*c*stdev; + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + +},{}],17:[function(require,module,exports){ + var util = require('../../util'); + var d3_dsv = require('d3-dsv'); + + function dsv(data, format) { + if (data) { + var h = format.header; + data = (h ? h.join(format.delimiter) + '\n' : '') + data; + } + return d3_dsv.dsv(format.delimiter).parse(data); + } + + dsv.delimiter = function(delim) { + var fmt = {delimiter: delim}; + return function(data, format) { + return dsv(data, format ? util.extend(format, fmt) : fmt); + }; + }; + + module.exports = dsv; + +},{"../../util":31,"d3-dsv":5}],18:[function(require,module,exports){ + var dsv = require('./dsv'); + + module.exports = { + json: require('./json'), + topojson: require('./topojson'), + treejson: require('./treejson'), + dsv: dsv, + csv: dsv.delimiter(','), + tsv: dsv.delimiter('\t') + }; + +},{"./dsv":17,"./json":19,"./topojson":20,"./treejson":21}],19:[function(require,module,exports){ + var util = require('../../util'); + + module.exports = function(data, format) { + var d = util.isObject(data) && !util.isBuffer(data) ? + data : JSON.parse(data); + if (format && format.property) { + d = util.accessor(format.property)(d); + } + return d; + }; + +},{"../../util":31}],20:[function(require,module,exports){ + (function (global){ + var json = require('./json'); + + var reader = function(data, format) { + var topojson = reader.topojson; + if (topojson == null) { throw Error('TopoJSON library not loaded.'); } + + var t = json(data, format), obj; + + if (format && format.feature) { + if ((obj = t.objects[format.feature])) { + return topojson.feature(t, obj).features; + } else { + throw Error('Invalid TopoJSON object: ' + format.feature); + } + } else if (format && format.mesh) { + if ((obj = t.objects[format.mesh])) { + return [topojson.mesh(t, t.objects[format.mesh])]; + } else { + throw Error('Invalid TopoJSON object: ' + format.mesh); + } + } else { + throw Error('Missing TopoJSON feature or mesh parameter.'); + } + }; + + reader.topojson = (typeof window !== "undefined" ? window['topojson'] : typeof global !== "undefined" ? global['topojson'] : null); + module.exports = reader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./json":19}],21:[function(require,module,exports){ + var json = require('./json'); + + module.exports = function(tree, format) { + return toTable(json(tree, format), format); + }; + + function toTable(root, fields) { + var childrenField = fields && fields.children || 'children', + parentField = fields && fields.parent || 'parent', + table = []; + + function visit(node, parent) { + node[parentField] = parent; + table.push(node); + var children = node[childrenField]; + if (children) { + for (var i=0; i 1 && domain[idx-1] === '.' && domain.lastIndexOf(d) === idx); + }); + if (!whiteListed) { + throw 'URL is not whitelisted: ' + url; + } + } + } + return url; + } + + function load(opt, callback) { + var error = callback || function(e) { throw e; }, url; + + try { + url = load.sanitizeUrl(opt); // enable override + } catch (err) { + error(err); + return; + } + + if (!url) { + error('Invalid URL: ' + opt.url); + } else if (load.useXHR) { + // on client, use xhr + return xhr(url, callback); + } else if (startsWith(url, fileProtocol)) { + // on server, if url starts with 'file://', strip it and load from file + return file(url.slice(fileProtocol.length), callback); + } else if (url.indexOf('://') < 0) { // TODO better protocol check? + // on server, if no protocol assume file + return file(url, callback); + } else { + // for regular URLs on server + return http(url, callback); + } + } + + function xhrHasResponse(request) { + var type = request.responseType; + return type && type !== 'text' ? + request.response : // null on error + request.responseText; // '' on error + } + + function xhr(url, callback) { + var async = !!callback; + var request = new XMLHttpRequest(); + // If IE does not support CORS, use XDomainRequest (copied from d3.xhr) + if (this.XDomainRequest && + !('withCredentials' in request) && + /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); + + function respond() { + var status = request.status; + if (!status && xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { + callback(null, request.responseText); + } else { + callback(request, null); + } + } + + if (async) { + if ('onload' in request) { + request.onload = request.onerror = respond; + } else { + request.onreadystatechange = function() { + if (request.readyState > 3) respond(); + }; + } + } + + request.open('GET', url, async); + request.send(); + + if (!async && xhrHasResponse(request)) { + return request.responseText; + } + } + + function file(filename, callback) { + var fs = require('fs'); + if (!callback) { + return fs.readFileSync(filename, 'utf8'); + } + fs.readFile(filename, callback); + } + + function http(url, callback) { + if (!callback) { + return require('sync-request')('GET', url).getBody(); + } + + var options = {url: url, encoding: null, gzip: true}; + require('request')(options, function(error, response, body) { + if (!error && response.statusCode === 200) { + callback(null, body); + } else { + error = error || + 'Load failed with response code ' + response.statusCode + '.'; + callback(error, null); + } + }); + } + + function startsWith(string, searchString) { + return string == null ? false : string.lastIndexOf(searchString, 0) === 0; + } + + load.sanitizeUrl = sanitizeUrl; + + load.useXHR = (typeof XMLHttpRequest !== 'undefined'); + + module.exports = load; + +},{"fs":2,"request":2,"sync-request":2,"url":2}],23:[function(require,module,exports){ + var util = require('../util'); + var type = require('./type'); + var formats = require('./formats'); + + function read(data, format) { + var type = (format && format.type) || 'json'; + data = formats[type](data, format); + if (format && format.parse) parse(data, format.parse); + return data; + } + + function parse(data, types) { + var cols, parsers, d, i, j, clen, len = data.length; + + types = (types==='auto') ? type.inferAll(data) : util.duplicate(types); + cols = util.keys(types); + parsers = cols.map(function(c) { return type.parsers[types[c]]; }); + + for (i=0, clen=cols.length; i 0 ? Math.min(l, opt.maxwidth) : l; + }); + + // print header row + var head = fields.map(function(name, i) { + return util.truncate(util.pad(name, lens[i], 'center'), lens[i]); + }).join(opt.separator); + + // build template function for each row + var tmpl = template(fields.map(function(name, i) { + return '{{' + + name + + (FMT[types[name]] || '') + + ('|pad:' + lens[i] + ',' + (POS[types[name]] || 'right')) + + ('|truncate:' + lens[i]) + + '}}'; + }).join(opt.separator)); + + // print table + return head + "\n" + data.map(tmpl).join('\n'); + }; + + module.exports.summary = function(s) { + s = s ? s.__summary__ ? s : stats.summary(s) : this; + var str = [], i, n; + for (i=0, n=s.length; i b) b = v; + } + } + return [a, b]; + }; + +// Find the integer indices of the minimum and maximum values. + stats.extent.index = function(values, f) { + f = util.$(f); + var x = -1, y = -1, a, b, v, i, n = values.length; + for (i=0; i b) { b = v; y = i; } + } + } + return [x, y]; + }; + +// Compute the dot product of two arrays of numbers. + stats.dot = function(values, a, b) { + var sum = 0, i, v; + if (!b) { + if (values.length !== a.length) { + throw Error('Array lengths must match.'); + } + for (i=0; i -1 && p !== v) { + mu = 1 + (i-1 + tie) / 2; + for (; tie -1) { + mu = 1 + (n-1 + tie) / 2; + for (; tie max) max = x; + delta = x - mean; + mean = mean + delta / (++valid); + M2 = M2 + delta * (x - mean); + vals.push(x); + } + } + M2 = M2 / (valid - 1); + sd = Math.sqrt(M2); + + // sort values for median and iqr + vals.sort(util.cmp); + + return { + type: type(values, f), + unique: u, + count: values.length, + valid: valid, + missing: missing, + distinct: distinct, + min: min, + max: max, + mean: mean, + stdev: sd, + median: (v = stats.quantile(vals, 0.5)), + q1: stats.quantile(vals, 0.25), + q3: stats.quantile(vals, 0.75), + modeskew: sd === 0 ? 0 : (mean - v) / sd + }; + }; + +// Compute profiles for all variables in a data set. + stats.summary = function(data, fields) { + fields = fields || util.keys(data[0]); + var s = fields.map(function(f) { + var p = stats.profile(data, util.$(f)); + return (p.field = f, p); + }); + return (s.__summary__ = true, s); + }; + + module.exports = stats; + +},{"./generate":16,"./import/type":25,"./util":31}],29:[function(require,module,exports){ + var util = require('./util'), + format = require('./format'); + + var context = { + formats: [], + format_map: {}, + truncate: util.truncate, + pad: util.pad + }; + + function template(text) { + var src = source(text, 'd'); + src = 'var __t; return ' + src + ';'; + + /* jshint evil: true */ + return (new Function('d', src)).bind(context); + } + + template.source = source; + template.context = context; + module.exports = template; + +// Clear cache of format objects. +// This can *break* prior template functions, so invoke with care! + template.clearFormatCache = function() { + context.formats = []; + context.format_map = {}; + }; + +// Generate property access code for use within template source. +// object: the name of the object (variable) containing template data +// property: the property access string, verbatim from template tag + template.property = function(object, property) { + var src = util.field(property).map(util.str).join(']['); + return object + '[' + src + ']'; + }; + +// Generate source code for a template function. +// text: the template text +// variable: the name of the data object variable ('obj' by default) +// properties: optional hash for collecting all accessed properties + function source(text, variable, properties) { + variable = variable || 'obj'; + var index = 0; + var src = '\''; + var regex = template_re; + + // Compile the template source, escaping string literals appropriately. + text.replace(regex, function(match, interpolate, offset) { + src += text + .slice(index, offset) + .replace(template_escaper, template_escapeChar); + index = offset + match.length; + + if (interpolate) { + src += '\'\n+((__t=(' + + template_var(interpolate, variable, properties) + + '))==null?\'\':__t)+\n\''; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + return src + '\''; + } + + function template_var(text, variable, properties) { + var filters = text.match(filter_re); + var prop = filters.shift().trim(); + var stringCast = true; + + function strcall(fn) { + fn = fn || ''; + if (stringCast) { + stringCast = false; + src = 'String(' + src + ')' + fn; + } else { + src += fn; + } + return src; + } + + function date() { + return '(typeof ' + src + '==="number"?new Date('+src+'):'+src+')'; + } + + function number_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+src+')'; + } + + function time_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+date()+')'; + } + + if (properties) properties[prop] = 1; + var src = template.property(variable, prop); + + for (var i=0; i 0) { + f = f.slice(0, pidx); + args = filters[i].slice(pidx+1) + .match(args_re) + .map(function(s) { return s.trim(); }); + } + f = f.trim(); + + switch (f) { + case 'length': + strcall('.length'); + break; + case 'lower': + strcall('.toLowerCase()'); + break; + case 'upper': + strcall('.toUpperCase()'); + break; + case 'lower-locale': + strcall('.toLocaleLowerCase()'); + break; + case 'upper-locale': + strcall('.toLocaleUpperCase()'); + break; + case 'trim': + strcall('.trim()'); + break; + case 'left': + a = util.number(args[0]); + strcall('.slice(0,' + a + ')'); + break; + case 'right': + a = util.number(args[0]); + strcall('.slice(-' + a +')'); + break; + case 'mid': + a = util.number(args[0]); + b = a + util.number(args[1]); + strcall('.slice(+'+a+','+b+')'); + break; + case 'slice': + a = util.number(args[0]); + strcall('.slice('+ a + + (args.length > 1 ? ',' + util.number(args[1]) : '') + + ')'); + break; + case 'truncate': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.truncate(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'pad': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.pad(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'number': + number_format(format.number, 'number'); + break; + case 'time': + time_format(format.time, 'time'); + break; + case 'time-utc': + time_format(format.utc, 'time-utc'); + break; + default: + throw Error('Unrecognized template filter: ' + f); + } + } + + return src; + } + + var template_re = /\{\{(.+?)\}\}|$/g, + filter_re = /(?:"[^"]*"|\'[^\']*\'|[^\|"]+|[^\|\']+)+/g, + args_re = /(?:"[^"]*"|\'[^\']*\'|[^,"]+|[^,\']+)+/g; + +// Certain characters need to be escaped so that they can be put into a +// string literal. + var template_escapes = { + '\'': '\'', + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var template_escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + function template_escapeChar(match) { + return '\\' + template_escapes[match]; + } + + function template_format(pattern, key, fmt) { + if ((pattern[0] === '\'' && pattern[pattern.length-1] === '\'') || + (pattern[0] === '"' && pattern[pattern.length-1] === '"')) { + pattern = pattern.slice(1, -1); + } else { + throw Error('Format pattern must be quoted: ' + pattern); + } + key = key + ':' + pattern; + if (!context.format_map[key]) { + var f = fmt(pattern); + var i = context.formats.length; + context.formats.push(f); + context.format_map[key] = i; + } + return context.format_map[key]; + } + +},{"./format":15,"./util":31}],30:[function(require,module,exports){ + var d3_time = require('d3-time'); + + var tempDate = new Date(), + baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD + utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0); + + function date(d) { + return (tempDate.setTime(+d), tempDate); + } + +// create a time unit entry + function entry(type, date, unit, step, min, max) { + var e = { + type: type, + date: date, + unit: unit + }; + if (step) { + e.step = step; + } else { + e.minstep = 1; + } + if (min != null) e.min = min; + if (max != null) e.max = max; + return e; + } + + function create(type, unit, base, step, min, max) { + return entry(type, + function(d) { return unit.offset(base, d); }, + function(d) { return unit.count(base, d); }, + step, min, max); + } + + var locale = [ + create('second', d3_time.second, baseDate), + create('minute', d3_time.minute, baseDate), + create('hour', d3_time.hour, baseDate), + create('day', d3_time.day, baseDate, [1, 7]), + create('month', d3_time.month, baseDate, [1, 3, 6]), + create('year', d3_time.year, baseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(1970, 0, 1, 0, 0, d); }, + function(d) { return date(d).getSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(1970, 0, 1, 0, d); }, + function(d) { return date(d).getMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(1970, 0, 1, d); }, + function(d) { return date(d).getHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(1970, 0, 4+d); }, + function(d) { return date(d).getDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(1970, 0, d); }, + function(d) { return date(d).getDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(1970, d % 12, 1); }, + function(d) { return date(d).getMonth(); }, + [1], 0, 11 + ) + ]; + + var utc = [ + create('second', d3_time.utcSecond, utcBaseDate), + create('minute', d3_time.utcMinute, utcBaseDate), + create('hour', d3_time.utcHour, utcBaseDate), + create('day', d3_time.utcDay, utcBaseDate, [1, 7]), + create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]), + create('year', d3_time.utcYear, utcBaseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); }, + function(d) { return date(d).getUTCSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); }, + function(d) { return date(d).getUTCMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(Date.UTC(1970, 0, 1, d)); }, + function(d) { return date(d).getUTCHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(Date.UTC(1970, 0, 4+d)); }, + function(d) { return date(d).getUTCDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(Date.UTC(1970, 0, d)); }, + function(d) { return date(d).getUTCDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(Date.UTC(1970, d % 12, 1)); }, + function(d) { return date(d).getUTCMonth(); }, + [1], 0, 11 + ) + ]; + + var STEPS = [ + [31536e6, 5], // 1-year + [7776e6, 4], // 3-month + [2592e6, 4], // 1-month + [12096e5, 3], // 2-week + [6048e5, 3], // 1-week + [1728e5, 3], // 2-day + [864e5, 3], // 1-day + [432e5, 2], // 12-hour + [216e5, 2], // 6-hour + [108e5, 2], // 3-hour + [36e5, 2], // 1-hour + [18e5, 1], // 30-minute + [9e5, 1], // 15-minute + [3e5, 1], // 5-minute + [6e4, 1], // 1-minute + [3e4, 0], // 30-second + [15e3, 0], // 15-second + [5e3, 0], // 5-second + [1e3, 0] // 1-second + ]; + + function find(units, span, minb, maxb) { + var step = STEPS[0], i, n, bins; + + for (i=1, n=STEPS.length; i step[0]) { + bins = span / step[0]; + if (bins > maxb) { + return units[STEPS[i-1][1]]; + } + if (bins >= minb) { + return units[step[1]]; + } + } + } + return units[STEPS[n-1][1]]; + } + + function toUnitMap(units) { + var map = {}, i, n; + for (i=0, n=units.length; i 1 ? + function(x) { return s.reduce(function(x,f) { return x[f]; }, x); } : + function(x) { return x[f]; } + ); + }; + +// short-cut for accessor + u.$ = u.accessor; + + u.mutator = function(f) { + var s; + return u.isString(f) && (s=u.field(f)).length > 1 ? + function(x, v) { + for (var i=0; i y) return sign[i]; + } + return 0; + }; + }; + + u.cmp = function(a, b) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a >= b) { + return 0; + } else if (a === null) { + return -1; + } else if (b === null) { + return 1; + } + return NaN; + }; + + u.numcmp = function(a, b) { return a - b; }; + + u.stablesort = function(array, sortBy, keyFn) { + var indices = array.reduce(function(idx, v, i) { + return (idx[keyFn(v)] = i, idx); + }, {}); + + array.sort(function(a, b) { + var sa = sortBy(a), + sb = sortBy(b); + return sa < sb ? -1 : sa > sb ? 1 + : (indices[keyFn(a)] - indices[keyFn(b)]); + }); + + return array; + }; + + +// string functions + + u.pad = function(s, length, pos, padchar) { + padchar = padchar || " "; + var d = length - s.length; + if (d <= 0) return s; + switch (pos) { + case 'left': + return strrep(d, padchar) + s; + case 'middle': + case 'center': + return strrep(Math.floor(d/2), padchar) + + s + strrep(Math.ceil(d/2), padchar); + default: + return s + strrep(d, padchar); + } + }; + + function strrep(n, str) { + var s = "", i; + for (i=0; i 1) { + for (var i=1, n=ref.length; i 0) { + node = pq.peek(); + pulse = pulses[node._id]; + + if (node.rank() !== node.qrank()) { + // A node's rank might change during a propagation. Re-queue if so. + pq.replace(node.qrank(true)); + } else { + // Evaluate node and propagate pulse. + pq.pop(); + pulses[node._id] = null; + listeners = node._listeners; + pulse = this.evaluate(pulse, node); + + // Propagate the pulse. + if (pulse !== this.doNotPropagate) { + // Ensure reflow pulses always send reflow pulses even if skipped. + if (!pulse.reflow && node.reflows()) { + pulse = ChangeSet.create(pulse, true); + } + + for (i=0, len=listeners.length; i 0) branch[i-1].addListener(node); + } + + return branch; + }; + + prototype.disconnect = function(branch) { + var collector, node, data, signals, i, n, j, m; + + for (i=0, n=branch.length; i= pulse.stamp, + run = node.router() || pulse.add.length || pulse.rem.length; + + return run || !reflowed || node.reevaluate(pulse); + }; + + prototype.evaluate = function(pulse, node) { + if (!this.reevaluate(pulse, node)) return pulse; + pulse = node.evaluate(pulse); + node.last(pulse.stamp); + return pulse; + }; + + module.exports = Graph; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Heap":37,"./Signal":39,"./Tuple":40,"datalib":26}],37:[function(require,module,exports){ + function Heap(comparator) { + this.cmp = comparator; + this.nodes = []; + } + + var prototype = Heap.prototype; + + prototype.size = function() { + return this.nodes.length; + }; + + prototype.clear = function() { + return (this.nodes = [], this); + }; + + prototype.peek = function() { + return this.nodes[0]; + }; + + prototype.push = function(x) { + var array = this.nodes; + array.push(x); + return _siftdown(array, 0, array.length-1, this.cmp); + }; + + prototype.pop = function() { + var array = this.nodes, + last = array.pop(), + item; + + if (array.length) { + item = array[0]; + array[0] = last; + _siftup(array, 0, this.cmp); + } else { + item = last; + } + return item; + }; + + prototype.replace = function(item) { + var array = this.nodes, + retval = array[0]; + array[0] = item; + _siftup(array, 0, this.cmp); + return retval; + }; + + prototype.pushpop = function(item) { + var array = this.nodes, ref = array[0]; + if (array.length && this.cmp(ref, item) < 0) { + array[0] = item; + item = ref; + _siftup(array, 0, this.cmp); + } + return item; + }; + + function _siftdown(array, start, idx, cmp) { + var item, parent, pidx; + + item = array[idx]; + while (idx > start) { + pidx = (idx - 1) >> 1; + parent = array[pidx]; + if (cmp(item, parent) < 0) { + array[idx] = parent; + idx = pidx; + continue; + } + break; + } + return (array[idx] = item); + } + + function _siftup(array, idx, cmp) { + var start = idx, + end = array.length, + item = array[idx], + cidx = 2 * idx + 1, ridx; + + while (cidx < end) { + ridx = cidx + 1; + if (ridx < end && cmp(array[cidx], array[ridx]) >= 0) { + cidx = ridx; + } + array[idx] = array[cidx]; + idx = cidx; + cidx = 2 * idx + 1; + } + array[idx] = item; + return _siftdown(array, start, idx, cmp); + } + + module.exports = Heap; + +},{}],38:[function(require,module,exports){ + var DEPS = require('./Dependencies').ALL, + nodeID = 0; + + function Node(graph) { + if (graph) this.init(graph); + } + + var Flags = Node.Flags = { + Router: 0x01, // Responsible for propagating tuples, cannot be skipped. + Collector: 0x02, // Holds a materialized dataset, pulse node to reflow. + Produces: 0x04, // Produces new tuples. + Mutates: 0x08, // Sets properties of incoming tuples. + Reflows: 0x10, // Forwards a reflow pulse. + Batch: 0x20 // Performs batch data processing, needs collector. + }; + + var prototype = Node.prototype; + + prototype.init = function(graph) { + this._id = ++nodeID; + this._graph = graph; + this._rank = graph.rank(); // Topological sort by rank + this._qrank = null; // Rank when enqueued for propagation + this._stamp = 0; // Last stamp seen + + this._listeners = []; + this._listeners._ids = {}; // To prevent duplicate listeners + + // Initialize dependencies. + this._deps = {}; + for (var i=0, n=DEPS.length; i l._rank) { + l.rerank(); + } + + return this; + }; + + prototype.removeListener = function(l) { + if (!this._listeners._ids[l._id]) return false; + + var idx = this._listeners.indexOf(l), + b = idx >= 0; + + if (b) { + this._listeners.splice(idx, 1); + this._listeners._ids[l._id] = null; + } + return b; + }; + + prototype.disconnect = function() { + this._listeners = []; + this._listeners._ids = {}; + }; + +// Evaluate this dataflow node for the current pulse. +// Subclasses should override to perform custom processing. + prototype.evaluate = function(pulse) { + return pulse; + }; + +// Should this node be re-evaluated for the current pulse? +// Searches pulse to see if any dependencies have updated. + prototype.reevaluate = function(pulse) { + var prop, dep, i, n, j, m; + + for (i=0, n=DEPS.length; i=0;) { + if (!handler || h[i].handler === handler) { + x = h.splice(i, 1)[0]; + this.removeListener(x.node); + } + } + + return this; + }; + + module.exports = Signal; + +},{"./ChangeSet":32,"./Node":38}],40:[function(require,module,exports){ + var tupleID = 0; + + function ingest(datum) { + datum = (datum === Object(datum)) ? datum : {data: datum}; + datum._id = ++tupleID; + if (datum._prev) datum._prev = null; + return datum; + } + + function idMap(a, ids) { + ids = ids || {}; + for (var i=0, n=a.length; i0;) { + idMap(arguments[i], ids); + } + return data.filter(function(x) { return !ids[x._id]; }); + } + }; + +},{}],41:[function(require,module,exports){ + module.exports = { + ChangeSet: require('./ChangeSet'), + Collector: require('./Collector'), + DataSource: require('./DataSource'), + Dependencies: require('./Dependencies'), + Graph: require('./Graph'), + Node: require('./Node'), + Signal: require('./Signal'), + Tuple: require('./Tuple'), + debug: require('vega-logging').debug + }; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Graph":36,"./Node":38,"./Signal":39,"./Tuple":40,"vega-logging":47}],42:[function(require,module,exports){ + function toMap(list) { + var map = {}, i, n; + for (i=0, n=list.length; i 0) { + return id; + } + if (constants.hasOwnProperty(id)) { + return constants[id]; + } + if (idWhiteList) { + if (idWhiteList.hasOwnProperty(id)) { + return id; + } else { + globals[id] = 1; + return lookupGlobal(id); + } + } + if (idBlackList && idBlackList.hasOwnProperty(id)) { + throw new Error('Illegal identifier: ' + id); + } + return id; + }, + 'Program': function(n) { + return n.body.map(codegen).join('\n'); + }, + 'MemberExpression': function(n) { + var d = !n.computed; + var o = codegen(n.object); + if (d) memberDepth += 1; + var p = codegen(n.property); + if (o === FIELD_VAR) { fields[p] = 1; } // HACKish... + if (d) memberDepth -= 1; + return o + (d ? '.'+p : '['+p+']'); + }, + 'CallExpression': function(n) { + if (n.callee.type !== 'Identifier') { + throw new Error('Illegal callee type: ' + n.callee.type); + } + var callee = n.callee.name; + var args = n.arguments; + var fn = functions.hasOwnProperty(callee) && functions[callee]; + if (!fn) throw new Error('Unrecognized function: ' + callee); + return fn instanceof Function ? + fn(args) : + fn + '(' + args.map(codegen).join(',') + ')'; + }, + 'ArrayExpression': function(n) { + return '[' + n.elements.map(codegen).join(',') + ']'; + }, + 'BinaryExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'UnaryExpression': function(n) { + return '(' + n.operator + codegen(n.argument) + ')'; + }, + 'ConditionalExpression': function(n) { + return '(' + codegen(n.test) + + '?' + codegen(n.consequent) + + ':' + codegen(n.alternate) + + ')'; + }, + 'LogicalExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'ObjectExpression': function(n) { + return '{' + n.properties.map(codegen).join(',') + '}'; + }, + 'Property': function(n) { + memberDepth += 1; + var k = codegen(n.key); + memberDepth -= 1; + return k + ':' + codegen(n.value); + }, + 'ExpressionStatement': function(n) { + return codegen(n.expression); + } + }; + + codegen_wrap.functions = functions; + codegen_wrap.constants = constants; + return codegen_wrap; + }; + +},{"./constants":43,"./functions":44}],43:[function(require,module,exports){ + module.exports = { + 'NaN': 'NaN', + 'E': 'Math.E', + 'LN2': 'Math.LN2', + 'LN10': 'Math.LN10', + 'LOG2E': 'Math.LOG2E', + 'LOG10E': 'Math.LOG10E', + 'PI': 'Math.PI', + 'SQRT1_2': 'Math.SQRT1_2', + 'SQRT2': 'Math.SQRT2' + }; +},{}],44:[function(require,module,exports){ + module.exports = function(codegen) { + + function fncall(name, args, cast, type) { + var obj = codegen(args[0]); + if (cast) { + obj = cast + '(' + obj + ')'; + if (cast.lastIndexOf('new ', 0) === 0) obj = '(' + obj + ')'; + } + return obj + '.' + name + (type < 0 ? '' : type === 0 ? + '()' : + '(' + args.slice(1).map(codegen).join(',') + ')'); + } + + function fn(name, cast, type) { + return function(args) { + return fncall(name, args, cast, type); + }; + } + + var DATE = 'new Date', + STRING = 'String', + REGEXP = 'RegExp'; + + return { + // MATH functions + 'isNaN': 'isNaN', + 'isFinite': 'isFinite', + 'abs': 'Math.abs', + 'acos': 'Math.acos', + 'asin': 'Math.asin', + 'atan': 'Math.atan', + 'atan2': 'Math.atan2', + 'ceil': 'Math.ceil', + 'cos': 'Math.cos', + 'exp': 'Math.exp', + 'floor': 'Math.floor', + 'log': 'Math.log', + 'max': 'Math.max', + 'min': 'Math.min', + 'pow': 'Math.pow', + 'random': 'Math.random', + 'round': 'Math.round', + 'sin': 'Math.sin', + 'sqrt': 'Math.sqrt', + 'tan': 'Math.tan', + + 'clamp': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to clamp function.'); + if (args.length > 3) + throw new Error('Too many arguments to clamp function.'); + var a = args.map(codegen); + return 'Math.max('+a[1]+', Math.min('+a[2]+','+a[0]+'))'; + }, + + // DATE functions + 'now': 'Date.now', + 'datetime': DATE, + 'date': fn('getDate', DATE, 0), + 'day': fn('getDay', DATE, 0), + 'year': fn('getFullYear', DATE, 0), + 'month': fn('getMonth', DATE, 0), + 'hours': fn('getHours', DATE, 0), + 'minutes': fn('getMinutes', DATE, 0), + 'seconds': fn('getSeconds', DATE, 0), + 'milliseconds': fn('getMilliseconds', DATE, 0), + 'time': fn('getTime', DATE, 0), + 'timezoneoffset': fn('getTimezoneOffset', DATE, 0), + 'utcdate': fn('getUTCDate', DATE, 0), + 'utcday': fn('getUTCDay', DATE, 0), + 'utcyear': fn('getUTCFullYear', DATE, 0), + 'utcmonth': fn('getUTCMonth', DATE, 0), + 'utchours': fn('getUTCHours', DATE, 0), + 'utcminutes': fn('getUTCMinutes', DATE, 0), + 'utcseconds': fn('getUTCSeconds', DATE, 0), + 'utcmilliseconds': fn('getUTCMilliseconds', DATE, 0), + + // shared sequence functions + 'length': fn('length', null, -1), + 'indexof': fn('indexOf', null), + 'lastindexof': fn('lastIndexOf', null), + + // STRING functions + 'parseFloat': 'parseFloat', + 'parseInt': 'parseInt', + 'upper': fn('toUpperCase', STRING, 0), + 'lower': fn('toLowerCase', STRING, 0), + 'slice': fn('slice', STRING), + 'substring': fn('substring', STRING), + + // REGEXP functions + 'regexp': REGEXP, + 'test': fn('test', REGEXP), + + // Control Flow functions + 'if': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to if function.'); + if (args.length > 3) + throw new Error('Too many arguments to if function.'); + var a = args.map(codegen); + return a[0]+'?'+a[1]+':'+a[2]; + } + }; + }; +},{}],45:[function(require,module,exports){ + var parser = require('./parser'), + codegen = require('./codegen'); + + var expr = module.exports = { + parse: function(input, opt) { + return parser.parse('('+input+')', opt); + }, + code: function(opt) { + return codegen(opt); + }, + compiler: function(args, opt) { + args = args.slice(); + var generator = codegen(opt), + len = args.length, + compile = function(str) { + var value = generator(expr.parse(str)); + args[len] = '"use strict"; return (' + value.code + ');'; + value.fn = Function.apply(null, args); + return value; + }; + compile.codegen = generator; + return compile; + }, + functions: require('./functions'), + constants: require('./constants') + }; + +},{"./codegen":42,"./constants":43,"./functions":44,"./parser":46}],46:[function(require,module,exports){ + /* + The following expression parser is based on Esprima (http://esprima.org/). + Original header comment and license for Esprima is included here: + + Copyright (C) 2013 Ariya Hidayat + Copyright (C) 2013 Thaddee Tyl + Copyright (C) 2013 Mathias Bynens + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* istanbul ignore next */ + module.exports = (function() { + 'use strict'; + + var Token, + TokenName, + Syntax, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + lookahead, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8, + RegularExpression: 9 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + TokenName[Token.RegularExpression] = 'RegularExpression'; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BinaryExpression: 'BinaryExpression', + CallExpression: 'CallExpression', + ConditionalExpression: 'ConditionalExpression', + ExpressionStatement: 'ExpressionStatement', + Identifier: 'Identifier', + Literal: 'Literal', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + UnaryExpression: 'UnaryExpression' + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), + NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); + } + + function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + default: + return false; + } + } + + function isStrictModeReservedWord(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + default: + return false; + } + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + // 'const' is specialized as Keyword in V8. + // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next. + // Some others are from future reserved words. + + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || + (id === 'try') || (id === 'let'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + function skipComment() { + var ch, start; + + start = (index === 0); + while (index < length) { + ch = source.charCodeAt(index); + + if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { + ++index; + } + ++lineNumber; + lineStart = index; + start = true; + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanUnicodeCodePointEscape() { + var ch, code, cu1, cu2; + + ch = source[index]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + while (index < length) { + ch = source[index++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // UTF-16 Encoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } + cu1 = ((code - 0x10000) >> 10) + 0xD800; + cu2 = ((code - 0x10000) & 1023) + 0xDC00; + return String.fromCharCode(cu1, cu2); + } + + function getEscapedIdentifier() { + var ch, id; + + ch = source.charCodeAt(index++); + id = String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id = ch; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (!isIdentifierPart(ch)) { + break; + } + ++index; + id += String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + id = id.substr(0, id.length - 1); + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id += ch; + } + } + + return id; + } + + function getIdentifier() { + var start, ch; + + start = index++; + while (index < length) { + ch = source.charCodeAt(index); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index = start; + return getEscapedIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index; + } else { + break; + } + } + + return source.slice(start, index); + } + + function scanIdentifier() { + var start, id, type; + + start = index; + + // Backslash (U+005C) starts an escaped character. + id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = Token.Identifier; + } else if (isKeyword(id)) { + type = Token.Keyword; + } else if (id === 'null') { + type = Token.NullLiteral; + } else if (id === 'true' || id === 'false') { + type = Token.BooleanLiteral; + } else { + type = Token.Identifier; + } + + return { + type: type, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + code = source.charCodeAt(index), + code2, + ch1 = source[index], + ch2, + ch3, + ch4; + + switch (code) { + + // Check for most common single-character punctuators. + case 0x2E: // . dot + case 0x28: // ( open bracket + case 0x29: // ) close bracket + case 0x3B: // ; semicolon + case 0x2C: // , comma + case 0x7B: // { open curly brace + case 0x7D: // } close curly brace + case 0x5B: // [ + case 0x5D: // ] + case 0x3A: // : + case 0x3F: // ? + case 0x7E: // ~ + ++index; + if (extra.tokenize) { + if (code === 0x28) { + extra.openParenToken = extra.tokens.length; + } else if (code === 0x7B) { + extra.openCurlyToken = extra.tokens.length; + } + } + return { + type: Token.Punctuator, + value: String.fromCharCode(code), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + default: + code2 = source.charCodeAt(index + 1); + + // '=' (U+003D) marks an assignment or comparison operator. + if (code2 === 0x3D) { + switch (code) { + case 0x2B: // + + case 0x2D: // - + case 0x2F: // / + case 0x3C: // < + case 0x3E: // > + case 0x5E: // ^ + case 0x7C: // | + case 0x25: // % + case 0x26: // & + case 0x2A: // * + index += 2; + return { + type: Token.Punctuator, + value: String.fromCharCode(code) + String.fromCharCode(code2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + case 0x21: // ! + case 0x3D: // = + index += 2; + + // !== and === + if (source.charCodeAt(index) === 0x3D) { + ++index; + } + return { + type: Token.Punctuator, + value: source.slice(start, index), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + } + } + + // 4-character punctuator: >>>= + + ch4 = source.substr(index, 4); + + if (ch4 === '>>>=') { + index += 4; + return { + type: Token.Punctuator, + value: ch4, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + ch3 = ch4.substr(0, 3); + + if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') { + index += 3; + return { + type: Token.Punctuator, + value: ch3, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // Other 2-character punctuators: ++ -- << >> && || + ch2 = ch3.substr(0, 2); + + if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') { + index += 2; + return { + type: Token.Punctuator, + value: ch2, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 1-character punctuators: < > = ! + - * % & | ^ / + + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // 7.8.3 Numeric Literals + + function scanHexLiteral(start) { + var number = ''; + + while (index < length) { + if (!isHexDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt('0x' + number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanOctalLiteral(start) { + var number = '0' + source[index++]; + while (index < length) { + if (!isOctalDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: true, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index; + return scanHexLiteral(start); + } + if (isOctalDigit(ch)) { + return scanOctalLiteral(start); + } + + // decimal number starts with '0' such as '09' is illegal. + if (ch && isDecimalDigit(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === '.') { + number += source[index++]; + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + if (isDecimalDigit(source.charCodeAt(index))) { + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + } else { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart; + startLineNumber = lineNumber; + startLineStart = lineStart; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + str += scanUnicodeCodePointEscape(); + } else { + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + startLineNumber: startLineNumber, + startLineStart: startLineStart, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function testRegExp(pattern, flags) { + var tmp = pattern, + value; + + if (flags.indexOf('u') >= 0) { + // Replace each astral symbol and every Unicode code point + // escape sequence with a single ASCII symbol to avoid throwing on + // regular expressions that are only valid in combination with the + // `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it + // would be replaced by `[x-b]` which throws an error. + tmp = tmp + .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) { + if (parseInt($1, 16) <= 0x10FFFF) { + return 'x'; + } + throwError({}, Messages.InvalidRegExp); + }) + .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); + } + + // First, detect invalid regular expressions. + try { + value = new RegExp(tmp); + } catch (e) { + throwError({}, Messages.InvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + return null; + } + } + + function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + classMarker = false; + terminated = false; + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwError({}, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; + } + + function scanRegExpFlags() { + var ch, str, flags, restore; + + str = ''; + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + for (str += '\\u'; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } else { + str += '\\'; + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + flags += ch; + str += ch; + } + } + + return { + value: flags, + literal: str + }; + } + + function scanRegExp() { + var start, body, flags, value; + + lookahead = null; + skipComment(); + start = index; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + + if (extra.tokenize) { + return { + type: Token.RegularExpression, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index + }; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = scanRegExp(); + + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (!extra.tokenize) { + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + regex: regex.regex, + range: [pos, index], + loc: loc + }); + } + + return regex; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advanceSlash() { + var prevToken, + checkToken; + // Using the following algorithm: + // https://github.com/mozilla/sweet.js/wiki/design + prevToken = extra.tokens[extra.tokens.length - 1]; + if (!prevToken) { + // Nothing before that: it cannot be a division. + return collectRegex(); + } + if (prevToken.type === 'Punctuator') { + if (prevToken.value === ']') { + return scanPunctuator(); + } + if (prevToken.value === ')') { + checkToken = extra.tokens[extra.openParenToken - 1]; + if (checkToken && + checkToken.type === 'Keyword' && + (checkToken.value === 'if' || + checkToken.value === 'while' || + checkToken.value === 'for' || + checkToken.value === 'with')) { + return collectRegex(); + } + return scanPunctuator(); + } + if (prevToken.value === '}') { + // Dividing a function by anything makes little sense, + // but we have to check for that. + if (extra.tokens[extra.openCurlyToken - 3] && + extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { + // Anonymous function. + checkToken = extra.tokens[extra.openCurlyToken - 4]; + if (!checkToken) { + return scanPunctuator(); + } + } else if (extra.tokens[extra.openCurlyToken - 4] && + extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { + // Named function. + checkToken = extra.tokens[extra.openCurlyToken - 5]; + if (!checkToken) { + return collectRegex(); + } + } else { + return scanPunctuator(); + } + return scanPunctuator(); + } + return collectRegex(); + } + if (prevToken.type === 'Keyword' && prevToken.value !== 'this') { + return collectRegex(); + } + return scanPunctuator(); + } + + function advance() { + var ch; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + } + + ch = source.charCodeAt(index); + + if (isIdentifierStart(ch)) { + return scanIdentifier(); + } + + // Very common: ( and ) and ; + if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (ch === 0x27 || ch === 0x22) { + return scanStringLiteral(); + } + + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (ch === 0x2E) { + if (isDecimalDigit(source.charCodeAt(index + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + // Slash (/) U+002F can also start a regex. + if (extra.tokenize && ch === 0x2F) { + return advanceSlash(); + } + + return scanPunctuator(); + } + + function collectToken() { + var loc, token, value, entry; + + skipComment(); + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + value = source.slice(token.start, token.end); + entry = { + type: TokenName[token.type], + value: value, + range: [token.start, token.end], + loc: loc + }; + if (token.regex) { + entry.regex = { + pattern: token.regex.pattern, + flags: token.regex.flags + }; + } + extra.tokens.push(entry); + } + + return token; + } + + function lex() { + var token; + + token = lookahead; + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + return token; + } + + function peek() { + var pos, line, start; + + pos = index; + line = lineNumber; + start = lineStart; + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + index = pos; + lineNumber = line; + lineStart = start; + } + + function Position() { + this.line = lineNumber; + this.column = index - lineStart; + } + + function SourceLocation() { + this.start = new Position(); + this.end = null; + } + + function WrappingSourceLocation(startToken) { + if (startToken.type === Token.StringLiteral) { + this.start = { + line: startToken.startLineNumber, + column: startToken.start - startToken.startLineStart + }; + } else { + this.start = { + line: startToken.lineNumber, + column: startToken.start - startToken.lineStart + }; + } + this.end = null; + } + + function Node() { + // Skip comment. + index = lookahead.start; + if (lookahead.type === Token.StringLiteral) { + lineNumber = lookahead.startLineNumber; + lineStart = lookahead.startLineStart; + } else { + lineNumber = lookahead.lineNumber; + lineStart = lookahead.lineStart; + } + if (extra.range) { + this.range = [index, 0]; + } + if (extra.loc) { + this.loc = new SourceLocation(); + } + } + + function WrappingNode(startToken) { + if (extra.range) { + this.range = [startToken.start, 0]; + } + if (extra.loc) { + this.loc = new WrappingSourceLocation(startToken); + } + } + + WrappingNode.prototype = Node.prototype = { + + finish: function () { + if (extra.range) { + this.range[1] = index; + } + if (extra.loc) { + this.loc.end = new Position(); + if (extra.source) { + this.loc.source = extra.source; + } + } + }, + + finishArrayExpression: function (elements) { + this.type = Syntax.ArrayExpression; + this.elements = elements; + this.finish(); + return this; + }, + + finishAssignmentExpression: function (operator, left, right) { + this.type = Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBinaryExpression: function (operator, left, right) { + this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishCallExpression: function (callee, args) { + this.type = Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishConditionalExpression: function (test, consequent, alternate) { + this.type = Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishExpressionStatement: function (expression) { + this.type = Syntax.ExpressionStatement; + this.expression = expression; + this.finish(); + return this; + }, + + finishIdentifier: function (name) { + this.type = Syntax.Identifier; + this.name = name; + this.finish(); + return this; + }, + + finishLiteral: function (token) { + this.type = Syntax.Literal; + this.value = token.value; + this.raw = source.slice(token.start, token.end); + if (token.regex) { + if (this.raw == '//') { + this.raw = '/(?:)/'; + } + this.regex = token.regex; + } + this.finish(); + return this; + }, + + finishMemberExpression: function (accessor, object, property) { + this.type = Syntax.MemberExpression; + this.computed = accessor === '['; + this.object = object; + this.property = property; + this.finish(); + return this; + }, + + finishObjectExpression: function (properties) { + this.type = Syntax.ObjectExpression; + this.properties = properties; + this.finish(); + return this; + }, + + finishProgram: function (body) { + this.type = Syntax.Program; + this.body = body; + this.finish(); + return this; + }, + + finishProperty: function (kind, key, value) { + this.type = Syntax.Property; + this.key = key; + this.value = value; + this.kind = kind; + this.finish(); + return this; + }, + + finishUnaryExpression: function (operator, argument) { + this.type = Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + this.finish(); + return this; + } + }; + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + // Throw an exception + + function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function (whole, index) { + assert(index < args.length, 'Message reference must be in range'); + return args[index]; + } + ); + + if (typeof token.lineNumber === 'number') { + error = new Error('Line ' + token.lineNumber + ': ' + msg); + error.index = token.start; + error.lineNumber = token.lineNumber; + error.column = token.start - lineStart + 1; + } else { + error = new Error('Line ' + lineNumber + ': ' + msg); + error.index = index; + error.lineNumber = lineNumber; + error.column = index - lineStart + 1; + } + + error.description = msg; + throw error; + } + + function throwErrorTolerant() { + try { + throwError.apply(null, arguments); + } catch (e) { + if (extra.errors) { + extra.errors.push(e); + } else { + throw e; + } + } + } + + + // Throw an exception because of the token. + + function throwUnexpected(token) { + if (token.type === Token.EOF) { + throwError(token, Messages.UnexpectedEOS); + } + + if (token.type === Token.NumericLiteral) { + throwError(token, Messages.UnexpectedNumber); + } + + if (token.type === Token.StringLiteral) { + throwError(token, Messages.UnexpectedString); + } + + if (token.type === Token.Identifier) { + throwError(token, Messages.UnexpectedIdentifier); + } + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + throwError(token, Messages.UnexpectedReserved); + } else if (strict && isStrictModeReservedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictReservedWord); + return; + } + throwError(token, Messages.UnexpectedToken, token.value); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, Messages.UnexpectedToken, token.value); + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpected(token); + } + } + + /** + * @name expectTolerant + * @description Quietly expect the given token value when in tolerant mode, otherwise delegates + * to expect(value) + * @param {String} value The value we are expecting the lookahead token to have + * @since 2.0 + */ + function expectTolerant(value) { + if (extra.errors) { + var token = lookahead; + if (token.type !== Token.Punctuator && token.value !== value) { + throwErrorTolerant(token, Messages.UnexpectedToken, token.value); + } else { + lex(); + } + } else { + expect(value); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + return lookahead.type === Token.Punctuator && lookahead.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + return lookahead.type === Token.Keyword && lookahead.value === keyword; + } + + function consumeSemicolon() { + var line; + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(index) === 0x3B || match(';')) { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + return; + } + + if (lookahead.type !== Token.EOF && !match('}')) { + throwUnexpected(lookahead); + } + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = [], node = new Node(); + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return node.finishArrayExpression(elements); + } + + // 11.1.5 Object Initialiser + + function parseObjectPropertyKey() { + var token, node = new Node(); + + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return node.finishLiteral(token); + } + + return node.finishIdentifier(token.value); + } + + function parseObjectProperty() { + var token, key, id, value, node = new Node(); + + token = lookahead; + + if (token.type === Token.Identifier) { + id = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', id, value); + } + if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', key, value); + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, key, kind, map = {}, toString = String, node = new Node(); + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + + key = '$' + name; + if (Object.prototype.hasOwnProperty.call(map, key)) { + if (map[key] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } else if (map[key] & kind) { + throwErrorTolerant({}, Messages.AccessorGetSet); + } + } + map[key] |= kind; + } else { + map[key] = kind; + } + + properties.push(property); + + if (!match('}')) { + expectTolerant(','); + } + } + + expect('}'); + + return node.finishObjectExpression(properties); + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + ++state.parenthesisCount; + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + var legalKeywords = {"if":1, "this":1}; + + function parsePrimaryExpression() { + var type, token, expr, node; + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + type = lookahead.type; + node = new Node(); + + if (type === Token.Identifier || legalKeywords[lookahead.value]) { + expr = node.finishIdentifier(lex().value); + } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && lookahead.octal) { + throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); + } + expr = node.finishLiteral(lex()); + } else if (type === Token.Keyword) { + throw new Error("Disabled."); + } else if (type === Token.BooleanLiteral) { + token = lex(); + token.value = (token.value === 'true'); + expr = node.finishLiteral(token); + } else if (type === Token.NullLiteral) { + token = lex(); + token.value = null; + expr = node.finishLiteral(token); + } else if (match('/') || match('/=')) { + if (typeof extra.tokens !== 'undefined') { + expr = node.finishLiteral(collectRegex()); + } else { + expr = node.finishLiteral(scanRegExp()); + } + peek(); + } else { + throwUnexpected(lex()); + } + + return expr; + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expectTolerant(','); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token, node = new Node(); + + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return node.finishIdentifier(token.value); + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseLeftHandSideExpressionAllowCall() { + var expr, args, property, startToken, previousAllowIn = state.allowIn; + + startToken = lookahead; + state.allowIn = true; + expr = parsePrimaryExpression(); + + for (;;) { + if (match('.')) { + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (match('(')) { + args = parseArguments(); + expr = new WrappingNode(startToken).finishCallExpression(expr, args); + } else if (match('[')) { + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else { + break; + } + } + state.allowIn = previousAllowIn; + + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(); + + if (lookahead.type === Token.Punctuator) { + if ((match('++') || match('--')) && !peekLineTerminator()) { + throw new Error("Disabled."); + } + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr, startToken; + + if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + throw new Error("Disabled."); + } else if (match('+') || match('-') || match('~') || match('!')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + throw new Error("Disabled."); + } else { + expr = parsePostfixExpression(); + } + + return expr; + } + + function binaryPrecedence(token, allowIn) { + var prec = 0; + + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + prec = 7; + break; + + case 'in': + prec = allowIn ? 7 : 0; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; + } + + // 11.5 Multiplicative Operators + // 11.6 Additive Operators + // 11.7 Bitwise Shift Operators + // 11.8 Relational Operators + // 11.9 Equality Operators + // 11.10 Binary Bitwise Operators + // 11.11 Binary Logical Operators + + function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = parseUnaryExpression(); + + token = lookahead; + prec = binaryPrecedence(token, state.allowIn); + if (prec === 0) { + return left; + } + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = parseUnaryExpression(); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = parseUnaryExpression(); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; + } + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent, alternate, startToken; + + startToken = lookahead; + + expr = parseBinaryExpression(); + + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + alternate = parseAssignmentExpression(); + + expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); + } + + return expr; + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var oldParenthesisCount, token, expr, startToken; + + oldParenthesisCount = state.parenthesisCount; + + startToken = lookahead; + token = lookahead; + + expr = parseConditionalExpression(); + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr = parseAssignmentExpression(); + + if (match(',')) { + throw new Error("Disabled."); // no sequence expressions + } + + return expr; + } + + // 12.4 Expression Statement + + function parseExpressionStatement(node) { + var expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 12 Statements + + function parseStatement() { + var type = lookahead.type, + expr, + node; + + if (type === Token.EOF) { + throwUnexpected(lookahead); + } + + if (type === Token.Punctuator && lookahead.value === '{') { + throw new Error("Disabled."); // block statement + } + + node = new Node(); + + if (type === Token.Punctuator) { + switch (lookahead.value) { + case ';': + throw new Error("Disabled."); // empty statement + case '(': + return parseExpressionStatement(node); + default: + break; + } + } else if (type === Token.Keyword) { + throw new Error("Disabled."); // keyword + } + + expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 14 Program + + function parseSourceElement() { + if (lookahead.type === Token.Keyword) { + switch (lookahead.value) { + case 'const': + case 'let': + throw new Error("Disabled."); + case 'function': + throw new Error("Disabled."); + default: + return parseStatement(); + } + } + + if (lookahead.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead; + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var body, node; + + skipComment(); + peek(); + node = new Node(); + strict = true; // assume strict + + body = parseSourceElements(); + return node.finishProgram(body); + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (entry.regex) { + token.regex = { + pattern: entry.regex.pattern, + flags: entry.regex.flags + }; + } + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function tokenize(code, options) { + var toString, + tokens; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + + // Options matching. + options = options || {}; + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + extra.tokenize = true; + // The following two fields are necessary to compute the Regex tokens. + extra.openParenToken = -1; + extra.openCurlyToken = -1; + + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + + try { + peek(); + if (lookahead.type === Token.EOF) { + return extra.tokens; + } + + lex(); + while (lookahead.type !== Token.EOF) { + try { + lex(); + } catch (lexError) { + if (extra.errors) { + extra.errors.push(lexError); + // We have to break on the first error + // to avoid infinite loops. + break; + } else { + throw lexError; + } + } + } + + filterTokenLocation(); + tokens = extra.tokens; + if (typeof extra.errors !== 'undefined') { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + return tokens; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + parenthesisCount: 0, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + } + + try { + program = parseProgram(); + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + + return program; + } + + return { + tokenize: tokenize, + parse: parse + }; + + })(); +},{}],47:[function(require,module,exports){ + var ts = Date.now(); + + function write(msg) { + msg = '[Vega Log] ' + msg; + console.log(msg); + } + + function error(msg) { + msg = '[Vega Err] ' + msg; + console.error(msg); + } + + function debug(input, args) { + if (!debug.enable) return; + var log = Function.prototype.bind.call(console.log, console); + var state = { + prevTime: Date.now() - ts, + stamp: input.stamp + }; + + if (input.add) { + state.add = input.add.length; + state.mod = input.mod.length; + state.rem = input.rem.length; + state.reflow = !!input.reflow; + } + + log.apply(console, (args.push(JSON.stringify(state)), args)); + ts = Date.now(); + } + + module.exports = { + log: write, + error: error, + debug: (debug.enable = false, debug) + }; + +},{}],48:[function(require,module,exports){ + module.exports = { + path: require('./path'), + render: require('./render'), + Item: require('./util/Item'), + bound: require('./util/bound'), + Bounds: require('./util/Bounds'), + canvas: require('./util/canvas'), + Gradient: require('./util/Gradient'), + toJSON: require('./util/scene').toJSON, + fromJSON: require('./util/scene').fromJSON + }; +},{"./path":50,"./render":70,"./util/Bounds":76,"./util/Gradient":78,"./util/Item":80,"./util/bound":81,"./util/canvas":82,"./util/scene":84}],49:[function(require,module,exports){ + var segmentCache = {}, + bezierCache = {}, + join = [].join; + +// Copied from Inkscape svgtopdf, thanks! + function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) { + var key = join.call(arguments); + if (segmentCache[key]) { + return segmentCache[key]; + } + + var th = rotateX * (Math.PI/180); + var sin_th = Math.sin(th); + var cos_th = Math.cos(th); + rx = Math.abs(rx); + ry = Math.abs(ry); + var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5; + var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5; + var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry); + if (pl > 1) { + pl = Math.sqrt(pl); + rx *= pl; + ry *= pl; + } + + var a00 = cos_th / rx; + var a01 = sin_th / rx; + var a10 = (-sin_th) / ry; + var a11 = (cos_th) / ry; + var x0 = a00 * ox + a01 * oy; + var y0 = a10 * ox + a11 * oy; + var x1 = a00 * x + a01 * y; + var y1 = a10 * x + a11 * y; + + var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0); + var sfactor_sq = 1 / d - 0.25; + if (sfactor_sq < 0) sfactor_sq = 0; + var sfactor = Math.sqrt(sfactor_sq); + if (sweep == large) sfactor = -sfactor; + var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0); + var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0); + + var th0 = Math.atan2(y0-yc, x0-xc); + var th1 = Math.atan2(y1-yc, x1-xc); + + var th_arc = th1-th0; + if (th_arc < 0 && sweep === 1){ + th_arc += 2 * Math.PI; + } else if (th_arc > 0 && sweep === 0) { + th_arc -= 2 * Math.PI; + } + + var segs = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001))); + var result = []; + for (var i=0; i len) { + for (j=1, m=parsed.length; j=0;) { + if (h[i].type !== type) continue; + if (!handler || h[i].handler === handler) h.splice(i, 1); + } + return this; + }; + + prototype.pickEvent = function(evt) { + var rect = this._canvas.getBoundingClientRect(), + pad = this._padding, x, y; + return this.pick(this._scene, + x = (evt.clientX - rect.left), + y = (evt.clientY - rect.top), + x - pad.left, y - pad.top); + }; + +// find the scenegraph item at the current mouse position +// x, y -- the absolute x, y mouse coordinates on the canvas element +// gx, gy -- the relative coordinates within the current group + prototype.pick = function(scene, x, y, gx, gy) { + var g = this.context(), + mark = marks[scene.marktype]; + return mark.pick.call(this, g, scene, x, y, gx, gy); + }; + + module.exports = CanvasHandler; + +},{"../../util/dom":83,"../Handler":53,"./marks":62}],56:[function(require,module,exports){ + var DOM = require('../../util/dom'), + Bounds = require('../../util/Bounds'), + ImageLoader = require('../../util/ImageLoader'), + Canvas = require('../../util/canvas'), + Renderer = require('../Renderer'), + marks = require('./marks'); + + function CanvasRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + } + + CanvasRenderer.RETINA = true; + + var base = Renderer.prototype; + var prototype = (CanvasRenderer.prototype = Object.create(base)); + prototype.constructor = CanvasRenderer; + + prototype.initialize = function(el, width, height, padding) { + this._canvas = Canvas.instance(width, height); + if (el) { + DOM.clear(el, 0).appendChild(this._canvas); + this._canvas.setAttribute('class', 'marks'); + } + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + Canvas.resize(this._canvas, this._width, this._height, + this._padding, CanvasRenderer.RETINA); + return this; + }; + + prototype.canvas = function() { + return this._canvas; + }; + + prototype.context = function() { + return this._canvas ? this._canvas.getContext('2d') : null; + }; + + prototype.pendingImages = function() { + return this._loader.pending(); + }; + + function clipToBounds(g, items) { + if (!items) return null; + + var b = new Bounds(), i, n, item, mark, group; + for (i=0, n=items.length; i 0) { + if (group.fill && util.fill(g, group, opac)) { + g.fillRect(gx, gy, w, h); + } + if (group.stroke && util.stroke(g, group, opac)) { + g.strokeRect(gx, gy, w, h); + } + } + } + + // setup graphics context + g.save(); + g.translate(gx, gy); + if (group.clip) { + g.beginPath(); + g.rect(0, 0, w, h); + g.clip(); + } + if (bounds) bounds.translate(-gx, -gy); + + // draw group contents + for (j=0, m=axes.length; j=0;) { + group = groups[i]; + + // first hit test against bounding box + // if a group is clipped, that should be handled by the bounds check. + b = group.bounds; + if (b && !b.contains(gx, gy)) continue; + + // passed bounds check, so test sub-groups + axes = group.axisItems || EMPTY; + items = group.items || EMPTY; + legends = group.legendItems || EMPTY; + dx = (group.x || 0); + dy = (group.y || 0); + + g.save(); + g.translate(dx, dy); + dx = gx - dx; + dy = gy - dy; + for (j=legends.length; --j>=0;) { + subscene = legends[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interactive !== false && subscene.layer !== 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=items.length; --j>=0;) { + subscene = items[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interative !== false && subscene.layer === 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + g.restore(); + + if (scene.interactive !== false && (group.fill || group.stroke) && + dx >= 0 && dx <= group.width && dy >= 0 && dy <= group.height) { + return group; + } + } + + return null; + } + + module.exports = { + draw: draw, + pick: pick + }; + +},{"./util":69}],61:[function(require,module,exports){ + var util = require('./util'); + + function draw(g, scene, bounds) { + if (!scene.items || !scene.items.length) return; + + var renderer = this, + items = scene.items, o; + + for (var i=0, len=items.length; i= 0;) { + o = scene.items[i]; b = o.bounds; + // first hit test against bounding box + if ((b && !b.contains(gx, gy)) || !b) continue; + // if in bounding box, perform more careful test + if (test(g, o, x, y, gx, gy)) return o; + } + return null; + }; + } + + function testPath(path, filled) { + return function(g, o, x, y) { + var item = Array.isArray(o) ? o[0] : o, + fill = (filled == null) ? item.fill : filled, + stroke = item.stroke && g.isPointInStroke, lw, lc; + + if (stroke) { + lw = item.strokeWidth; + lc = item.strokeCap; + g.lineWidth = lw != null ? lw : 1; + g.lineCap = lc != null ? lc : 'butt'; + } + + return path(g, o) ? false : + (fill && g.isPointInPath(x, y)) || + (stroke && g.isPointInStroke(x, y)); + }; + } + + function pickPath(path) { + return pick(testPath(path)); + } + + function fill(g, o, opacity) { + opacity *= (o.fillOpacity==null ? 1 : o.fillOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.fillStyle = color(g, o, o.fill); + return true; + } else { + return false; + } + } + + function stroke(g, o, opacity) { + var lw = (lw = o.strokeWidth) != null ? lw : 1, lc; + if (lw <= 0) return false; + + opacity *= (o.strokeOpacity==null ? 1 : o.strokeOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.strokeStyle = color(g, o, o.stroke); + g.lineWidth = lw; + g.lineCap = (lc = o.strokeCap) != null ? lc : 'butt'; + g.vgLineDash(o.strokeDash || null); + g.vgLineDashOffset(o.strokeDashOffset || 0); + return true; + } else { + return false; + } + } + + function color(g, o, value) { + return (value.id) ? + gradient(g, value, o.bounds) : + value; + } + + function gradient(g, p, b) { + var w = b.width(), + h = b.height(), + x1 = b.x1 + p.x1 * w, + y1 = b.y1 + p.y1 * h, + x2 = b.x1 + p.x2 * w, + y2 = b.y1 + p.y2 * h, + grad = g.createLinearGradient(x1, y1, x2, y2), + stop = p.stops, + i, n; + + for (i=0, n=stop.length; i=0;) { + if (h[i].type === type && !handler || h[i].handler === handler) { + svg.removeEventListener(name, h[i].listener); + h.splice(i, 1); + } + } + return this; + }; + + module.exports = SVGHandler; + +},{"../../util/dom":83,"../Handler":53}],72:[function(require,module,exports){ + var ImageLoader = require('../../util/ImageLoader'), + Renderer = require('../Renderer'), + text = require('../../util/text'), + DOM = require('../../util/dom'), + SVG = require('../../util/svg'), + ns = SVG.metadata.xmlns, + marks = require('./marks'); + + function SVGRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + this._dirtyID = 0; + } + + var base = Renderer.prototype; + var prototype = (SVGRenderer.prototype = Object.create(base)); + prototype.constructor = SVGRenderer; + + prototype.initialize = function(el, width, height, padding) { + if (el) { + this._svg = DOM.child(el, 0, 'svg', ns, 'marks'); + DOM.clear(el, 1); + // set the svg root group + this._root = DOM.child(this._svg, 0, 'g', ns); + DOM.clear(this._svg, 1); + } + + // create the svg definitions cache + this._defs = { + clip_id: 1, + gradient: {}, + clipping: {} + }; + + // set background color if defined + this.background(this._bgcolor); + + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.background = function(bgcolor) { + if (arguments.length && this._svg) { + this._svg.style.setProperty('background-color', bgcolor); + } + return base.background.apply(this, arguments); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + + if (this._svg) { + var w = this._width, + h = this._height, + p = this._padding; + + this._svg.setAttribute('width', w + p.left + p.right); + this._svg.setAttribute('height', h + p.top + p.bottom); + + this._root.setAttribute('transform', 'translate('+p.left+','+p.top+')'); + } + + return this; + }; + + prototype.svg = function() { + if (!this._svg) return null; + + var attr = { + 'class': 'marks', + 'width': this._width + this._padding.left + this._padding.right, + 'height': this._height + this._padding.top + this._padding.bottom, + }; + for (var key in SVG.metadata) { + attr[key] = SVG.metadata[key]; + } + + return DOM.openTag('svg', attr) + this._svg.innerHTML + DOM.closeTag('svg'); + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + +// -- Render entry point -- + + prototype.render = function(scene, items) { + if (this._dirtyCheck(items)) { + if (this._dirtyAll) this._resetDefs(); + this.draw(this._root, scene, -1); + DOM.clear(this._root, 1); + } + this.updateDefs(); + return this; + }; + + prototype.draw = function(el, scene, index) { + this.drawMark(el, scene, index, marks[scene.marktype]); + }; + + +// -- Manage SVG definitions ('defs') block -- + + prototype.updateDefs = function() { + var svg = this._svg, + defs = this._defs, + el = defs.el, + index = 0, id; + + for (id in defs.gradient) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateGradient(el, defs.gradient[id], index++); + } + + for (id in defs.clipping) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateClipping(el, defs.clipping[id], index++); + } + + // clean-up + if (el) { + if (index === 0) { + svg.removeChild(el); + defs.el = null; + } else { + DOM.clear(el, index); + } + } + }; + + function updateGradient(el, grad, index) { + var i, n, stop; + + el = DOM.child(el, index, 'linearGradient', ns); + el.setAttribute('id', grad.id); + el.setAttribute('x1', grad.x1); + el.setAttribute('x2', grad.x2); + el.setAttribute('y1', grad.y1); + el.setAttribute('y2', grad.y2); + + for (i=0, n=grad.stops.length; i 0) ? openTag('defs') + defs + closeTag('defs') : ''; + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + var object; + + function emit(name, value, ns, prefixed) { + object[prefixed || name] = value; + } + + prototype.attributes = function(attr, item) { + object = {}; + attr(emit, item, this); + return object; + }; + + prototype.mark = function(scene) { + var mdef = MARKS[scene.marktype], + tag = mdef.tag, + attr = mdef.attr, + nest = mdef.nest || false, + data = nest ? + (scene.items && scene.items.length ? [scene.items[0]] : []) : + (scene.items || []), + defs = this._defs, + str = '', + style, i, item; + + if (tag !== 'g' && scene.interactive === false) { + style = 'style="pointer-events: none;"'; + } + + // render opening group tag + str += openTag('g', { + 'class': DOM.cssClass(scene) + }, style); + + // render contained elements + for (i=0; i/g, '>'); + } + + module.exports = SVGStringRenderer; + +},{"../../util/ImageLoader":79,"../../util/dom":83,"../../util/svg":85,"../../util/text":86,"../Renderer":54,"./marks":75}],74:[function(require,module,exports){ + module.exports = { + Handler: require('./SVGHandler'), + Renderer: require('./SVGRenderer'), + string: { + Renderer : require('./SVGStringRenderer') + } + }; +},{"./SVGHandler":71,"./SVGRenderer":72,"./SVGStringRenderer":73}],75:[function(require,module,exports){ + var text = require('../../util/text'), + SVG = require('../../util/svg'), + textAlign = SVG.textAlign, + path = SVG.path; + + function translateItem(o) { + return translate(o.x || 0, o.y || 0); + } + + function translate(x, y) { + return 'translate(' + x + ',' + y + ')'; + } + + module.exports = { + arc: { + tag: 'path', + type: 'arc', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.arc(o)); + } + }, + area: { + tag: 'path', + type: 'area', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.area(items)); + } + }, + group: { + tag: 'g', + type: 'group', + attr: function(emit, o, renderer) { + var id = null, defs, c; + emit('transform', translateItem(o)); + if (o.clip) { + defs = renderer._defs; + id = o.clip_id || (o.clip_id = 'clip' + defs.clip_id++); + c = defs.clipping[id] || (defs.clipping[id] = {id: id}); + c.width = o.width || 0; + c.height = o.height || 0; + } + emit('clip-path', id ? ('url(#' + id + ')') : null); + }, + background: function(emit, o) { + emit('class', 'background'); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + image: { + tag: 'image', + type: 'image', + attr: function(emit, o, renderer) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0, + url = renderer.imageURL(o.url); + + x = x - (o.align === 'center' ? w/2 : o.align === 'right' ? w : 0); + y = y - (o.baseline === 'middle' ? h/2 : o.baseline === 'bottom' ? h : 0); + + emit('href', url, 'http://www.w3.org/1999/xlink', 'xlink:href'); + emit('transform', translate(x, y)); + emit('width', w); + emit('height', h); + } + }, + line: { + tag: 'path', + type: 'line', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.line(items)); + } + }, + path: { + tag: 'path', + type: 'path', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', o.path); + } + }, + rect: { + tag: 'rect', + type: 'rect', + nest: false, + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + rule: { + tag: 'line', + type: 'rule', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('x2', o.x2 != null ? o.x2 - (o.x||0) : 0); + emit('y2', o.y2 != null ? o.y2 - (o.y||0) : 0); + } + }, + symbol: { + tag: 'path', + type: 'symbol', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.symbol(o)); + } + }, + text: { + tag: 'text', + type: 'text', + nest: false, + attr: function(emit, o) { + var dx = (o.dx || 0), + dy = (o.dy || 0) + text.offset(o), + x = (o.x || 0), + y = (o.y || 0), + a = o.angle || 0, + r = o.radius || 0, t; + + if (r) { + t = (o.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + emit('text-anchor', textAlign[o.align] || 'start'); + + if (a) { + t = translate(x, y) + ' rotate('+a+')'; + if (dx || dy) t += ' ' + translate(dx, dy); + } else { + t = translate(x+dx, y+dy); + } + emit('transform', t); + } + } + }; + +},{"../../util/svg":85,"../../util/text":86}],76:[function(require,module,exports){ + function Bounds(b) { + this.clear(); + if (b) this.union(b); + } + + var prototype = Bounds.prototype; + + prototype.clone = function() { + return new Bounds(this); + }; + + prototype.clear = function() { + this.x1 = +Number.MAX_VALUE; + this.y1 = +Number.MAX_VALUE; + this.x2 = -Number.MAX_VALUE; + this.y2 = -Number.MAX_VALUE; + return this; + }; + + prototype.set = function(x1, y1, x2, y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + return this; + }; + + prototype.add = function(x, y) { + if (x < this.x1) this.x1 = x; + if (y < this.y1) this.y1 = y; + if (x > this.x2) this.x2 = x; + if (y > this.y2) this.y2 = y; + return this; + }; + + prototype.expand = function(d) { + this.x1 -= d; + this.y1 -= d; + this.x2 += d; + this.y2 += d; + return this; + }; + + prototype.round = function() { + this.x1 = Math.floor(this.x1); + this.y1 = Math.floor(this.y1); + this.x2 = Math.ceil(this.x2); + this.y2 = Math.ceil(this.y2); + return this; + }; + + prototype.translate = function(dx, dy) { + this.x1 += dx; + this.x2 += dx; + this.y1 += dy; + this.y2 += dy; + return this; + }; + + prototype.rotate = function(angle, x, y) { + var cos = Math.cos(angle), + sin = Math.sin(angle), + cx = x - x*cos + y*sin, + cy = y - x*sin - y*cos, + x1 = this.x1, x2 = this.x2, + y1 = this.y1, y2 = this.y2; + + return this.clear() + .add(cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy) + .add(cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy) + .add(cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy) + .add(cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy); + }; + + prototype.union = function(b) { + if (b.x1 < this.x1) this.x1 = b.x1; + if (b.y1 < this.y1) this.y1 = b.y1; + if (b.x2 > this.x2) this.x2 = b.x2; + if (b.y2 > this.y2) this.y2 = b.y2; + return this; + }; + + prototype.encloses = function(b) { + return b && ( + this.x1 <= b.x1 && + this.x2 >= b.x2 && + this.y1 <= b.y1 && + this.y2 >= b.y2 + ); + }; + + prototype.intersects = function(b) { + return b && !( + this.x2 < b.x1 || + this.x1 > b.x2 || + this.y2 < b.y1 || + this.y1 > b.y2 + ); + }; + + prototype.contains = function(x, y) { + return !( + x < this.x1 || + x > this.x2 || + y < this.y1 || + y > this.y2 + ); + }; + + prototype.width = function() { + return this.x2 - this.x1; + }; + + prototype.height = function() { + return this.y2 - this.y1; + }; + + module.exports = Bounds; + +},{}],77:[function(require,module,exports){ + module.exports = function(b) { + function noop() { } + function add(x,y) { b.add(x, y); } + + return { + bounds: function(_) { + if (!arguments.length) return b; + return (b = _, this); + }, + beginPath: noop, + closePath: noop, + moveTo: add, + lineTo: add, + quadraticCurveTo: function(x1, y1, x2, y2) { + b.add(x1, y1); + b.add(x2, y2); + }, + bezierCurveTo: function(x1, y1, x2, y2, x3, y3) { + b.add(x1, y1); + b.add(x2, y2); + b.add(x3, y3); + } + }; + }; + +},{}],78:[function(require,module,exports){ + var gradient_id = 0; + + function Gradient(type) { + this.id = 'gradient_' + (gradient_id++); + this.type = type || 'linear'; + this.stops = []; + this.x1 = 0; + this.x2 = 1; + this.y1 = 0; + this.y2 = 0; + } + + var prototype = Gradient.prototype; + + prototype.stop = function(offset, color) { + this.stops.push({ + offset: offset, + color: color + }); + return this; + }; + + module.exports = Gradient; +},{}],79:[function(require,module,exports){ + (function (global){ + var load = require('datalib/src/import/load'); + + function ImageLoader(loadConfig) { + this._pending = 0; + this._config = loadConfig || ImageLoader.Config; + } + +// Overridable global default load configuration + ImageLoader.Config = null; + + var prototype = ImageLoader.prototype; + + prototype.pending = function() { + return this._pending; + }; + + prototype.params = function(uri) { + var p = {url: uri}, k; + for (k in this._config) { p[k] = this._config[k]; } + return p; + }; + + prototype.imageURL = function(uri) { + return load.sanitizeUrl(this.params(uri)); + }; + + function browser(uri, callback) { + var url = load.sanitizeUrl(this.params(uri)); + if (!url) { // error + if (callback) callback(uri, null); + return null; + } + + var loader = this, + image = new Image(); + + loader._pending += 1; + + image.onload = function() { + loader._pending -= 1; + image.loaded = true; + if (callback) callback(null, image); + }; + image.src = url; + + return image; + } + + function server(uri, callback) { + var loader = this, + image = new ((typeof window !== "undefined" ? window['canvas'] : typeof global !== "undefined" ? global['canvas'] : null).Image)(); + + loader._pending += 1; + + load(this.params(uri), function(err, data) { + loader._pending -= 1; + if (err) { + if (callback) callback(err, null); + return null; + } + image.src = data; + image.loaded = true; + if (callback) callback(null, image); + }); + + return image; + } + + prototype.loadImage = function(uri, callback) { + return load.useXHR ? + browser.call(this, uri, callback) : + server.call(this, uri, callback); + }; + + module.exports = ImageLoader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib/src/import/load":22}],80:[function(require,module,exports){ + function Item(mark) { + this.mark = mark; + } + + var prototype = Item.prototype; + + prototype.hasPropertySet = function(name) { + var props = this.mark.def.properties; + return props && props[name] != null; + }; + + prototype.cousin = function(offset, index) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + group = mark.group, + iidx = index==null ? mark.items.indexOf(this) : index, + midx = group.items.indexOf(mark) + offset; + return group.items[midx].items[iidx]; + }; + + prototype.sibling = function(offset) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + iidx = mark.items.indexOf(this) + offset; + return mark.items[iidx]; + }; + + prototype.remove = function() { + var item = this, + list = item.mark.items, + i = list.indexOf(item); + if (i >= 0) { + if (i===list.length-1) { + list.pop(); + } else { + list.splice(i, 1); + } + } + return item; + }; + + prototype.touch = function() { + if (this.pathCache) this.pathCache = null; + }; + + module.exports = Item; +},{}],81:[function(require,module,exports){ + var BoundsContext = require('./BoundsContext'), + Bounds = require('./Bounds'), + canvas = require('./canvas'), + svg = require('./svg'), + text = require('./text'), + paths = require('../path'), + parse = paths.parse, + drawPath = paths.render, + areaPath = svg.path.area, + linePath = svg.path.line, + halfpi = Math.PI / 2, + sqrt3 = Math.sqrt(3), + tan30 = Math.tan(30 * Math.PI / 180), + g2D = null, + bc = BoundsContext(); + + function context() { + return g2D || (g2D = canvas.instance(1,1).getContext('2d')); + } + + function strokeBounds(o, bounds) { + if (o.stroke && o.opacity !== 0 && o.stokeOpacity !== 0) { + bounds.expand(o.strokeWidth != null ? o.strokeWidth : 1); + } + return bounds; + } + + function pathBounds(o, path, bounds, x, y) { + if (path == null) { + bounds.set(0, 0, 0, 0); + } else { + drawPath(bc.bounds(bounds), path, x, y); + strokeBounds(o, bounds); + } + return bounds; + } + + function path(o, bounds) { + var p = o.path ? o.pathCache || (o.pathCache = parse(o.path)) : null; + return pathBounds(o, p, bounds, o.x, o.y); + } + + function area(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(areaPath(items))); + return pathBounds(item, p, bounds); + } + + function line(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(linePath(items))); + return pathBounds(item, p, bounds); + } + + function rect(o, bounds) { + var x, y; + return strokeBounds(o, bounds.set( + x = o.x || 0, + y = o.y || 0, + (x + o.width) || 0, + (y + o.height) || 0 + )); + } + + function image(o, bounds) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0; + x = x - (o.align === 'center' ? w/2 : (o.align === 'right' ? w : 0)); + y = y - (o.baseline === 'middle' ? h/2 : (o.baseline === 'bottom' ? h : 0)); + return bounds.set(x, y, x+w, y+h); + } + + function rule(o, bounds) { + var x1, y1; + return strokeBounds(o, bounds.set( + x1 = o.x || 0, + y1 = o.y || 0, + o.x2 != null ? o.x2 : x1, + o.y2 != null ? o.y2 : y1 + )); + } + + function arc(o, bounds) { + var cx = o.x || 0, + cy = o.y || 0, + ir = o.innerRadius || 0, + or = o.outerRadius || 0, + sa = (o.startAngle || 0) - halfpi, + ea = (o.endAngle || 0) - halfpi, + xmin = Infinity, xmax = -Infinity, + ymin = Infinity, ymax = -Infinity, + a, i, n, x, y, ix, iy, ox, oy; + + var angles = [sa, ea], + s = sa - (sa % halfpi); + for (i=0; i<4 && s index) { + el.removeChild(el.childNodes[--curr]); + } + return el; + }, + remove: remove, + // generate css class name for mark + cssClass: function(mark) { + return 'mark-' + mark.marktype + (mark.name ? ' '+mark.name : ''); + }, + // generate string for an opening xml tag + // tag: the name of the xml tag + // attr: hash of attribute name-value pairs to include + // raw: additional raw string to include in tag markup + openTag: function(tag, attr, raw) { + var s = '<' + tag, key, val; + if (attr) { + for (key in attr) { + val = attr[key]; + if (val != null) { + s += ' ' + key + '="' + val + '"'; + } + } + } + if (raw) s += ' ' + raw; + return s + '>'; + }, + // generate string for closing xml tag + // tag: the name of the xml tag + closeTag: function(tag) { + return ''; + } + }; + +},{}],84:[function(require,module,exports){ + var bound = require('../util/bound'); + + var sets = [ + 'items', + 'axisItems', + 'legendItems' + ]; + + var keys = [ + 'marktype', 'name', 'interactive', 'clip', + 'items', 'axisItems', 'legendItems', 'layer', + 'x', 'y', 'width', 'height', 'align', 'baseline', // layout + 'fill', 'fillOpacity', 'opacity', // fill + 'stroke', 'strokeOpacity', 'strokeWidth', 'strokeCap', // stroke + 'strokeDash', 'strokeDashOffset', // stroke dash + 'startAngle', 'endAngle', 'innerRadius', 'outerRadius', // arc + 'interpolate', 'tension', 'orient', // area, line + 'url', // image + 'path', // path + 'x2', 'y2', // rule + 'size', 'shape', // symbol + 'text', 'angle', 'theta', 'radius', 'dx', 'dy', // text + 'font', 'fontSize', 'fontWeight', 'fontStyle', 'fontVariant' // font + ]; + + function toJSON(scene, indent) { + return JSON.stringify(scene, keys, indent); + } + + function fromJSON(json) { + var scene = (typeof json === 'string' ? JSON.parse(json) : json); + return initialize(scene); + } + + function initialize(scene) { + var type = scene.marktype, + i, n, s, m, items; + + for (s=0, m=sets.length; s 0) { wait(); } else { callback(this.canvas()); } + }; + + prototype.svg = function() { + return (this._type === 'svg') ? this._renderer.svg() : null; + }; + + prototype.initialize = function() { + var w = this._width, + h = this._height, + bg = this._bgcolor, + pad = this._padding, + config = this.model().config(); + + if (this._viewport) { + w = this._viewport[0] - (pad ? pad.left + pad.right : 0); + h = this._viewport[1] - (pad ? pad.top + pad.bottom : 0); + } + + this._renderer = (this._renderer || new this._io.Renderer(config.load)) + .initialize(null, w, h, pad) + .background(bg); + + return this; + }; + + module.exports = HeadlessView; +},{"./View":89,"vega-scenegraph":48}],88:[function(require,module,exports){ + var dl = require('datalib'), + df = require('vega-dataflow'), + ChangeSet = df.ChangeSet, + Base = df.Graph.prototype, + Node = df.Node, // jshint ignore:line + GroupBuilder = require('../scene/GroupBuilder'), + visit = require('../scene/visit'), + config = require('./config'); + + function Model(cfg) { + this._defs = {}; + this._predicates = {}; + this._scene = null; + + this._node = null; + this._builder = null; // Top-level scenegraph builder + + this._reset = {axes: false, legends: false}; + + this.config(cfg); + Base.init.call(this); + } + + var prototype = (Model.prototype = Object.create(Base)); + prototype.constructor = Model; + + prototype.defs = function(defs) { + if (!arguments.length) return this._defs; + this._defs = defs; + return this; + }; + + prototype.config = function(cfg) { + if (!arguments.length) return this._config; + this._config = Object.create(config); + for (var name in cfg) { + var x = cfg[name], y = this._config[name]; + if (dl.isObject(x) && dl.isObject(y)) { + dl.extend(y, x); + } else { + this._config[name] = x; + } + } + + return this; + }; + + prototype.width = function(width) { + if (this._defs) this._defs.width = width; + if (this._defs && this._defs.marks) this._defs.marks.width = width; + if (this._scene) { + this._scene.items[0].width = width; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.height = function(height) { + if (this._defs) this._defs.height = height; + if (this._defs && this._defs.marks) this._defs.marks.height = height; + if (this._scene) { + this._scene.items[0].height = height; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.node = function() { + return this._node || (this._node = new Node(this)); + }; + + prototype.data = function() { + var data = Base.data.apply(this, arguments); + if (arguments.length > 1) { // new Datasource + this.node().addListener(data.pipeline()[0]); + } + return data; + }; + + function predicates(name) { + var m = this, pred = {}; + if (!dl.isArray(name)) return this._predicates[name]; + name.forEach(function(n) { pred[n] = m._predicates[n]; }); + return pred; + } + + prototype.predicate = function(name, predicate) { + if (arguments.length === 1) return predicates.call(this, name); + return (this._predicates[name] = predicate); + }; + + prototype.predicates = function() { return this._predicates; }; + + prototype.scene = function(renderer) { + if (!arguments.length) return this._scene; + + if (this._builder) { + this.node().removeListener(this._builder); + this._builder._groupBuilder.disconnect(); + } + + var m = this, + b = this._builder = new Node(this); + + b.evaluate = function(input) { + if (b._groupBuilder) return input; + + var gb = b._groupBuilder = new GroupBuilder(m, m._defs.marks, m._scene={}), + p = gb.pipeline(); + + this.addListener(gb.connect()); + p[p.length-1].addListener(renderer); + return input; + }; + + this.addListener(b); + return this; + }; + + prototype.reset = function() { + if (this._scene && this._reset.axes) { + visit(this._scene, function(item) { + if (item.axes) item.axes.forEach(function(axis) { axis.reset(); }); + }); + this._reset.axes = false; + } + if (this._scene && this._reset.legends) { + visit(this._scene, function(item) { + if (item.legends) item.legends.forEach(function(l) { l.reset(); }); + }); + this._reset.legends = false; + } + return this; + }; + + prototype.addListener = function(l) { + this.node().addListener(l); + }; + + prototype.removeListener = function(l) { + this.node().removeListener(l); + }; + + prototype.fire = function(cs) { + if (!cs) cs = ChangeSet.create(); + this.propagate(cs, this.node()); + }; + + module.exports = Model; +},{"../scene/GroupBuilder":112,"../scene/visit":117,"./config":90,"datalib":26,"vega-dataflow":41}],89:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + sg = require('vega-scenegraph').render, + log = require('vega-logging'), + Deps = df.Dependencies, + parseStreams = require('../parse/streams'), + Encoder = require('../scene/Encoder'), + Transition = require('../scene/Transition'); + + function View(el, width, height) { + this._el = null; + this._model = null; + this._width = this.__width = width || 500; + this._height = this.__height = height || 300; + this._bgcolor = null; + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._viewport = null; + this._renderer = null; + this._handler = null; + this._streamer = null; // Targeted update for streaming changes + this._changeset = null; + this._repaint = true; // Full re-render on every re-init + this._renderers = sg; + this._io = null; + this._api = {}; // Stash streaming data API sandboxes. + } + + var prototype = View.prototype; + + prototype.model = function(model) { + if (!arguments.length) return this._model; + if (this._model !== model) { + this._model = model; + this._streamer = new df.Node(model); + this._streamer._rank = -1; // HACK: To reduce re-ranking churn. + this._changeset = df.ChangeSet.create(); + if (this._handler) this._handler.model(model); + } + return this; + }; + +// Sandboxed streaming data API + function streaming(src) { + var view = this, + ds = this._model.data(src), + name = ds.name(), + listener = ds.pipeline()[0], + streamer = this._streamer, + api = {}; + + // If we have it stashed, don't create a new closure. + if (this._api[src]) return this._api[src]; + + api.insert = function(vals) { + ds.insert(dl.duplicate(vals)); // Don't pollute the environment + streamer.addListener(listener); + view._changeset.data[name] = 1; + return api; + }; + + api.update = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.update.apply(ds, arguments), api); + }; + + api.remove = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.remove.apply(ds, arguments), api); + }; + + api.values = function() { return ds.values(); }; + + return (this._api[src] = api); + } + + prototype.data = function(data) { + var v = this; + if (!arguments.length) return v._model.values(); + else if (dl.isString(data)) return streaming.call(v, data); + else if (dl.isObject(data)) { + dl.keys(data).forEach(function(k) { + var api = streaming.call(v, k); + data[k](api); + }); + } + return this; + }; + + var VIEW_SIGNALS = dl.toMap(['width', 'height', 'padding']); + + prototype.signal = function(name, value, propagate) { + var m = this._model, + key, values; + + // Getter. Returns the value for the specified signal, or + // returns all signal values. + if (!arguments.length) { + return m.values(Deps.SIGNALS); + } else if (arguments.length === 1 && dl.isString(name)) { + return m.values(Deps.SIGNALS, name); + } + + // Setter. Can be done in batch or individually. In either case, + // the final argument determines if set values should propagate. + if (dl.isObject(name)) { + values = name; + propagate = value; + } else { + values = {}; + values[name] = value; + } + for (key in values) { + if (VIEW_SIGNALS[key]) { + this[key](values[key]); + } else { + setSignal.call(this, key, values[key], propagate); + } + } + return this; + }; + + function setSignal(name, value, propagate) { + var cs = this._changeset; + this._streamer.addListener(this._model.signal(name).value(value)); + if (propagate !== false) cs.signals[name] = 1; + cs.reflow = true; + } + + prototype.width = function(width) { + if (!arguments.length) return this.__width; + if (this.__width !== width) { + this._width = this.__width = width; + this.model().width(width); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'width', width); + } + return this; + }; + + prototype.height = function(height) { + if (!arguments.length) return this.__height; + if (this.__height !== height) { + this._height = this.__height = height; + this.model().height(height); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'height', height); + } + return this; + }; + + prototype.background = function(bgcolor) { + if (!arguments.length) return this._bgcolor; + if (this._bgcolor !== bgcolor) { + this._bgcolor = bgcolor; + this.initialize(); + } + return this; + }; + + prototype.padding = function(pad) { + if (!arguments.length) return this._padding; + if (this._padding !== pad) { + if (dl.isString(pad)) { + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._strict = (pad === 'strict'); + } else { + this._autopad = 0; + this._padding = pad; + this._strict = false; + } + if (this._renderer) this._renderer.resize(this._width, this._height, this._padding); + if (this._handler) this._handler.padding(this._padding); + setSignal.call(this, 'padding', this._padding); + } + return (this._repaint = true, this); + }; + + prototype.autopad = function(opt) { + if (this._autopad < 1) return this; + else this._autopad = 0; + + var b = this.model().scene().bounds, + pad = this._padding, + config = this.model().config(), + inset = config.autopadInset, + l = b.x1 < 0 ? Math.ceil(-b.x1) + inset : 0, + t = b.y1 < 0 ? Math.ceil(-b.y1) + inset : 0, + r = b.x2 > this._width ? Math.ceil(+b.x2 - this._width) + inset : 0; + b = b.y2 > this._height ? Math.ceil(+b.y2 - this._height) + inset : 0; + pad = {left:l, top:t, right:r, bottom:b}; + + if (this._strict) { + this._autopad = 0; + this._padding = pad; + this._width = Math.max(0, this.__width - (l+r)); + this._height = Math.max(0, this.__height - (t+b)); + + this._model.width(this._width).height(this._height).reset(); + setSignal.call(this, 'width', this._width); + setSignal.call(this, 'height', this._height); + setSignal.call(this, 'padding', pad); + + this.initialize().update({props:'enter'}).update({props:'update'}); + } else { + this.padding(pad).update(opt); + } + return this; + }; + + prototype.viewport = function(size) { + if (!arguments.length) return this._viewport; + if (this._viewport !== size) { + this._viewport = size; + this.initialize(); + } + return this; + }; + + prototype.renderer = function(type) { + if (!arguments.length) return this._renderer; + if (this._renderers[type]) type = this._renderers[type]; + else if (dl.isString(type)) throw new Error('Unknown renderer: ' + type); + else if (!type) throw new Error('No renderer specified'); + + if (this._io !== type) { + this._io = type; + this._renderer = null; + this.initialize(); + if (this._build) this.render(); + } + return this; + }; + + prototype.initialize = function(el) { + var v = this, prevHandler, + w = v._width, h = v._height, pad = v._padding, bg = v._bgcolor, + config = this.model().config(); + + if (!arguments.length || el === null) { + el = this._el ? this._el.parentNode : null; + if (!el) return this; // This View cannot init w/o an + } + + // clear pre-existing container + d3.select(el).select('div.vega').remove(); + + // add div container + this._el = el = d3.select(el) + .append('div') + .attr('class', 'vega') + .style('position', 'relative') + .node(); + if (v._viewport) { + d3.select(el) + .style('width', (v._viewport[0] || w)+'px') + .style('height', (v._viewport[1] || h)+'px') + .style('overflow', 'auto'); + } + + // renderer + sg.canvas.Renderer.RETINA = config.render.retina; + v._renderer = (v._renderer || new this._io.Renderer(config.load)) + .initialize(el, w, h, pad) + .background(bg); + + // input handler + prevHandler = v._handler; + v._handler = new this._io.Handler() + .initialize(el, pad, v); + + if (prevHandler) { + prevHandler.handlers().forEach(function(h) { + v._handler.on(h.type, h.handler); + }); + } else { + // Register event listeners for signal stream definitions. + v._detach = parseStreams(this); + } + + return (this._repaint = true, this); + }; + + prototype.destroy = function() { + if (this._detach) this._detach(); + }; + + function build() { + var v = this; + v._renderNode = new df.Node(v._model) + .router(true); + + v._renderNode.evaluate = function(input) { + log.debug(input, ['rendering']); + + var s = v._model.scene(), + h = v._handler; + + if (h && h.scene) h.scene(s); + + if (input.trans) { + input.trans.start(function(items) { v._renderer.render(s, items); }); + } else if (v._repaint) { + v._renderer.render(s); + v._repaint = false; + } else if (input.dirty.length) { + v._renderer.render(s, input.dirty); + } + + if (input.dirty.length) { + input.dirty.forEach(function(i) { i._dirty = false; }); + s.items[0]._dirty = false; + } + + // For all updated datasources, clear their previous values. + for (var d in input.data) { v._model.data(d).synchronize(); } + return input; + }; + + return (v._model.scene(v._renderNode), true); + } + + prototype.update = function(opt) { + opt = opt || {}; + var v = this, + model = this._model, + streamer = this._streamer, + cs = this._changeset, + trans = opt.duration ? new Transition(opt.duration, opt.ease) : null; + + if (trans) cs.trans = trans; + if (opt.props !== undefined) { + if (dl.keys(cs.data).length > 0) { + throw Error( + 'New data values are not reflected in the visualization.' + + ' Please call view.update() before updating a specified property set.' + ); + } + + cs.reflow = true; + cs.request = opt.props; + } + + var built = v._build; + v._build = v._build || build.call(this); + + // If specific items are specified, short-circuit dataflow graph. + // Else-If there are streaming updates, perform a targeted propagation. + // Otherwise, re-evaluate the entire model (datasources + scene). + if (opt.items && built) { + Encoder.update(model, opt.trans, opt.props, opt.items, cs.dirty); + v._renderNode.evaluate(cs); + } else if (streamer.listeners().length && built) { + // Include re-evaluation entire model when repaint flag is set + if (this._repaint) streamer.addListener(model.node()); + model.propagate(cs, streamer); + streamer.disconnect(); + } else { + model.fire(cs); + } + + v._changeset = df.ChangeSet.create(); + + return v.autopad(opt); + }; + + prototype.toImageURL = function(type) { + var v = this, Renderer; + + // lookup appropriate renderer + switch (type || 'png') { + case 'canvas': + case 'png': + Renderer = sg.canvas.Renderer; break; + case 'svg': + Renderer = sg.svg.string.Renderer; break; + default: throw Error('Unrecognized renderer type: ' + type); + } + + var retina = sg.canvas.Renderer.RETINA; + sg.canvas.Renderer.RETINA = false; // ignore retina screen + + // render the scenegraph + var ren = new Renderer(v._model.config.load) + .initialize(null, v._width, v._height, v._padding) + .render(v._model.scene()); + + sg.canvas.Renderer.RETINA = retina; // restore retina settings + + // return data url + if (type === 'svg') { + var blob = new Blob([ren.svg()], {type: 'image/svg+xml'}); + return window.URL.createObjectURL(blob); + } else { + return ren.canvas().toDataURL('image/png'); + } + }; + + prototype.render = function(items) { + this._renderer.render(this._model.scene(), items); + return this; + }; + + prototype.on = function() { + this._handler.on.apply(this._handler, arguments); + return this; + }; + + prototype.onSignal = function(name, handler) { + this._model.signal(name).on(handler); + return this; + }; + + prototype.off = function() { + this._handler.off.apply(this._handler, arguments); + return this; + }; + + prototype.offSignal = function(name, handler) { + this._model.signal(name).off(handler); + return this; + }; + + View.factory = function(model) { + var HeadlessView = require('./HeadlessView'); + return function(opt) { + opt = opt || {}; + var defs = model.defs(); + var v = (opt.el ? new View() : new HeadlessView()) + .model(model) + .renderer(opt.renderer || 'canvas') + .width(defs.width) + .height(defs.height) + .background(defs.background) + .padding(defs.padding) + .viewport(defs.viewport) + .initialize(opt.el); + + if (opt.data) v.data(opt.data); + + if (opt.hover !== false && opt.el) { + v.on('mouseover', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'hover', items:item}); + } + }) + .on('mouseout', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'update', items:item}); + } + }); + } + + return v; + }; + }; + + module.exports = View; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"../parse/streams":107,"../scene/Encoder":111,"../scene/Transition":114,"./HeadlessView":87,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],90:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + config = {}; + + config.load = { + // base url for loading external data files + // used only for server-side operation + baseURL: '', + // Allows domain restriction when using data loading via XHR. + // To enable, set it to a list of allowed domains + // e.g., ['wikipedia.org', 'eff.org'] + domainWhiteList: false + }; + +// inset padding for automatic padding calculation + config.autopadInset = 5; + +// extensible scale lookup table +// all d3.scale.* instances also supported + config.scale = { + time: d3.time.scale, + utc: d3.time.scale.utc + }; + +// default rendering settings + config.render = { + retina: true + }; + +// root scenegraph group + config.scene = { + fill: undefined, + fillOpacity: undefined, + stroke: undefined, + strokeOpacity: undefined, + strokeWidth: undefined, + strokeDash: undefined, + strokeDashOffset: undefined + }; + +// default axis properties + config.axis = { + orient: 'bottom', + ticks: 10, + padding: 3, + axisColor: '#000', + axisWidth: 1, + gridColor: '#000', + gridOpacity: 0.15, + tickColor: '#000', + tickLabelColor: '#000', + tickWidth: 1, + tickSize: 6, + tickLabelFontSize: 11, + tickLabelFont: 'sans-serif', + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold', + titleOffset: 'auto', + titleOffsetAutoMin: 30, + titleOffsetAutoMax: Infinity, + titleOffsetAutoMargin: 4 + }; + +// default legend properties + config.legend = { + orient: 'right', + offset: 20, + padding: 3, // padding between legend items and border + margin: 2, // extra margin between two consecutive legends + gradientStrokeColor: '#888', + gradientStrokeWidth: 1, + gradientHeight: 16, + gradientWidth: 100, + labelColor: '#000', + labelFontSize: 10, + labelFont: 'sans-serif', + labelAlign: 'left', + labelBaseline: 'middle', + labelOffset: 8, + symbolShape: 'circle', + symbolSize: 50, + symbolColor: '#888', + symbolStrokeWidth: 1, + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold' + }; + +// default color values + config.color = { + rgb: [128, 128, 128], + lab: [50, 0, 0], + hcl: [0, 0, 50], + hsl: [0, 0, 0.5] + }; + +// default scale ranges + config.range = { + category10: d3.scale.category10().range(), + category20: d3.scale.category20().range(), + category20b: d3.scale.category20b().range(), + category20c: d3.scale.category20c().range(), + shapes: [ + 'circle', + 'cross', + 'diamond', + 'square', + 'triangle-down', + 'triangle-up' + ] + }; + + module.exports = config; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],91:[function(require,module,exports){ + var dl = require('datalib'), + parse = require('../parse'), + Scale = require('../scene/Scale'), + config = require('./config'); + + function compile(module, opt, schema) { + var s = module.schema; + if (!s) return; + if (s.refs) dl.extend(schema.refs, s.refs); + if (s.defs) dl.extend(schema.defs, s.defs); + } + + module.exports = function(opt) { + var schema = null; + opt = opt || {}; + + // Compile if we're not loading the schema from a URL. + // Load from a URL to extend the existing base schema. + if (opt.url) { + schema = dl.json(dl.extend({url: opt.url}, config.load)); + } else { + schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Vega Visualization Specification Language", + "defs": {}, + "refs": {}, + "$ref": "#/defs/spec" + }; + + dl.keys(parse).forEach(function(k) { compile(parse[k], opt, schema); }); + + // Scales aren't in the parser, add schema manually + compile(Scale, opt, schema); + } + + // Extend schema to support custom mark properties or property sets. + if (opt.properties) dl.keys(opt.properties).forEach(function(k) { + schema.defs.propset.properties[k] = {"$ref": "#/refs/"+opt.properties[k]+"Value"}; + }); + + if (opt.propertySets) dl.keys(opt.propertySets).forEach(function(k) { + schema.defs.mark.properties.properties.properties[k] = {"$ref": "#/defs/propset"}; + }); + + return schema; + }; +},{"../parse":97,"../scene/Scale":113,"./config":90,"datalib":26}],92:[function(require,module,exports){ + var dl = require('datalib'), + axs = require('../scene/axis'); + + var ORIENT = { + "x": "bottom", + "y": "left", + "top": "top", + "bottom": "bottom", + "left": "left", + "right": "right" + }; + + function parseAxes(model, spec, axes, group) { + var config = model.config(); + (spec || []).forEach(function(def, index) { + axes[index] = axes[index] || axs(model); + parseAxis(config, def, index, axes[index], group); + }); + } + + function parseAxis(config, def, index, axis, group) { + // axis scale + if (def.scale !== undefined) { + axis.scale(group.scale(def.scale)); + } + + // axis orientation + axis.orient(def.orient || ORIENT[def.type]); + // axis offset + axis.offset(def.offset || 0); + // axis layer + axis.layer(def.layer || "front"); + // axis grid lines + axis.grid(def.grid || false); + // axis title + axis.title(def.title || null); + // axis title offset + axis.titleOffset(def.titleOffset != null ? + def.titleOffset : config.axis.titleOffset); + // axis values + axis.tickValues(def.values || null); + // axis label formatting + axis.tickFormat(def.format || null); + axis.tickFormatType(def.formatType || null); + // axis tick subdivision + axis.tickSubdivide(def.subdivide || 0); + // axis tick padding + axis.tickPadding(def.tickPadding || config.axis.padding); + + // axis tick size(s) + var size = []; + if (def.tickSize !== undefined) { + for (var i=0; i<3; ++i) size.push(def.tickSize); + } else { + var ts = config.axis.tickSize; + size = [ts, ts, ts]; + } + if (def.tickSizeMajor != null) size[0] = def.tickSizeMajor; + if (def.tickSizeMinor != null) size[1] = def.tickSizeMinor; + if (def.tickSizeEnd != null) size[2] = def.tickSizeEnd; + if (size.length) { + axis.tickSize.apply(axis, size); + } + + // axis tick count + axis.tickCount(def.ticks || config.axis.ticks); + + // style properties + var p = def.properties; + if (p && p.ticks) { + axis.majorTickProperties(p.majorTicks ? + dl.extend({}, p.ticks, p.majorTicks) : p.ticks); + axis.minorTickProperties(p.minorTicks ? + dl.extend({}, p.ticks, p.minorTicks) : p.ticks); + } else { + axis.majorTickProperties(p && p.majorTicks || {}); + axis.minorTickProperties(p && p.minorTicks || {}); + } + axis.tickLabelProperties(p && p.labels || {}); + axis.titleProperties(p && p.title || {}); + axis.gridLineProperties(p && p.grid || {}); + axis.domainProperties(p && p.axis || {}); + } + + module.exports = parseAxes; +},{"../scene/axis":115,"datalib":26}],93:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null); + + function parseBg(bg) { + // return null if input is null or undefined + if (bg == null) return null; + // run through d3 rgb to sanity check + return d3.rgb(bg) + ''; + } + + module.exports = parseBg; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],94:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + parseTransforms = require('./transforms'), + parseModify = require('./modify'); + + function parseData(model, spec, callback) { + var config = model.config(), + count = 0; + + function loaded(d) { + return function(error, data) { + if (error) { + log.error('LOADING FAILED: ' + d.url + ' ' + error); + } else { + model.data(d.name).values(dl.read(data, d.format)); + } + if (--count === 0) callback(); + }; + } + + // process each data set definition + (spec || []).forEach(function(d) { + if (d.url) { + count += 1; + dl.load(dl.extend({url: d.url}, config.load), loaded(d)); + } + parseData.datasource(model, d); + }); + + if (count === 0) setTimeout(callback, 1); + return spec; + } + + parseData.datasource = function(model, d) { + var transform = (d.transform || []).map(function(t) { + return parseTransforms(model, t); + }), + mod = (d.modify || []).map(function(m) { + return parseModify(model, m, d); + }), + ds = model.data(d.name, mod.concat(transform)); + + if (d.values) { + ds.values(dl.read(d.values, d.format)); + } else if (d.source) { + // Derived ds will be pulsed by its src rather than the model. + ds.source(d.source).addListener(ds); + model.removeListener(ds.pipeline()[0]); + } + + return ds; + }; + + module.exports = parseData; +},{"./modify":101,"./transforms":108,"datalib":26,"vega-logging":47}],95:[function(require,module,exports){ + module.exports = (function() { + /* + * Generated by PEG.js 0.8.0. + * + * http://pegjs.majda.cz/ + */ + + function peg$subclass(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + } + + function SyntaxError(message, expected, found, offset, line, column) { + this.message = message; + this.expected = expected; + this.found = found; + this.offset = offset; + this.line = line; + this.column = column; + + this.name = "SyntaxError"; + } + + peg$subclass(SyntaxError, Error); + + function parse(input) { + var options = arguments.length > 1 ? arguments[1] : {}, + + peg$FAILED = {}, + + peg$startRuleFunctions = { start: peg$parsestart }, + peg$startRuleFunction = peg$parsestart, + + peg$c0 = peg$FAILED, + peg$c1 = ",", + peg$c2 = { type: "literal", value: ",", description: "\",\"" }, + peg$c3 = function(o, m) { return [o].concat(m); }, + peg$c4 = function(o) { return [o]; }, + peg$c5 = "[", + peg$c6 = { type: "literal", value: "[", description: "\"[\"" }, + peg$c7 = "]", + peg$c8 = { type: "literal", value: "]", description: "\"]\"" }, + peg$c9 = ">", + peg$c10 = { type: "literal", value: ">", description: "\">\"" }, + peg$c11 = function(f1, f2, o) { return {start: f1, end: f2, middle: o}; }, + peg$c12 = [], + peg$c13 = function(s, f) { return (s.filters = f, s); }, + peg$c14 = function(s) { return s; }, + peg$c15 = "(", + peg$c16 = { type: "literal", value: "(", description: "\"(\"" }, + peg$c17 = ")", + peg$c18 = { type: "literal", value: ")", description: "\")\"" }, + peg$c19 = function(m) { return {stream: m}; }, + peg$c20 = "@", + peg$c21 = { type: "literal", value: "@", description: "\"@\"" }, + peg$c22 = ":", + peg$c23 = { type: "literal", value: ":", description: "\":\"" }, + peg$c24 = function(n, e) { return {event: e, name: n}; }, + peg$c25 = function(m, e) { return {event: e, mark: m}; }, + peg$c26 = function(t, e) { return {event: e, target: t}; }, + peg$c27 = function(e) { return {event: e}; }, + peg$c28 = function(s) { return {signal: s}; }, + peg$c29 = "rect", + peg$c30 = { type: "literal", value: "rect", description: "\"rect\"" }, + peg$c31 = "symbol", + peg$c32 = { type: "literal", value: "symbol", description: "\"symbol\"" }, + peg$c33 = "path", + peg$c34 = { type: "literal", value: "path", description: "\"path\"" }, + peg$c35 = "arc", + peg$c36 = { type: "literal", value: "arc", description: "\"arc\"" }, + peg$c37 = "area", + peg$c38 = { type: "literal", value: "area", description: "\"area\"" }, + peg$c39 = "line", + peg$c40 = { type: "literal", value: "line", description: "\"line\"" }, + peg$c41 = "rule", + peg$c42 = { type: "literal", value: "rule", description: "\"rule\"" }, + peg$c43 = "image", + peg$c44 = { type: "literal", value: "image", description: "\"image\"" }, + peg$c45 = "text", + peg$c46 = { type: "literal", value: "text", description: "\"text\"" }, + peg$c47 = "group", + peg$c48 = { type: "literal", value: "group", description: "\"group\"" }, + peg$c49 = "mousedown", + peg$c50 = { type: "literal", value: "mousedown", description: "\"mousedown\"" }, + peg$c51 = "mouseup", + peg$c52 = { type: "literal", value: "mouseup", description: "\"mouseup\"" }, + peg$c53 = "click", + peg$c54 = { type: "literal", value: "click", description: "\"click\"" }, + peg$c55 = "dblclick", + peg$c56 = { type: "literal", value: "dblclick", description: "\"dblclick\"" }, + peg$c57 = "wheel", + peg$c58 = { type: "literal", value: "wheel", description: "\"wheel\"" }, + peg$c59 = "keydown", + peg$c60 = { type: "literal", value: "keydown", description: "\"keydown\"" }, + peg$c61 = "keypress", + peg$c62 = { type: "literal", value: "keypress", description: "\"keypress\"" }, + peg$c63 = "keyup", + peg$c64 = { type: "literal", value: "keyup", description: "\"keyup\"" }, + peg$c65 = "mousewheel", + peg$c66 = { type: "literal", value: "mousewheel", description: "\"mousewheel\"" }, + peg$c67 = "mousemove", + peg$c68 = { type: "literal", value: "mousemove", description: "\"mousemove\"" }, + peg$c69 = "mouseout", + peg$c70 = { type: "literal", value: "mouseout", description: "\"mouseout\"" }, + peg$c71 = "mouseover", + peg$c72 = { type: "literal", value: "mouseover", description: "\"mouseover\"" }, + peg$c73 = "mouseenter", + peg$c74 = { type: "literal", value: "mouseenter", description: "\"mouseenter\"" }, + peg$c75 = "touchstart", + peg$c76 = { type: "literal", value: "touchstart", description: "\"touchstart\"" }, + peg$c77 = "touchmove", + peg$c78 = { type: "literal", value: "touchmove", description: "\"touchmove\"" }, + peg$c79 = "touchend", + peg$c80 = { type: "literal", value: "touchend", description: "\"touchend\"" }, + peg$c81 = function(e) { return e; }, + peg$c82 = /^[a-zA-Z0-9_\-]/, + peg$c83 = { type: "class", value: "[a-zA-Z0-9_\\-]", description: "[a-zA-Z0-9_\\-]" }, + peg$c84 = function(n) { return n.join(""); }, + peg$c85 = /^[a-zA-Z0-9\-_ #.>+~[\]=|\^$*]/, + peg$c86 = { type: "class", value: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]", description: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]" }, + peg$c87 = function(c) { return c.join(""); }, + peg$c88 = /^['"a-zA-Z0-9_().><=! \t-&|~]/, + peg$c89 = { type: "class", value: "['\"a-zA-Z0-9_().><=! \\t-&|~]", description: "['\"a-zA-Z0-9_().><=! \\t-&|~]" }, + peg$c90 = function(v) { return v.join(""); }, + peg$c91 = /^[ \t\r\n]/, + peg$c92 = { type: "class", value: "[ \\t\\r\\n]", description: "[ \\t\\r\\n]" }, + + peg$currPos = 0, + peg$reportedPos = 0, + peg$cachedPos = 0, + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$silentFails = 0, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$reportedPos, peg$currPos); + } + + function offset() { + return peg$reportedPos; + } + + function line() { + return peg$computePosDetails(peg$reportedPos).line; + } + + function column() { + return peg$computePosDetails(peg$reportedPos).column; + } + + function expected(description) { + throw peg$buildException( + null, + [{ type: "other", description: description }], + peg$reportedPos + ); + } + + function error(message) { + throw peg$buildException(message, null, peg$reportedPos); + } + + function peg$computePosDetails(pos) { + function advance(details, startPos, endPos) { + var p, ch; + + for (p = startPos; p < endPos; p++) { + ch = input.charAt(p); + if (ch === "\n") { + if (!details.seenCR) { details.line++; } + details.column = 1; + details.seenCR = false; + } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { + details.line++; + details.column = 1; + details.seenCR = true; + } else { + details.column++; + details.seenCR = false; + } + } + } + + if (peg$cachedPos !== pos) { + if (peg$cachedPos > pos) { + peg$cachedPos = 0; + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; + } + advance(peg$cachedPosDetails, peg$cachedPos, pos); + peg$cachedPos = pos; + } + + return peg$cachedPosDetails; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildException(message, expected, pos) { + function cleanupExpected(expected) { + var i = 1; + + expected.sort(function(a, b) { + if (a.description < b.description) { + return -1; + } else if (a.description > b.description) { + return 1; + } else { + return 0; + } + }); + + while (i < expected.length) { + if (expected[i - 1] === expected[i]) { + expected.splice(i, 1); + } else { + i++; + } + } + } + + function buildMessage(expected, found) { + function stringEscape(s) { + function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } + + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\x08/g, '\\b') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\f/g, '\\f') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) + .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) + .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); + } + + var expectedDescs = new Array(expected.length), + expectedDesc, foundDesc, i; + + for (i = 0; i < expected.length; i++) { + expectedDescs[i] = expected[i].description; + } + + expectedDesc = expected.length > 1 + ? expectedDescs.slice(0, -1).join(", ") + + " or " + + expectedDescs[expected.length - 1] + : expectedDescs[0]; + + foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; + + return "Expected " + expectedDesc + " but " + foundDesc + " found."; + } + + var posDetails = peg$computePosDetails(pos), + found = pos < input.length ? input.charAt(pos) : null; + + if (expected !== null) { + cleanupExpected(expected); + } + + return new SyntaxError( + message !== null ? message : buildMessage(expected, found), + expected, + found, + pos, + posDetails.line, + posDetails.column + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parsemerged(); + + return s0; + } + + function peg$parsemerged() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s3 = peg$c1; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + s5 = peg$parsemerged(); + if (s5 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c3(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c4(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parseordered() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + s3 = peg$parsefiltered(); + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c1; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parsesep(); + if (s6 !== peg$FAILED) { + s7 = peg$parsefiltered(); + if (s7 !== peg$FAILED) { + s8 = peg$parsesep(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c7; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parsesep(); + if (s10 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 62) { + s11 = peg$c9; + peg$currPos++; + } else { + s11 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c10); } + } + if (s11 !== peg$FAILED) { + s12 = peg$parsesep(); + if (s12 !== peg$FAILED) { + s13 = peg$parseordered(); + if (s13 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c11(s3, s7, s13); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$parsefiltered(); + } + + return s0; + } + + function peg$parsefiltered() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsefilter(); + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsefilter(); + } + } else { + s2 = peg$c0; + } + if (s2 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c14(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parsestream() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c15; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c16); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsemerged(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c19(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 64) { + s1 = peg$c20; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c21); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsename(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c22; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parseeventType(); + if (s4 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c24(s2, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsemarkType(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c25(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsecss(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c26(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseeventType(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c27(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsename(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c28(s1); + } + s0 = s1; + } + } + } + } + } + + return s0; + } + + function peg$parsemarkType() { + var s0; + + if (input.substr(peg$currPos, 4) === peg$c29) { + s0 = peg$c29; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c30); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c31) { + s0 = peg$c31; + peg$currPos += 6; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c32); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c33) { + s0 = peg$c33; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c34); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c35) { + s0 = peg$c35; + peg$currPos += 3; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c36); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c37) { + s0 = peg$c37; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c38); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c39) { + s0 = peg$c39; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c40); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c41) { + s0 = peg$c41; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c42); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c43) { + s0 = peg$c43; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c45) { + s0 = peg$c45; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c46); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c47) { + s0 = peg$c47; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c48); } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parseeventType() { + var s0; + + if (input.substr(peg$currPos, 9) === peg$c49) { + s0 = peg$c49; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c50); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c51) { + s0 = peg$c51; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c53) { + s0 = peg$c53; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c54); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c55) { + s0 = peg$c55; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c56); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c57) { + s0 = peg$c57; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c58); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c59) { + s0 = peg$c59; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c60); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c61) { + s0 = peg$c61; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c62); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c63) { + s0 = peg$c63; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c64); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c65) { + s0 = peg$c65; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c66); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c67) { + s0 = peg$c67; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c68); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c69) { + s0 = peg$c69; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c70); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c71) { + s0 = peg$c71; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c72); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c73) { + s0 = peg$c73; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c74); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c75) { + s0 = peg$c75; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c76); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c77) { + s0 = peg$c77; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c78); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c79) { + s0 = peg$c79; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c80); } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefilter() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseexpr(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s3 = peg$c7; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c81(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + + return s0; + } + + function peg$parsename() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c84(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsecss() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c87(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseexpr() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c90(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsesep() { + var s0, s1; + + s0 = []; + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail({ type: "end", description: "end of input" }); + } + + throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); + } + } + + return { + SyntaxError: SyntaxError, + parse: parse + }; + })(); +},{}],96:[function(require,module,exports){ + var expr = require('vega-expression'), + args = ['datum', 'event', 'signals']; + + module.exports = expr.compiler(args, { + idWhiteList: args, + fieldVar: args[0], + globalVar: args[2], + functions: function(codegen) { + var fn = expr.functions(codegen); + fn.eventItem = function() { return 'event.vg.item'; }; + fn.eventGroup = 'event.vg.getGroup'; + fn.eventX = 'event.vg.getX'; + fn.eventY = 'event.vg.getY'; + fn.open = 'window.open'; + return fn; + } + }); +},{"vega-expression":45}],97:[function(require,module,exports){ + module.exports = { + axes: require('./axes'), + background: require('./background'), + data: require('./data'), + events: require('./events'), + expr: require('./expr'), + legends: require('./legends'), + mark: require('./mark'), + marks: require('./marks'), + modify: require('./modify'), + padding: require('./padding'), + predicates: require('./predicates'), + properties: require('./properties'), + signals: require('./signals'), + spec: require('./spec'), + streams: require('./streams'), + transforms: require('./transforms') + }; +},{"./axes":92,"./background":93,"./data":94,"./events":95,"./expr":96,"./legends":98,"./mark":99,"./marks":100,"./modify":101,"./padding":102,"./predicates":103,"./properties":104,"./signals":105,"./spec":106,"./streams":107,"./transforms":108}],98:[function(require,module,exports){ + var lgnd = require('../scene/legend'); + + function parseLegends(model, spec, legends, group) { + (spec || []).forEach(function(def, index) { + legends[index] = legends[index] || lgnd(model); + parseLegend(def, index, legends[index], group); + }); + } + + function parseLegend(def, index, legend, group) { + // legend scales + legend.size (def.size ? group.scale(def.size) : null); + legend.shape (def.shape ? group.scale(def.shape) : null); + legend.fill (def.fill ? group.scale(def.fill) : null); + legend.stroke(def.stroke ? group.scale(def.stroke) : null); + + // legend orientation + if (def.orient) legend.orient(def.orient); + + // legend offset + if (def.offset != null) legend.offset(def.offset); + + // legend title + legend.title(def.title || null); + + // legend values + legend.values(def.values || null); + + // legend label formatting + legend.format(def.format !== undefined ? def.format : null); + + // style properties + var p = def.properties; + legend.titleProperties(p && p.title || {}); + legend.labelProperties(p && p.labels || {}); + legend.legendProperties(p && p.legend || {}); + legend.symbolProperties(p && p.symbols || {}); + legend.gradientProperties(p && p.gradient || {}); + } + + module.exports = parseLegends; +},{"../scene/legend":116}],99:[function(require,module,exports){ + var dl = require('datalib'), + parseProperties = require('./properties'); + + function parseMark(model, mark) { + var props = mark.properties, + group = mark.marks; + + // parse mark property definitions + dl.keys(props).forEach(function(k) { + props[k] = parseProperties(model, mark.type, props[k]); + }); + + // parse delay function + if (mark.delay) { + mark.delay = parseProperties(model, mark.type, {delay: mark.delay}); + } + + // recurse if group type + if (group) { + mark.marks = group.map(function(g) { return parseMark(model, g); }); + } + + return mark; + } + + module.exports = parseMark; +},{"./properties":104,"datalib":26}],100:[function(require,module,exports){ + var parseMark = require('./mark'), + parseProperties = require('./properties'); + + function parseRootMark(model, spec, width, height) { + return { + type: 'group', + width: width, + height: height, + properties: defaults(spec.scene || {}, model), + scales: spec.scales || [], + axes: spec.axes || [], + legends: spec.legends || [], + marks: (spec.marks || []).map(function(m) { return parseMark(model, m); }) + }; + } + + var PROPERTIES = [ + 'fill', 'fillOpacity', 'stroke', 'strokeOpacity', + 'strokeWidth', 'strokeDash', 'strokeDashOffset' + ]; + + function defaults(spec, model) { + var config = model.config().scene, + props = {}, i, n, m, p, s; + + for (i=0, n=m=PROPERTIES.length; i= 0; --i) { + if (src[i][field] == value) + dest.push.apply(dest, src.splice(i, 1)); + } + }; + + function parseModify(model, def, ds) { + var signal = def.signal ? dl.field(def.signal) : null, + signalName = signal ? signal[0] : null, + predicate = def.predicate ? model.predicate(def.predicate.name || def.predicate) : null, + reeval = (predicate === null), + isClear = def.type === Types.CLEAR, + node = new Node(model).router(isClear); + + node.evaluate = function(input) { + if (predicate !== null) { // TODO: predicate args + var db = model.values(Deps.DATA, predicate.data || EMPTY), + sg = model.values(Deps.SIGNALS, predicate.signals || EMPTY); + reeval = predicate.call(predicate, {}, db, sg, model._predicates); + } + + log.debug(input, [def.type+"ing", reeval]); + if (!reeval || (!isClear && !input.signals[signalName])) return input; + + var datum = {}, + value = signal ? model.signalRef(def.signal) : null, + d = model.data(ds.name), + t = null; + + datum[def.field] = value; + + // We have to modify ds._data so that subsequent pulses contain + // our dynamic data. W/o modifying ds._data, only the output + // collector will contain dynamic tuples. + if (def.type === Types.INSERT) { + t = Tuple.ingest(datum); + input.add.push(t); + d._data.push(t); + } else if (def.type === Types.REMOVE) { + filter(def.field, value, input.add, input.rem); + filter(def.field, value, input.mod, input.rem); + d._data = d._data.filter(function(x) { return x[def.field] !== value; }); + } else if (def.type === Types.TOGGLE) { + var add = [], rem = []; + filter(def.field, value, input.rem, add); + filter(def.field, value, input.add, rem); + filter(def.field, value, input.mod, rem); + if (!(add.length || rem.length)) add.push(Tuple.ingest(datum)); + + input.add.push.apply(input.add, add); + d._data.push.apply(d._data, add); + input.rem.push.apply(input.rem, rem); + d._data = d._data.filter(function(x) { return rem.indexOf(x) === -1; }); + } else if (def.type === Types.CLEAR) { + input.rem.push.apply(input.rem, input.add); + input.rem.push.apply(input.rem, input.mod); + input.add = []; + input.mod = []; + d._data = []; + } + + input.fields[def.field] = 1; + return input; + }; + + if (signalName) node.dependency(Deps.SIGNALS, signalName); + + if (predicate) { + node.dependency(Deps.DATA, predicate.data); + node.dependency(Deps.SIGNALS, predicate.signals); + } + + return node; + } + + module.exports = parseModify; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],102:[function(require,module,exports){ + var dl = require('datalib'); + + function parsePadding(pad) { + return pad == null ? 'auto' : + dl.isObject(pad) ? pad : + dl.isNumber(pad) ? {top:pad, left:pad, right:pad, bottom:pad} : + pad === 'strict' ? pad : 'auto'; + } + + module.exports = parsePadding; +},{"datalib":26}],103:[function(require,module,exports){ + var dl = require('datalib'); + + var types = { + '=': parseComparator, + '==': parseComparator, + '!=': parseComparator, + '>': parseComparator, + '>=': parseComparator, + '<': parseComparator, + '<=': parseComparator, + 'and': parseLogical, + '&&': parseLogical, + 'or': parseLogical, + '||': parseLogical, + 'in': parseIn + }; + + var nullScale = function() { return 0; }; + nullScale.invert = nullScale; + + function parsePredicates(model, spec) { + (spec || []).forEach(function(s) { + var parse = types[s.type](model, s); + + /* jshint evil:true */ + var pred = Function("args", "db", "signals", "predicates", parse.code); + pred.root = function() { return model.scene().items[0]; }; // For global scales + pred.nullScale = nullScale; + pred.isFunction = dl.isFunction; + pred.signals = parse.signals; + pred.data = parse.data; + + model.predicate(s.name, pred); + }); + + return spec; + } + + function parseSignal(signal, signals) { + var s = dl.field(signal), + code = "signals["+s.map(dl.str).join("][")+"]"; + signals[s[0]] = 1; + return code; + } + + function parseOperands(model, operands) { + var decl = [], defs = [], + signals = {}, db = {}; + + function setSignal(s) { signals[s] = 1; } + function setData(d) { db[d] = 1; } + + dl.array(operands).forEach(function(o, i) { + var name = "o" + i, + def = ""; + + if (o.value !== undefined) { + def = dl.str(o.value); + } else if (o.arg) { + def = "args["+dl.str(o.arg)+"]"; + } else if (o.signal) { + def = parseSignal(o.signal, signals); + } else if (o.predicate) { + var ref = o.predicate, + predName = ref && (ref.name || ref), + pred = model.predicate(predName), + p = "predicates["+dl.str(predName)+"]"; + + pred.signals.forEach(setSignal); + pred.data.forEach(setData); + + if (dl.isObject(ref)) { + dl.keys(ref).forEach(function(k) { + if (k === "name") return; + var i = ref[k]; + def += "args["+dl.str(k)+"] = "; + if (i.signal) { + def += parseSignal(i.signal, signals); + } else if (i.arg) { + def += "args["+dl.str(i.arg)+"]"; + } + def += ", "; + }); + } + + def += p+".call("+p+", args, db, signals, predicates)"; + } + + decl.push(name); + defs.push(name+"=("+def+")"); + }); + + return { + code: "var " + decl.join(", ") + ";\n" + defs.join(";\n") + ";\n", + signals: dl.keys(signals), + data: dl.keys(db) + }; + } + + function parseComparator(model, spec) { + var ops = parseOperands(model, spec.operands); + if (spec.type === '=') spec.type = '=='; + + ops.code += "o0 = o0 instanceof Date ? o0.getTime() : o0;\n" + + "o1 = o1 instanceof Date ? o1.getTime() : o1;\n"; + + return { + code: ops.code + "return " + ["o0", "o1"].join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseLogical(model, spec) { + var ops = parseOperands(model, spec.operands), + o = [], i = 0, len = spec.operands.length; + + while (o.push("o"+i++) < len); + if (spec.type === 'and') spec.type = '&&'; + else if (spec.type === 'or') spec.type = '||'; + + return { + code: ops.code + "return " + o.join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseIn(model, spec) { + var o = [spec.item], code = ""; + if (spec.range) o.push.apply(o, spec.range); + if (spec.scale) { + code = parseScale(spec.scale, o); + } + + var ops = parseOperands(model, o); + code = ops.code + code + "\n var ordSet = null;\n"; + + if (spec.data) { + var field = dl.field(spec.field).map(dl.str); + code += "var where = function(d) { return d["+field.join("][")+"] == o0 };\n"; + code += "return db["+dl.str(spec.data)+"].filter(where).length > 0;"; + } else if (spec.range) { + // TODO: inclusive/exclusive range? + if (spec.scale) { + code += "if (scale.length == 2) {\n" + // inverting ordinal scales + " ordSet = scale(o1, o2);\n" + + "} else {\n" + + " o1 = scale(o1);\no2 = scale(o2);\n" + + "}"; + } + + code += "return ordSet !== null ? ordSet.indexOf(o0) !== -1 :\n" + + " o1 < o2 ? o1 <= o0 && o0 <= o2 : o2 <= o0 && o0 <= o1;"; + } + + return { + code: code, + signals: ops.signals, + data: ops.data.concat(spec.data ? [spec.data] : []) + }; + } + +// Populate ops such that ultimate scale/inversion function will be in `scale` var. + function parseScale(spec, ops) { + var code = "var scale = ", + idx = ops.length; + + if (dl.isString(spec)) { + ops.push({ value: spec }); + code += "this.root().scale(o"+idx+")"; + } else if (spec.arg) { // Scale function is being passed as an arg + ops.push(spec); + code += "o"+idx; + } else if (spec.name) { // Full scale parameter {name: ..} + ops.push(dl.isString(spec.name) ? {value: spec.name} : spec.name); + code += "(this.isFunction(o"+idx+") ? o"+idx+" : "; + if (spec.scope) { + ops.push(spec.scope); + code += "((o"+(idx+1)+".scale || this.root().scale)(o"+idx+") || this.nullScale)"; + } else { + code += "this.root().scale(o"+idx+")"; + } + code += ")"; + } + + if (spec.invert === true) { // Allow spec.invert.arg? + code += ".invert"; + } + + return code+";\n"; + } + + module.exports = parsePredicates; +},{"datalib":26}],104:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple; + + var DEPS = ["signals", "scales", "data", "fields"]; + + function properties(model, mark, spec) { + var config = model.config(), + code = "", + names = dl.keys(spec), + i, len, name, ref, vars = {}, + deps = { + signals: {}, + scales: {}, + data: {}, + fields: {}, + nested: [], + _nRefs: {}, // Temp stash to de-dupe nested refs. + reflow: false + }; + + code += "var o = trans ? {} : item, d=0, set=this.tpl.set, tmpl=signals||{}, t;\n" + + // Stash for dl.template + "tmpl.datum = item.datum;\n" + + "tmpl.group = group;\n" + + "tmpl.parent = group.datum;\n"; + + function handleDep(p) { + if (ref[p] == null) return; + var k = dl.array(ref[p]), i, n; + for (i=0, n=k.length; i 0) ? "\n " : " "; + if (ref.rule) { + ref = rule(model, name, ref.rule); + code += "\n " + ref.code; + } else if (dl.isArray(ref)) { + ref = rule(model, name, ref); + code += "\n " + ref.code; + } else { + ref = valueRef(config, name, ref); + code += "d += set(o, "+dl.str(name)+", "+ref.val+");"; + } + + vars[name] = true; + DEPS.forEach(handleDep); + deps.reflow = deps.reflow || ref.reflow; + if (ref.nested.length) ref.nested.forEach(handleNestedRefs); + } + + // If nested references are present, sort them based on their level + // to speed up determination of whether encoders should be reeval'd. + dl.keys(deps._nRefs).forEach(function(k) { deps.nested.push(deps._nRefs[k]); }); + deps.nested.sort(function(a, b) { + a = a.level; + b = b.level; + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + }); + + if (vars.x2) { + if (vars.x) { + code += "\n if (o.x > o.x2) { " + + "\n t = o.x;" + + "\n d += set(o, 'x', o.x2);" + + "\n d += set(o, 'x2', t); " + + "\n };"; + code += "\n d += set(o, 'width', (o.x2 - o.x));"; + } else if (vars.width) { + code += "\n d += set(o, 'x', (o.x2 - o.width));"; + } else { + code += "\n d += set(o, 'x', o.x2);"; + } + } + + if (vars.xc) { + if (vars.width) { + code += "\n d += set(o, 'x', (o.xc - o.width/2));" ; + } else { + code += "\n d += set(o, 'x', o.xc);" ; + } + } + + if (vars.y2) { + if (vars.y) { + code += "\n if (o.y > o.y2) { " + + "\n t = o.y;" + + "\n d += set(o, 'y', o.y2);" + + "\n d += set(o, 'y2', t);" + + "\n };"; + code += "\n d += set(o, 'height', (o.y2 - o.y));"; + } else if (vars.height) { + code += "\n d += set(o, 'y', (o.y2 - o.height));"; + } else { + code += "\n d += set(o, 'y', o.y2);"; + } + } + + if (vars.yc) { + if (vars.height) { + code += "\n d += set(o, 'y', (o.yc - o.height/2));" ; + } else { + code += "\n d += set(o, 'y', o.yc);" ; + } + } + + if (hasPath(mark, vars)) code += "\n d += (item.touch(), 1);"; + code += "\n if (trans) trans.interpolate(item, o);"; + code += "\n return d > 0;"; + + try { + /* jshint evil:true */ + var encoder = Function('item', 'group', 'trans', 'db', + 'signals', 'predicates', code); + encoder.tpl = Tuple; + encoder.util = dl; + encoder.d3 = d3; // For color spaces + dl.extend(encoder, dl.template.context); + return { + encode: encoder, + signals: dl.keys(deps.signals), + scales: dl.keys(deps.scales), + data: dl.keys(deps.data), + fields: dl.keys(deps.fields), + nested: deps.nested, + reflow: deps.reflow + }; + } catch (e) { + log.error(e); + log.log(code); + } + } + + function dependencies(a, b) { + if (!dl.isObject(a)) { + a = {reflow: false, nested: []}; + DEPS.forEach(function(d) { a[d] = []; }); + } + + if (dl.isObject(b)) { + a.reflow = a.reflow || b.reflow; + a.nested.push.apply(a.nested, b.nested); + DEPS.forEach(function(d) { a[d].push.apply(a[d], b[d]); }); + } + + return a; + } + + function hasPath(mark, vars) { + return vars.path || + ((mark==='area' || mark==='line') && + (vars.x || vars.x2 || vars.width || + vars.y || vars.y2 || vars.height || + vars.tension || vars.interpolate)); + } + + function rule(model, name, rules) { + var config = model.config(), + deps = dependencies(), + inputs = [], code = ''; + + (rules||[]).forEach(function(r, i) { + var def = r.predicate, + predName = def && (def.name || def), + pred = model.predicate(predName), + p = 'predicates['+dl.str(predName)+']', + input = [], args = name+'_arg'+i, + ref; + + if (dl.isObject(def)) { + dl.keys(def).forEach(function(k) { + if (k === 'name') return; + var ref = valueRef(config, i, def[k]); + input.push(dl.str(k)+': '+ref.val); + dependencies(deps, ref); + }); + } + + ref = valueRef(config, name, r); + dependencies(deps, ref); + + if (predName) { + deps.signals.push.apply(deps.signals, pred.signals); + deps.data.push.apply(deps.data, pred.data); + inputs.push(args+" = {\n "+input.join(",\n ")+"\n }"); + code += "if ("+p+".call("+p+","+args+", db, signals, predicates)) {" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"; + code += rules[i+1] ? "\n } else " : " }"; + } else { + code += "{" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"+ + "\n }\n"; + } + }); + + code = "var " + inputs.join(",\n ") + ";\n " + code; + return (deps.code = code, deps); + } + + function valueRef(config, name, ref) { + if (ref == null) return null; + + if (name==='fill' || name==='stroke') { + if (ref.c) { + return colorRef(config, 'hcl', ref.h, ref.c, ref.l); + } else if (ref.h || ref.s) { + return colorRef(config, 'hsl', ref.h, ref.s, ref.l); + } else if (ref.l || ref.a) { + return colorRef(config, 'lab', ref.l, ref.a, ref.b); + } else if (ref.r || ref.g || ref.b) { + return colorRef(config, 'rgb', ref.r, ref.g, ref.b); + } + } + + // initialize value + var val = null, scale = null, + deps = dependencies(), + sgRef = null, fRef = null, sRef = null, tmpl = {}; + + if (ref.template !== undefined) { + val = dl.template.source(ref.template, 'tmpl', tmpl); + dl.keys(tmpl).forEach(function(k) { + var f = dl.field(k), + a = f.shift(); + if (a === 'parent' || a === 'group') { + deps.nested.push({ + parent: a === 'parent', + group: a === 'group', + level: 1 + }); + } else if (a === 'datum') { + deps.fields.push(f[0]); + } else { + deps.signals.push(a); + } + }); + } + + if (ref.value !== undefined) { + val = dl.str(ref.value); + } + + if (ref.signal !== undefined) { + sgRef = dl.field(ref.signal); + val = 'signals['+sgRef.map(dl.str).join('][')+']'; + deps.signals.push(sgRef.shift()); + } + + if (ref.field !== undefined) { + ref.field = dl.isString(ref.field) ? {datum: ref.field} : ref.field; + fRef = fieldRef(ref.field); + val = fRef.val; + dependencies(deps, fRef); + } + + if (ref.scale !== undefined) { + sRef = scaleRef(ref.scale); + scale = sRef.val; + dependencies(deps, sRef); + deps.scales.push(ref.scale.name || ref.scale); + + // run through scale function if val specified. + // if no val, scale function is predicate arg. + if (val !== null || ref.band || ref.mult || ref.offset) { + val = scale + (ref.band ? '.rangeBand()' : + '('+(val !== null ? val : 'item.datum.data')+')'); + } else { + val = scale; + } + } + + // multiply, offset, return value + val = '(' + (ref.mult?(dl.number(ref.mult)+' * '):'') + val + ')' + + (ref.offset ? ' + ' + dl.number(ref.offset) : ''); + + // Collate dependencies + return (deps.val = val, deps); + } + + function colorRef(config, type, x, y, z) { + var xx = x ? valueRef(config, '', x) : config.color[type][0], + yy = y ? valueRef(config, '', y) : config.color[type][1], + zz = z ? valueRef(config, '', z) : config.color[type][2], + deps = dependencies(); + + [xx, yy, zz].forEach(function(v) { + if (dl.isArray) return; + dependencies(deps, v); + }); + + var val = '(this.d3.' + type + '(' + [xx.val, yy.val, zz.val].join(',') + ') + "")'; + return (deps.val = val, deps); + } + +// {field: {datum: "foo"} } -> item.datum.foo +// {field: {group: "foo"} } -> group.foo +// {field: {parent: "foo"} } -> group.datum.foo + function fieldRef(ref) { + if (dl.isString(ref)) { + return {val: dl.field(ref).map(dl.str).join('][')}; + } + + // Resolve nesting/parent lookups + var l = ref.level || 1, + nested = (ref.group || ref.parent) && l, + scope = nested ? Array(l).join('group.mark.') : '', + r = fieldRef(ref.datum || ref.group || ref.parent || ref.signal), + val = r.val, + deps = dependencies(null, r); + + if (ref.datum) { + val = 'item.datum['+val+']'; + deps.fields.push(ref.datum); + } else if (ref.group) { + val = scope+'group['+val+']'; + deps.nested.push({ level: l, group: true }); + } else if (ref.parent) { + val = scope+'group.datum['+val+']'; + deps.nested.push({ level: l, parent: true }); + } else if (ref.signal) { + val = 'signals['+val+']'; + deps.signals.push(dl.field(ref.signal)[0]); + deps.reflow = true; + } + + return (deps.val = val, deps); + } + +// {scale: "x"} +// {scale: {name: "x"}}, +// {scale: fieldRef} + function scaleRef(ref) { + var scale = null, + fr = null, + deps = dependencies(); + + if (dl.isString(ref)) { + scale = dl.str(ref); + } else if (ref.name) { + scale = dl.isString(ref.name) ? dl.str(ref.name) : (fr = fieldRef(ref.name)).val; + } else { + scale = (fr = fieldRef(ref)).val; + } + + scale = '(item.mark._scaleRefs['+scale+'] = 1, group.scale('+scale+'))'; + if (ref.invert) scale += '.invert'; + + // Mark scale refs as they're dealt with separately in mark._scaleRefs. + if (fr) fr.nested.forEach(function(g) { g.scale = true; }); + return fr ? (fr.val = scale, fr) : (deps.val = scale, deps); + } + + module.exports = properties; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],105:[function(require,module,exports){ + var dl = require('datalib'), + SIGNALS = require('vega-dataflow').Dependencies.SIGNALS, + expr = require('./expr'); + + var RESERVED = ['datum', 'event', 'signals', 'width', 'height', 'padding'] + .concat(dl.keys(expr.codegen.functions)); + + function parseSignals(model, spec) { + // process each signal definition + (spec || []).forEach(function(s) { + if (RESERVED.indexOf(s.name) !== -1) { + throw Error('Signal name "'+s.name+'" is a '+ + 'reserved keyword ('+RESERVED.join(', ')+').'); + } + + var signal = model.signal(s.name, s.init) + .verbose(s.verbose); + + if (s.init && s.init.expr) { + s.init.expr = expr(s.init.expr); + signal.value(exprVal(model, s.init)); + } + + if (s.expr) { + s.expr = expr(s.expr); + signal.evaluate = function(input) { + var val = exprVal(model, s), + sg = input.signals; + if (val !== signal.value() || signal.verbose()) { + signal.value(val); + sg[s.name] = 1; + } + return sg[s.name] ? input : model.doNotPropagate; + }; + signal.dependency(SIGNALS, s.expr.globals); + s.expr.globals.forEach(function(dep) { + model.signal(dep).addListener(signal); + }); + } + }); + + return spec; + } + + function exprVal(model, spec) { + var e = spec.expr, + val = e.fn(null, null, model.values(SIGNALS, e.globals)); + return spec.scale ? parseSignals.scale(model, spec, val) : val; + } + + parseSignals.scale = function scale(model, spec, value, datum, evt) { + var def = spec.scale, + name = def.name || def.signal || def, + scope = def.scope, e; + + if (scope) { + if (scope.signal) { + scope = model.signalRef(scope.signal); + } else if (dl.isString(scope)) { // Scope is an expression + e = def._expr = (def._expr || expr(scope)); + scope = e.fn(datum, evt, model.values(SIGNALS, e.globals)); + } + } + + if (!scope || !scope.scale) { + scope = (scope && scope.mark) ? scope.mark.group : model.scene().items[0]; + } + + var s = scope.scale(name); + return !s ? value : (def.invert ? s.invert(value) : s(value)); + }; + + module.exports = parseSignals; +},{"./expr":96,"datalib":26,"vega-dataflow":41}],106:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Model = require('../core/Model'), + View = require('../core/View'); + + function parseSpec(spec, callback) { + var vf = arguments[arguments.length-1], + viewFactory = arguments.length > 2 && dl.isFunction(vf) ? vf : View.factory, + config = arguments[2] !== viewFactory ? arguments[2] : {}, + model = new Model(config); + + function parse(spec) { + // protect against subsequent spec modification + spec = dl.duplicate(spec); + + var parsers = require('./'), + create = function() { callback(viewFactory(model)); }, + width = spec.width || 500, + height = spec.height || 500, + padding = parsers.padding(spec.padding); + + // create signals for width, height and padding + model.signal('width', width); + model.signal('height', height); + model.signal('padding', padding); + + // initialize model + model.defs({ + width: width, + height: height, + padding: padding, + viewport: spec.viewport || null, + background: parsers.background(spec.background), + signals: parsers.signals(model, spec.signals), + predicates: parsers.predicates(model, spec.predicates), + marks: parsers.marks(model, spec, width, height), + data: parsers.data(model, spec.data, create) + }); + } + + if (dl.isObject(spec)) { + parse(spec); + } else if (dl.isString(spec)) { + var opts = dl.extend({url: spec}, model.config().load); + dl.load(opts, function(err, data) { + if (err) { + log.error('LOADING SPECIFICATION FAILED: ' + err.statusText); + } else { + try { + parse(JSON.parse(data)); + } catch (e) { + log.error('INVALID SPECIFICATION: Must be a valid JSON object. '+e); + } + } + }); + } else { + log.error('INVALID SPECIFICATION: Must be a valid JSON object or URL.'); + } + } + + module.exports = parseSpec; +},{"../core/Model":88,"../core/View":89,"./":97,"datalib":26,"vega-logging":47}],107:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + parseSignals = require('./signals'), + selector = require('./events'), + expr = require('./expr'); + + var GATEKEEPER = '_vgGATEKEEPER'; + + var vgEvent = { + getGroup: function(name) { return name ? this.name[name] : this.group; }, + getXY: function(item) { + var p = {x: this.x, y: this.y}; + if (typeof item === 'string') { + item = this.name[item]; + } + for (; item; item = item.mark && item.mark.group) { + p.x -= item.x || 0; + p.y -= item.y || 0; + } + return p; + }, + getX: function(item) { return this.getXY(item).x; }, + getY: function(item) { return this.getXY(item).y; } + }; + + function parseStreams(view) { + var model = view.model(), + spec = model.defs().signals, + registry = {handlers: {}, nodes: {}}, + internal = dl.duplicate(registry), // Internal event processing + external = dl.duplicate(registry); // External event processing + + (spec || []).forEach(function(sig) { + var signal = model.signal(sig.name); + if (sig.expr) return; // Cannot have an expr and stream definition. + + (sig.streams || []).forEach(function(stream) { + var sel = selector.parse(stream.type), + exp = expr(stream.expr); + mergedStream(signal, sel, exp, stream); + }); + }); + + // We register the event listeners all together so that if multiple + // signals are registered on the same event, they will receive the + // new value on the same pulse. + dl.keys(internal.handlers).forEach(function(type) { + view.on(type, function(evt, item) { + evt.preventDefault(); // stop text selection + extendEvent(evt, item); + fire(internal, type, (item && item.datum) || {}, evt); + }); + }); + + // add external event listeners + dl.keys(external.handlers).forEach(function(type) { + if (typeof window === 'undefined') return; // No external support + + var h = external.handlers[type], + t = type.split(':'), // --> no element pseudo-selectors + elt = (t[0] === 'window') ? [window] : + window.document.querySelectorAll(t[0]); + + function handler(evt) { + extendEvent(evt); + fire(external, type, d3.select(this).datum(), evt); + } + + for (var i=0; i 0, + i, ilen, j, jlen, group, legend; + + if (input.add.length || input.rem.length || !items.length || + input.mod.length === items.length || + type === 'area' || type === 'line') { + bound.mark(this._mark, null, isGrp && !hasLegends); + } else { + input.mod.forEach(function(item) { bound.item(item); }); + } + + if (isGrp && hasLegends) { + for (i=0, ilen=items.length; i this._stamp) { + join.call(this, fcs, output, this._ds.values(), true, fullUpdate); + } else if (fullUpdate) { + output.mod = this._mark.items.slice(); + } + } else { + data = dl.isFunction(this._def.from) ? this._def.from() : [Sentinel]; + join.call(this, input, output, data); + } + + // Stash output before Bounder for downstream reactive geometry. + this._output = output = this._graph.evaluate(output, this._encoder); + + // Add any new scale references to the dependency list, and ensure + // they're connected. + if (update.nested && update.nested.length && this._status === CONNECTED) { + dl.keys(this._mark._scaleRefs).forEach(function(s) { + var scale = self._parent.scale(s); + if (!scale) return; + + scale.addListener(self); + self.dependency(Deps.SCALES, s); + self._encoder.dependency(Deps.SCALES, s); + }); + } + + // Supernodes calculate bounds too, but only on items marked dirty. + if (this._isSuper) { + output.mod = output.mod.filter(function(x) { return x._dirty; }); + output = this._graph.evaluate(output, this._bounder); + } + + return output; + }; + + function newItem() { + var item = Tuple.ingest(new Item(this._mark)); + + // For the root node's item + if (this._def.width) Tuple.set(item, 'width', this._def.width); + if (this._def.height) Tuple.set(item, 'height', this._def.height); + return item; + } + + function join(input, output, data, ds, fullUpdate) { + var keyf = keyFunction(this._def.key || (ds ? '_id' : null)), + prev = this._mark.items || [], + rem = ds ? input.rem : prev, + mod = Tuple.idMap((!ds || fullUpdate) ? data : input.mod), + next = [], + i, key, len, item, datum, enter, diff; + + // Only mark rems as exiting. Due to keyf, there may be an add/mod + // tuple that replaces it. + for (i=0, len=rem.length; i0) s += '|'; + s += String(f[i](d)); + } + return s; + }; + } + + module.exports = Builder; +},{"../parse/data":94,"./Bounder":109,"./Encoder":111,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],111:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + df = require('vega-dataflow'), + Node = df.Node, // jshint ignore:line + Deps = df.Dependencies, + bound = require('vega-scenegraph').bound; + + var EMPTY = {}; + + function Encoder(graph, mark, builder) { + var props = mark.def.properties || {}, + enter = props.enter, + update = props.update, + exit = props.exit; + + Node.prototype.init.call(this, graph); + + this._mark = mark; + this._builder = builder; + var s = this._scales = []; + + // Only scales used in the 'update' property set are set as + // encoder depedencies to have targeted reevaluations. However, + // we still want scales in 'enter' and 'exit' to be evaluated + // before the encoder. + if (enter) s.push.apply(s, enter.scales); + + if (update) { + this.dependency(Deps.DATA, update.data); + this.dependency(Deps.SIGNALS, update.signals); + this.dependency(Deps.FIELDS, update.fields); + this.dependency(Deps.SCALES, update.scales); + s.push.apply(s, update.scales); + } + + if (exit) s.push.apply(s, exit.scales); + + return this.mutates(true); + } + + var proto = (Encoder.prototype = new Node()); + + proto.evaluate = function(input) { + log.debug(input, ['encoding', this._mark.def.type]); + var graph = this._graph, + props = this._mark.def.properties || {}, + items = this._mark.items, + enter = props.enter, + update = props.update, + exit = props.exit, + dirty = input.dirty, + preds = graph.predicates(), + req = input.request, + group = this._mark.group, + guide = group && (group.mark.axis || group.mark.legend), + db = EMPTY, sg = EMPTY, i, len, item, prop; + + if (req && !guide) { + if ((prop = props[req]) && input.mod.length) { + db = prop.data ? graph.values(Deps.DATA, prop.data) : null; + sg = prop.signals ? graph.values(Deps.SIGNALS, prop.signals) : null; + + for (i=0, len=input.mod.length; i this._stamp) return true; + } + + return false; + } + +// Short-circuit encoder if user specifies items + Encoder.update = function(graph, trans, request, items, dirty) { + items = dl.array(items); + var preds = graph.predicates(), + db = graph.values(Deps.DATA), + sg = graph.values(Deps.SIGNALS), + i, len, item, props, prop; + + for (i=0, len=items.length; i 0, + hasAxes = dl.array(this._def.axes).length > 0, + hasLegends = dl.array(this._def.legends).length > 0, + i, j, c, len, group, pipeline, def, inline = false; + + for (i=0, len=input.add.length; i=0; --i) { + group = input.add[i]; + for (j=this._children[group._id].length-1; j>=0; --j) { + c = this._children[group._id][j]; + c.builder.connect(); + pipeline = c.builder.pipeline(); + def = c.builder._def; + + // This new child needs to be built during this propagation cycle. + // We could add its builder as a listener off the _recursor node, + // but try to inline it if we can to minimize graph dispatches. + inline = (def.type !== Types.GROUP); + inline = inline && (this._graph.data(c.from) !== undefined); + inline = inline && (pipeline[pipeline.length-1].listeners().length === 1); // Reactive geom source + inline = inline && (def.from && !def.from.mark); // Reactive geom target + c.inline = inline; + + if (inline) this._graph.evaluate(input, c.builder); + else this._recursor.addListener(c.builder); + } + } + + function removeTemp(c) { + if (c.type == Types.MARK && !c.inline && + builder._graph.data(c.from) !== undefined) { + builder._recursor.removeListener(c.builder); + } + } + + function updateAxis(a) { + var scale = a.scale(); + if (!input.scales[scale.scaleName]) return; + a.reset().def(); + } + + function updateLegend(l) { + var scale = l.size() || l.shape() || l.fill() || l.stroke(); + if (!input.scales[scale.scaleName]) return; + l.reset().def(); + } + + for (i=0, len=input.mod.length; i rng[1]) { + start = rng[1] || 0; + rng = [start + (bw * len + space), start]; + } else { + start = rng[0] || 0; + rng = [start, start + (bw * len + space)]; + } + } + + str = typeof rng[0] === 'string'; + if (str || rng.length > 2 || rng.length===1 || dataDrivenRange) { + scale.range(rng); // color or shape values + spatial = false; + } else if (points && round) { + scale.rangeRoundPoints(rng, pad); + } else if (points) { + scale.rangePoints(rng, pad); + } else if (round) { + scale.rangeRoundBands(rng, pad, outer); + } else { + scale.rangeBands(rng, pad, outer); + } + + prev.range = rng; + this._updated = true; + } + + if (!scale.invert && spatial) invertOrdinal(scale); + } + +// "Polyfill" ordinal scale inversion. Currently, only ordinal scales +// with ordered numeric ranges are supported. + var bisect = d3.bisector(dl.numcmp).right, + findAsc = function(a, x) { return bisect(a,x) - 1; }, + findDsc = d3.bisector(function(a,b) { return -1 * dl.numcmp(a,b); }).left; + + function invertOrdinal(scale) { + scale.invert = function(x, y) { + var rng = scale.range(), + asc = rng[0] < rng[1], + find = asc ? findAsc : findDsc; + + if (arguments.length === 1) { + if (!dl.isNumber(x)) { + throw Error('Ordinal scale inversion is only supported for numeric input ('+x+').'); + } + return scale.domain()[find(rng, x)]; + + } else if (arguments.length === 2) { // Invert extents + if (!dl.isNumber(x) || !dl.isNumber(y)) { + throw Error('Extents to ordinal invert are not numbers ('+x+', '+y+').'); + } + + var domain = scale.domain(), + a = find(rng, x), + b = find(rng, y), + n = rng.length - 1, r; + if (b < a) { r = a; a = b; b = a; } // ensure a <= b + if (a < 0) a = 0; + if (b > n) b = n; + + return (asc ? dl.range(a, b+1) : dl.range(b, a-1, -1)) + .map(function(i) { return domain[i]; }); + } + }; + } + + function quantitative(scale, rng, group) { + var def = this._def, + prev = scale._prev, + round = signal.call(this, def.round), + exponent = signal.call(this, def.exponent), + clamp = signal.call(this, def.clamp), + nice = signal.call(this, def.nice), + domain, interval; + + // domain + domain = (def.type === Types.QUANTILE) ? + dataRef.call(this, DataRef.DOMAIN, def.domain, scale, group) : + domainMinMax.call(this, scale, group); + if (domain && !dl.equal(prev.domain, domain)) { + scale.domain(domain); + prev.domain = domain; + this._updated = true; + } + + // range + // vertical scales should flip by default, so use XOR here + if (signal.call(this, def.range) === 'height') rng = rng.reverse(); + if (dl.equal(prev.range, rng)) return; + scale[round && scale.rangeRound ? 'rangeRound' : 'range'](rng); + prev.range = rng; + this._updated = true; + + // TODO: Support signals for these properties. Until then, only eval + // them once. + if (this._stamp > 0) return; + if (exponent && def.type===Types.POWER) scale.exponent(exponent); + if (clamp) scale.clamp(true); + if (nice) { + if (def.type === Types.TIME) { + interval = d3.time[nice]; + if (!interval) log.error('Unrecognized interval: ' + interval); + scale.nice(interval); + } else { + scale.nice(); + } + } + } + + function isUniques(scale) { + return scale.type === Types.ORDINAL || scale.type === Types.QUANTILE; + } + + function getRefs(def) { + return def.fields || dl.array(def); + } + + function inherits(refs) { + return refs.some(function(r) { + if (!r.data) return true; + return r.data && dl.array(r.field).some(function(f) { + return f.parent; + }); + }); + } + + function getFields(ref, group) { + return dl.array(ref.field).map(function(f) { + return f.parent ? + dl.accessor(f.parent)(group.datum) : + f; // String or {'signal'} + }); + } + +// Scale datarefs can be computed over multiple schema types. +// This function determines the type of aggregator created, and +// what data is sent to it: values, tuples, or multi-tuples that must +// be standardized into a consistent schema. + function aggrType(def, scale) { + var refs = getRefs(def); + + // If we're operating over only a single domain, send full tuples + // through for efficiency (fewer accessor creations/calls) + if (refs.length == 1 && dl.array(refs[0].field).length == 1) { + return Aggregate.TYPES.TUPLE; + } + + // With quantitative scales, we only care about min/max. + if (!isUniques(scale)) return Aggregate.TYPES.VALUE; + + // If we don't sort, then we can send values directly to aggrs as well + if (!dl.isObject(def.sort)) return Aggregate.TYPES.VALUE; + + return Aggregate.TYPES.MULTI; + } + + function getCache(which, def, scale, group) { + var refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + uniques = isUniques(scale), + sort = def.sort, + ck = '_'+which, + fields = getFields(refs[0], group); + + if (scale[ck] || this[ck]) return scale[ck] || this[ck]; + + var cache = new Aggregate(this._graph).type(atype), + groupby, summarize; + + // If a scale's dataref doesn't inherit data from the group, we can + // store the dataref aggregator at the Scale (dataflow node) level. + if (inherit) { + scale[ck] = cache; + } else { + this[ck] = cache; + } + + if (uniques) { + if (atype === Aggregate.TYPES.VALUE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.identity }]; + summarize = {'*': DataRef.COUNT}; + } else if (atype === Aggregate.TYPES.TUPLE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.$(fields[0]) }]; + summarize = dl.isObject(sort) ? [{ + field: DataRef.VALUE, + get: dl.$(sort.field), + ops: [sort.op] + }] : {'*': DataRef.COUNT}; + } else { // atype === Aggregate.TYPES.MULTI + groupby = DataRef.GROUPBY; + summarize = [{ field: DataRef.VALUE, ops: [sort.op] }]; + } + } else { + groupby = []; + summarize = [{ + field: DataRef.VALUE, + get: (atype == Aggregate.TYPES.TUPLE) ? dl.$(fields[0]) : dl.identity, + ops: [DataRef.MIN, DataRef.MAX], + as: [DataRef.MIN, DataRef.MAX] + }]; + } + + cache.param('groupby', groupby) + .param('summarize', summarize); + + return (cache._lastUpdate = -1, cache); + } + + function dataRef(which, def, scale, group) { + if (def == null) { return []; } + if (dl.isArray(def)) return def.map(signal.bind(this)); + + var self = this, graph = this._graph, + refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + cache = getCache.apply(this, arguments), + sort = def.sort, + uniques = isUniques(scale), + i, rlen, j, flen, ref, fields, field, data, from, so, cmp; + + function addDep(s) { + self.dependency(Deps.SIGNALS, s); + } + + if (inherit || (!inherit && cache._lastUpdate < this._stamp)) { + for (i=0, rlen=refs.length; i 1) f = 1; + e = curr.ease(f); + + for (i=0, n=curr.length; i 0 ? (e = 1e-12, Math.ceil) : (e = -1e-12, Math.floor), + e; + function log(x) { + return (domain[0] < 0 ? + -Math.log(x > 0 ? 0 : -x) : + Math.log(x < 0 ? 0 : x)) / Math.log(base); + } + function pow(x) { + return domain[0] < 0 ? -Math.pow(base, -x) : Math.pow(base, x); + } + return function(d) { + return pow(v(log(d) + e)) / d >= k ? f(d) : ''; + }; + } + + function getFormatter(formatType, str) { + var fmt = dl.format, + log = scale.type === 'log', + domain, f; + + switch (formatType) { + case NUMBER: + domain = scale.domain(); + f = fmt.auto.number(domain, tickCount, str || (log ? '.1r' : null)); + return log ? logFilter(domain, tickCount, f) : f; + case TIME: return (str ? fmt : fmt.auto).time(str); + case UTC: return (str ? fmt : fmt.auto).utc(str); + default: return String; + } + } + + function getTicks(format) { + var major = tickValues || (scale.ticks ? scale.ticks(tickCount) : scale.domain()), + minor = axisSubdivide(scale, major, tickSubdivide).map(ingest); + major = major.map(function(d) { return (d = ingest(d), d.label = format(d.data), d); }); + return [major, minor]; + } + + axis.def = function() { + if (!axisDef.type) axis_def(scale); + + var ticks = getTicks(getTickFormat()); + var tdata = title ? [title].map(ingest) : []; + + axisDef.marks[0].from = function() { return grid ? ticks[0] : []; }; + axisDef.marks[1].from = function() { return ticks[0]; }; + axisDef.marks[2].from = function() { return ticks[1]; }; + axisDef.marks[3].from = axisDef.marks[1].from; + axisDef.marks[4].from = function() { return [1]; }; + axisDef.marks[5].from = function() { return tdata; }; + axisDef.offset = offset; + axisDef.orient = orient; + axisDef.layer = layer; + if (titleOffset === 'auto') titleAutoOffset(axisDef); + + return axisDef; + }; + + function titleAutoOffset(axisDef) { + var orient = axisDef.orient, + update = axisDef.marks[5].properties.update, + fn = update.encode, + min = config.titleOffsetAutoMin, + max = config.titleOffsetAutoMax, + pad = config.titleOffsetAutoMargin; + + // Offset axis title using bounding box of axis domain and labels + // Assumes other components are **encoded and bounded** beforehand + update.encode = function(item, group, trans, db, signals, preds) { + var dirty = fn.call(fn, item, group, trans, db, signals, preds), + field = (orient==='bottom' || orient==='top') ? 'y' : 'x'; + if (titleStyle[field] != null) return dirty; + + axisBounds.clear() + .union(group.items[3].bounds) + .union(group.items[4].bounds); + + var o = trans ? {} : item, + method = (orient==='left' || orient==='right') ? 'width' : 'height', + sign = (orient==='top' || orient==='left') ? -1 : 1, + off = ~~(axisBounds[method]() + item.fontSize/2 + pad); + + Tuple.set(o, field, sign * Math.min(Math.max(min, off), max)); + if (trans) trans.interpolate(item, o); + return true; + }; + } + + function axis_def(scale) { + // setup scale mapping + var newScale, oldScale, range; + if (scale.type === ORDINAL) { + newScale = {scale: scale.scaleName, offset: 0.5 + scale.rangeBand()/2}; + oldScale = newScale; + } else { + newScale = {scale: scale.scaleName, offset: 0.5}; + oldScale = {scale: scale.scaleName+':prev', offset: 0.5}; + } + range = axisScaleRange(scale); + + // setup axis marks + dl.extend(m.gridLines, axisTicks(config)); + dl.extend(m.majorTicks, axisTicks(config)); + dl.extend(m.minorTicks, axisTicks(config)); + dl.extend(m.tickLabels, axisTickLabels(config)); + dl.extend(m.domain, axisDomain(config)); + dl.extend(m.title, axisTitle(config)); + m.gridLines.properties.enter.stroke = {value: config.gridColor}; + m.gridLines.properties.enter.strokeOpacity = {value: config.gridOpacity}; + + // extend axis marks based on axis orientation + axisTicksExtend(orient, m.gridLines, oldScale, newScale, Infinity); + axisTicksExtend(orient, m.majorTicks, oldScale, newScale, tickMajorSize); + axisTicksExtend(orient, m.minorTicks, oldScale, newScale, tickMinorSize); + axisLabelExtend(orient, m.tickLabels, oldScale, newScale, tickMajorSize, tickPadding); + + axisDomainExtend(orient, m.domain, range, tickEndSize); + axisTitleExtend(orient, m.title, range, +titleOffset || -1); + + // add / override custom style properties + dl.extend(m.gridLines.properties.update, gridLineStyle); + dl.extend(m.majorTicks.properties.update, majorTickStyle); + dl.extend(m.minorTicks.properties.update, minorTickStyle); + dl.extend(m.tickLabels.properties.update, tickLabelStyle); + dl.extend(m.domain.properties.update, domainStyle); + dl.extend(m.title.properties.update, titleStyle); + + var marks = [m.gridLines, m.majorTicks, m.minorTicks, m.tickLabels, m.domain, m.title]; + dl.extend(axisDef, { + type: 'group', + interactive: false, + properties: { + enter: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + }, + update: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + } + } + }); + + axisDef.marks = marks.map(function(m) { return parseMark(model, m); }); + } + + axis.scale = function(x) { + if (!arguments.length) return scale; + if (scale !== x) { scale = x; reset(); } + return axis; + }; + + axis.orient = function(x) { + if (!arguments.length) return orient; + if (orient !== x) { + orient = x in axisOrients ? x + '' : config.orient; + reset(); + } + return axis; + }; + + axis.title = function(x) { + if (!arguments.length) return title; + if (title !== x) { title = x; reset(); } + return axis; + }; + + axis.tickCount = function(x) { + if (!arguments.length) return tickCount; + tickCount = x; + return axis; + }; + + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormatString; + if (tickFormatString !== x) { + tickFormatString = x; + reset(); + } + return axis; + }; + + axis.tickFormatType = function(x) { + if (!arguments.length) return tickFormatType; + if (tickFormatType !== x) { + tickFormatType = x; + reset(); + } + return axis; + }; + + axis.tickSize = function(x, y) { + if (!arguments.length) return tickMajorSize; + var n = arguments.length - 1, + major = +x, + minor = n > 1 ? +y : tickMajorSize, + end = n > 0 ? +arguments[n] : tickMajorSize; + + if (tickMajorSize !== major || + tickMinorSize !== minor || + tickEndSize !== end) { + reset(); + } + + tickMajorSize = major; + tickMinorSize = minor; + tickEndSize = end; + return axis; + }; + + axis.tickSubdivide = function(x) { + if (!arguments.length) return tickSubdivide; + tickSubdivide = +x; + return axis; + }; + + axis.offset = function(x) { + if (!arguments.length) return offset; + offset = dl.isObject(x) ? x : +x; + return axis; + }; + + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + if (tickPadding !== +x) { tickPadding = +x; reset(); } + return axis; + }; + + axis.titleOffset = function(x) { + if (!arguments.length) return titleOffset; + if (titleOffset !== x) { titleOffset = x; reset(); } + return axis; + }; + + axis.layer = function(x) { + if (!arguments.length) return layer; + if (layer !== x) { layer = x; reset(); } + return axis; + }; + + axis.grid = function(x) { + if (!arguments.length) return grid; + if (grid !== x) { grid = x; reset(); } + return axis; + }; + + axis.gridLineProperties = function(x) { + if (!arguments.length) return gridLineStyle; + if (gridLineStyle !== x) { gridLineStyle = x; } + return axis; + }; + + axis.majorTickProperties = function(x) { + if (!arguments.length) return majorTickStyle; + if (majorTickStyle !== x) { majorTickStyle = x; } + return axis; + }; + + axis.minorTickProperties = function(x) { + if (!arguments.length) return minorTickStyle; + if (minorTickStyle !== x) { minorTickStyle = x; } + return axis; + }; + + axis.tickLabelProperties = function(x) { + if (!arguments.length) return tickLabelStyle; + if (tickLabelStyle !== x) { tickLabelStyle = x; } + return axis; + }; + + axis.titleProperties = function(x) { + if (!arguments.length) return titleStyle; + if (titleStyle !== x) { titleStyle = x; } + return axis; + }; + + axis.domainProperties = function(x) { + if (!arguments.length) return domainStyle; + if (domainStyle !== x) { domainStyle = x; } + return axis; + }; + + axis.reset = function() { + reset(); + return axis; + }; + + return axis; + } + + var axisOrients = {top: 1, right: 1, bottom: 1, left: 1}; + + function axisSubdivide(scale, ticks, m) { + var subticks = []; + if (m && ticks.length > 1) { + var extent = axisScaleExtent(scale.domain()), + i = -1, + n = ticks.length, + d = (ticks[1] - ticks[0]) / ++m, + j, + v; + while (++i < n) { + for (j = m; --j > 0;) { + if ((v = +ticks[i] - j * d) >= extent[0]) { + subticks.push(v); + } + } + } + for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) { + subticks.push(v); + } + } + return subticks; + } + + function axisScaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start]; + } + + function axisScaleRange(scale) { + return scale.rangeExtent ? + scale.rangeExtent() : + axisScaleExtent(scale.range()); + } + + var axisAlign = { + bottom: 'center', + top: 'center', + left: 'right', + right: 'left' + }; + + var axisBaseline = { + bottom: 'top', + top: 'bottom', + left: 'middle', + right: 'middle' + }; + + function axisLabelExtend(orient, labels, oldScale, newScale, size, pad) { + size = Math.max(size, 0) + pad; + if (orient === 'left' || orient === 'top') { + size *= -1; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(labels.properties.enter, { + x: oldScale, + y: {value: size}, + }); + dl.extend(labels.properties.update, { + x: newScale, + y: {value: size}, + align: {value: 'center'}, + baseline: {value: axisBaseline[orient]} + }); + } else { + dl.extend(labels.properties.enter, { + x: {value: size}, + y: oldScale, + }); + dl.extend(labels.properties.update, { + x: {value: size}, + y: newScale, + align: {value: axisAlign[orient]}, + baseline: {value: 'middle'} + }); + } + } + + function axisTicksExtend(orient, ticks, oldScale, newScale, size) { + var sign = (orient === 'left' || orient === 'top') ? -1 : 1; + if (size === Infinity) { + size = (orient === 'top' || orient === 'bottom') ? + {field: {group: 'height', level: 2}, mult: -sign} : + {field: {group: 'width', level: 2}, mult: -sign}; + } else { + size = {value: sign * size}; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(ticks.properties.enter, { + x: oldScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.update, { + x: newScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.exit, { + x: newScale, + }); + } else { + dl.extend(ticks.properties.enter, { + x: {value: 0}, + x2: size, + y: oldScale + }); + dl.extend(ticks.properties.update, { + x: {value: 0}, + x2: size, + y: newScale + }); + dl.extend(ticks.properties.exit, { + y: newScale, + }); + } + } + + function axisTitleExtend(orient, title, range, offset) { + var update = title.properties.update, + mid = ~~((range[0] + range[1]) / 2), + sign = (orient === 'top' || orient === 'left') ? -1 : 1; + + if (orient === 'bottom' || orient === 'top') { + update.x = {value: mid}; + update.angle = {value: 0}; + if (offset >= 0) update.y = sign * offset; + } else { + update.y = {value: mid}; + update.angle = {value: orient === 'left' ? -90 : 90}; + if (offset >= 0) update.x = sign * offset; + } + } + + function axisDomainExtend(orient, domain, range, size) { + var path; + if (orient === 'top' || orient === 'left') { + size = -1 * size; + } + if (orient === 'bottom' || orient === 'top') { + path = 'M' + range[0] + ',' + size + 'V0H' + range[1] + 'V' + size; + } else { + path = 'M' + size + ',' + range[0] + 'H0V' + range[1] + 'H' + size; + } + domain.properties.update.path = {value: path}; + } + + function axisUpdate(item, group, trans) { + var o = trans ? {} : item, + offset = item.mark.def.offset, + orient = item.mark.def.orient, + width = group.width, + height = group.height; // TODO fallback to global w,h? + + if (dl.isArray(offset)) { + var ofx = offset[0], + ofy = offset[1]; + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -ofx); Tuple.set(o, 'y', ofy); break; } + case 'right': { Tuple.set(o, 'x', width + ofx); Tuple.set(o, 'y', ofy); break; } + case 'bottom': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', height + ofy); break; } + case 'top': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', -ofy); break; } + default: { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', ofy); } + } + } else { + if (dl.isObject(offset)) { + offset = -group.scale(offset.scale)(offset.value); + } + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -offset); Tuple.set(o, 'y', 0); break; } + case 'right': { Tuple.set(o, 'x', width + offset); Tuple.set(o, 'y', 0); break; } + case 'bottom': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', height + offset); break; } + case 'top': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', -offset); break; } + default: { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', 0); } + } + } + + if (trans) trans.interpolate(item, o); + return true; + } + + function axisTicks(config) { + return { + type: 'rule', + interactive: false, + key: 'data', + properties: { + enter: { + stroke: {value: config.tickColor}, + strokeWidth: {value: config.tickWidth}, + opacity: {value: 1e-6} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTickLabels(config) { + return { + type: 'text', + interactive: true, + key: 'data', + properties: { + enter: { + fill: {value: config.tickLabelColor}, + font: {value: config.tickLabelFont}, + fontSize: {value: config.tickLabelFontSize}, + opacity: {value: 1e-6}, + text: {field: 'label'} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTitle(config) { + return { + type: 'text', + interactive: true, + properties: { + enter: { + font: {value: config.titleFont}, + fontSize: {value: config.titleFontSize}, + fontWeight: {value: config.titleFontWeight}, + fill: {value: config.titleColor}, + align: {value: 'center'}, + baseline: {value: 'middle'}, + text: {field: 'data'} + }, + update: {} + } + }; + } + + function axisDomain(config) { + return { + type: 'path', + interactive: false, + properties: { + enter: { + x: {value: 0.5}, + y: {value: 0.5}, + stroke: {value: config.axisColor}, + strokeWidth: {value: config.axisWidth} + }, + update: {} + } + }; + } + + module.exports = axs; +},{"../parse/mark":99,"datalib":26,"vega-dataflow":41,"vega-scenegraph":48}],116:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Gradient = require('vega-scenegraph').Gradient, + parseProperties = require('../parse/properties'), + parseMark = require('../parse/mark'); + + function lgnd(model) { + var size = null, + shape = null, + fill = null, + stroke = null, + spacing = null, + values = null, + format = null, + formatString = null, + config = model.config().legend, + title, + orient = config.orient, + offset = config.offset, + padding = config.padding, + tickArguments = [5], + legendStyle = {}, + symbolStyle = {}, + gradientStyle = {}, + titleStyle = {}, + labelStyle = {}, + m = { // Legend marks as references for updates + titles: {}, + symbols: {}, + labels: {}, + gradient: {} + }; + + var legend = {}, + legendDef = {}; + + function reset() { legendDef.type = null; } + function ingest(d, i) { return {data: d, index: i}; } + + legend.def = function() { + var scale = size || shape || fill || stroke; + + format = !formatString ? null : ((scale.type === 'time') ? + dl.format.time(formatString) : dl.format.number(formatString)); + + if (!legendDef.type) { + legendDef = (scale===fill || scale===stroke) && !discrete(scale.type) ? + quantDef(scale) : ordinalDef(scale); + } + legendDef.orient = orient; + legendDef.offset = offset; + legendDef.padding = padding; + legendDef.margin = config.margin; + return legendDef; + }; + + function discrete(type) { + return type==='ordinal' || type==='quantize' || + type==='quantile' || type==='threshold'; + } + + function ordinalDef(scale) { + var def = o_legend_def(size, shape, fill, stroke); + + // generate data + var data = (values == null ? + (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : + values).map(ingest); + var fmt = format==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : format; + + // determine spacing between legend entries + var fs, range, offset, pad=5, domain = d3.range(data.length); + if (size) { + range = data.map(function(x) { return Math.sqrt(size(x.data)); }); + offset = d3.max(range); + range = range.reduce(function(a,b,i,z) { + if (i > 0) a[i] = a[i-1] + z[i-1]/2 + pad; + return (a[i] += b/2, a); }, [0]).map(Math.round); + } else { + offset = Math.round(Math.sqrt(config.symbolSize)); + range = spacing || + (fs = labelStyle.fontSize) && (fs.value + pad) || + (config.labelFontSize + pad); + range = domain.map(function(d,i) { + return Math.round(offset/2 + i*range); + }); + } + + // account for padding and title size + var sz = padding, ts; + if (title) { + ts = titleStyle.fontSize; + sz += 5 + ((ts && ts.value) || config.titleFontSize); + } + for (var i=0, n=range.length; i'}, + summarize: { + type: 'custom', + set: function(summarize) { + var signalDeps = {}, + tx = this._transform, + i, len, f, fields, name, ops; + + if (!dl.isArray(fields = summarize)) { // Object syntax from dl + fields = []; + for (name in summarize) { + ops = dl.array(summarize[name]); + fields.push({field: name, ops: ops}); + } + } + + function sg(x) { if (x.signal) signalDeps[x.signal] = 1; } + + for (i=0, len=fields.length; i', default: [5, 2]} + }); + + this._output = { + start: 'bin_start', + end: 'bin_end', + mid: 'bin_mid' + }; + return this.mutates(true); + } + + var prototype = (Bin.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Bin; + + prototype.extent = function(data) { + // TODO only recompute extent upon data or field change? + var e = [this.param('min'), this.param('max')], d; + if (e[0] == null || e[1] == null) { + d = dl.extent(data, this.param('field').accessor); + if (e[0] == null) e[0] = d[0]; + if (e[1] == null) e[1] = d[1]; + } + return e; + }; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['binning']); + + var extent = this.extent(data), + output = this._output, + step = this.param('step'), + steps = this.param('steps'), + minstep = this.param('minstep'), + get = this.param('field').accessor, + opt = { + min: extent[0], + max: extent[1], + base: this.param('base'), + maxbins: this.param('maxbins'), + div: this.param('div') + }; + + if (step) opt.step = step; + if (steps) opt.steps = steps; + if (minstep) opt.minstep = minstep; + var b = dl.bins(opt), + s = b.step; + + function update(d) { + var v = get(d); + v = v == null ? null + : b.start + s * ~~((v - b.start) / s); + Tuple.set(d, output.start, v); + Tuple.set(d, output.end, v + s); + Tuple.set(d, output.mid, v + s/2); + } + input.add.forEach(update); + input.mod.forEach(update); + input.rem.forEach(update); + + input.fields[output.start] = 1; + input.fields[output.end] = 1; + input.fields[output.mid] = 1; + return input; + }; + + module.exports = Bin; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],121:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function CountPattern(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + field: {type: 'field', default: 'data'}, + pattern: {type: 'value', default: '[\\w\']+'}, + case: {type: 'value', default: 'lower'}, + stopwords: {type: 'value', default: ''} + }); + + this._output = {text: 'text', count: 'count'}; + + return this.router(true).produces(true); + } + + var prototype = (CountPattern.prototype = Object.create(Transform.prototype)); + prototype.constructor = CountPattern; + + prototype.transform = function(input, reset) { + log.debug(input, ['countpattern']); + + var get = this.param('field').accessor, + pattern = this.param('pattern'), + stop = this.param('stopwords'), + rem = false; + + // update parameters + if (this._stop !== stop) { + this._stop = stop; + this._stop_re = new RegExp('^' + stop + '$', 'i'); + reset = true; + } + + if (this._pattern !== pattern) { + this._pattern = pattern; + this._match = new RegExp(this._pattern, 'g'); + reset = true; + } + + if (reset) this._counts = {}; + + function curr(t) { return (Tuple.prev_init(t), get(t)); } + function prev(t) { return get(Tuple.prev(t)); } + + this._add(input.add, curr); + if (!reset) this._rem(input.rem, prev); + if (reset || (rem = input.fields[get.field])) { + if (rem) this._rem(input.mod, prev); + this._add(input.mod, curr); + } + + // generate output tuples + return this._changeset(input); + }; + + prototype._changeset = function(input) { + var counts = this._counts, + tuples = this._tuples || (this._tuples = {}), + change = df.ChangeSet.create(input), + out = this._output, w, t, c; + + for (w in counts) { + t = tuples[w]; + c = counts[w] || 0; + if (!t && c) { + tuples[w] = (t = Tuple.ingest({})); + t[out.text] = w; + t[out.count] = c; + change.add.push(t); + } else if (c === 0) { + if (t) change.rem.push(t); + delete counts[w]; + delete tuples[w]; + } else if (t[out.count] !== c) { + Tuple.set(t, out.count, c); + change.mod.push(t); + } + } + return change; + }; + + prototype._tokenize = function(text) { + switch (this.param('case')) { + case 'upper': text = text.toUpperCase(); break; + case 'lower': text = text.toLowerCase(); break; + } + return text.match(this._match); + }; + + prototype._add = function(tuples, get) { + var counts = this._counts, + stop = this._stop_re, + tok, i, j, t; + + for (j=0; j cross.s, + fltrd = !cross || cross.f, + omod = output.mod, + orem = output.rem, + i, t, y; + + // If we have cached values, iterate through them for lazy + // removal, and to re-run the filter. + if (tpls) { + if (lazy || test) { + for (i=tpls.length-1; i>=0; --i) { + t = tpls[i]; + y = t[other]; + + if (lazy && !cache[y._id]) { + tpls.splice(i, 1); + continue; + } + + if (!test || test(t)) { + omod.push(t); + } else { + orem.push.apply(orem, tpls.splice(i, 1)); + cross.f = true; + } + } + + cross.s = this._lastRem; + } else { + omod.push.apply(omod, tpls); + } + } + + // If we have a filter param, call add to catch any tuples that may + // have previously been filtered. + if (test && fltrd) add.call(this, output, left, data, diag, test, x); + } + + function rem(output, x) { + var cross = this._cache[x._id]; + if (!cross) return; + output.rem.push.apply(output.rem, cross.c); + this._cache[x._id] = null; + this._lastRem = this._stamp; + } + + function purge(output) { + var cache = this._cache, + keys = dl.keys(cache), + rem = output.rem, + ids = {}, + i, len, j, jlen, cross, t; + + for (i=0, len=keys.length; i this._lastWith) { + woutput.rem.forEach(r); + woutput.add.forEach(add.bind(this, output, false, data, diag, test)); + woutput.mod.forEach(mod.bind(this, output, false, data, diag, test)); + this._lastWith = woutput.stamp; + } + + // Mods need to come after all removals have been run. + input.mod.forEach(mod.bind(this, output, true, wdata, diag, test)); + } + + output.fields[as.left] = 1; + output.fields[as.right] = 1; + return output; + }; + + module.exports = Cross; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],123:[function(require,module,exports){ + var Transform = require('./Transform'), + Aggregate = require('./Aggregate'); + + function Facet(graph) { + Transform.addParameters(this, { + transform: { + type: "custom", + set: function(pipeline) { + return (this._transform._pipeline = pipeline, this._transform); + }, + get: function() { + var parse = require('../parse/transforms'), + facet = this._transform; + return facet._pipeline.map(function(t) { + return parse(facet._graph, t); + }); + } + } + }); + + this._pipeline = []; + return Aggregate.call(this, graph); + } + + var prototype = (Facet.prototype = Object.create(Aggregate.prototype)); + prototype.constructor = Facet; + + prototype.aggr = function() { + return Aggregate.prototype.aggr.call(this).facet(this); + }; + + prototype.transform = function(input, reset) { + var output = Aggregate.prototype.transform.call(this, input, reset); + + // New facet cells should trigger a re-ranking of the dataflow graph. + // This ensures facet datasources are computed before scenegraph nodes. + // We rerank the Facet's first listener, which is the next node in the + // datasource's pipeline. + if (input.add.length) { + this.listeners()[0].rerank(); + } + + return output; + }; + + module.exports = Facet; +},{"../parse/transforms":108,"./Aggregate":118,"./Transform":139}],124:[function(require,module,exports){ + var dl = require('datalib'), + Aggregator = dl.Aggregator, + Base = Aggregator.prototype, + df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + facetID = 0; + + function Facetor() { + Aggregator.call(this); + this._facet = null; + this._facetID = ++facetID; + } + + var prototype = (Facetor.prototype = Object.create(Base)); + prototype.constructor = Facetor; + + prototype.facet = function(f) { + return arguments.length ? (this._facet = f, this) : this._facet; + }; + + prototype._ingest = function(t) { + return Tuple.ingest(t, null); + }; + + prototype._assign = Tuple.set; + + function disconnect_cell(facet) { + log.debug({}, ['disconnecting cell', this.tuple._id]); + var pipeline = this.ds.pipeline(); + facet.removeListener(pipeline[0]); + facet._graph.removeListener(pipeline[0]); + facet._graph.disconnect(pipeline); + } + + prototype._newcell = function(x, key) { + var cell = Base._newcell.call(this, x, key), + facet = this._facet; + + if (facet) { + var graph = facet._graph, + tuple = cell.tuple, + pipeline = facet.param('transform'); + cell.ds = graph.data(tuple._facetID, pipeline, tuple); + cell.disconnect = disconnect_cell; + facet.addListener(pipeline[0]); + } + + return cell; + }; + + prototype._newtuple = function(x, key) { + var t = Base._newtuple.call(this, x); + if (this._facet) { + Tuple.set(t, 'key', key); + Tuple.set(t, '_facetID', this._facetID + '_' + key); + } + return t; + }; + + prototype.clear = function() { + if (this._facet) { + for (var k in this._cells) { + this._cells[k].disconnect(this._facet); + } + } + return Base.clear.call(this); + }; + + prototype._on_add = function(x, cell) { + if (this._facet) cell.ds._input.add.push(x); + }; + + prototype._on_rem = function(x, cell) { + if (this._facet) cell.ds._input.rem.push(x); + }; + + prototype._on_mod = function(x, prev, cell0, cell1) { + if (this._facet) { // Propagate tuples + if (cell0 === cell1) { + cell0.ds._input.mod.push(x); + } else { + cell0.ds._input.rem.push(x); + cell1.ds._input.add.push(x); + } + } + }; + + prototype._on_drop = function(cell) { + if (this._facet) cell.disconnect(this._facet); + }; + + prototype._on_keep = function(cell) { + // propagate sort, signals, fields, etc. + if (this._facet) df.ChangeSet.copy(this._input, cell.ds._input); + }; + + module.exports = Facetor; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],125:[function(require,module,exports){ + var df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Filter(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, {test: {type: 'expr'}}); + + this._skip = {}; + return this.router(true); + } + + var prototype = (Filter.prototype = Object.create(Transform.prototype)); + prototype.constructor = Filter; + + prototype.transform = function(input) { + log.debug(input, ['filtering']); + + var output = df.ChangeSet.create(input), + graph = this._graph, + skip = this._skip, + test = this.param('test'), + signals = graph.values(SIGNALS, this.dependency(SIGNALS)); + + input.rem.forEach(function(x) { + if (skip[x._id] !== 1) output.rem.push(x); + else skip[x._id] = 0; + }); + + input.add.forEach(function(x) { + if (test(x, null, signals)) output.add.push(x); + else skip[x._id] = 1; + }); + + input.mod.forEach(function(x) { + var b = test(x, null, signals), + s = (skip[x._id] === 1); + if (b && s) { + skip[x._id] = 0; + output.add.push(x); + } else if (b && !s) { + output.mod.push(x); + } else if (!b && s) { + // do nothing, keep skip true + } else { // !b && !s + output.rem.push(x); + skip[x._id] = 1; + } + }); + + return output; + }; + + module.exports = Filter; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],126:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Fold(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + fields: {type: 'array'} + }); + + this._output = {key: 'key', value: 'value'}; + this._cache = {}; + + return this.router(true).produces(true); + } + + var prototype = (Fold.prototype = Object.create(Transform.prototype)); + prototype.constructor = Fold; + + prototype._reset = function(input, output) { + for (var id in this._cache) { + output.rem.push.apply(output.rem, this._cache[id]); + } + this._cache = {}; + }; + + prototype._tuple = function(x, i, len) { + var list = this._cache[x._id] || (this._cache[x._id] = Array(len)); + return list[i] ? Tuple.rederive(x, list[i]) : (list[i] = Tuple.derive(x)); + }; + + prototype._fn = function(data, on, out) { + var i, j, n, m, d, t; + for (i=0, n=data.length; i', default: require('./screen').size}, + bound: {type: 'value', default: true}, + links: {type: 'data'}, + + // TODO: for now force these to be value params only (pun-intended) + // Can update to include fields after Parameter refactoring. + linkStrength: {type: 'value', default: 1}, + linkDistance: {type: 'value', default: 20}, + charge: {type: 'value', default: -30}, + + chargeDistance: {type: 'value', default: Infinity}, + friction: {type: 'value', default: 0.9}, + theta: {type: 'value', default: 0.8}, + gravity: {type: 'value', default: 0.1}, + alpha: {type: 'value', default: 0.1}, + iterations: {type: 'value', default: 500}, + + interactive: {type: 'value', default: this._interactive}, + active: {type: 'value', default: this._prev}, + fixed: {type: 'data'} + }); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y' + }; + + return this.mutates(true); + } + + var prototype = (Force.prototype = Object.create(Transform.prototype)); + prototype.constructor = Force; + + prototype.transform = function(nodeInput, reset) { + log.debug(nodeInput, ['force']); + reset = reset - (nodeInput.signals.active ? 1 : 0); + + // get variables + var interactive = this.param('interactive'), + linkSource = this.param('links').source, + linkInput = linkSource.last(), + active = this.param('active'), + output = this._output, + layout = this._layout, + nodes = this._nodes, + links = this._links; + + // configure nodes, links and layout + if (linkInput.stamp < nodeInput.stamp) linkInput = null; + this.configure(nodeInput, linkInput, interactive, reset); + + // run batch layout + if (!interactive) { + var iterations = this.param('iterations'); + for (var i=0; i'}, + translate: {type: 'array', default: require('./screen').center}, + rotate: {type: 'array'}, + scale: {type: 'value'}, + precision: {type: 'value'}, + clipAngle: {type: 'value'}, + clipExtent: {type: 'value'} + }; + + Geo.d3Projection = function() { + var p = this.param('projection'), + param = Geo.Parameters, + proj, name, value; + + if (p !== this._mode) { + this._mode = p; + this._projection = d3.geo[p](); + } + proj = this._projection; + + for (name in param) { + if (name === 'projection' || !proj[name]) continue; + value = this.param(name); + if (value === undefined || (dl.isArray(value) && value.length === 0)) { + continue; + } + if (value !== proj[name]()) { + proj[name](value); + } + } + + return proj; + }; + + var prototype = (Geo.prototype = Object.create(Transform.prototype)); + prototype.constructor = Geo; + + prototype.transform = function(input) { + log.debug(input, ['geo']); + + var output = this._output, + lon = this.param('lon').accessor, + lat = this.param('lat').accessor, + proj = Geo.d3Projection.call(this); + + function set(t) { + var ll = [lon(t), lat(t)]; + var xy = proj(ll) || [null, null]; + Tuple.set(t, output.x, xy[0]); + Tuple.set(t, output.y, xy[1]); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + return input; + }; + + module.exports = Geo; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],130:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Geo = require('./Geo'), + Transform = require('./Transform'); + + function GeoPath(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, Geo.Parameters); + Transform.addParameters(this, { + field: {type: 'field', default: null}, + }); + + this._output = { + 'path': 'layout_path' + }; + return this.mutates(true); + } + + var prototype = (GeoPath.prototype = Object.create(Transform.prototype)); + prototype.constructor = GeoPath; + + prototype.transform = function(input) { + log.debug(input, ['geopath']); + + var output = this._output, + geojson = this.param('field').accessor || dl.identity, + proj = Geo.d3Projection.call(this), + path = d3.geo.path().projection(proj); + + function set(t) { + Tuple.set(t, output.path, path(geojson(t))); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = GeoPath; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Geo":129,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],131:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Hierarchy(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + // hierarchy parameters + sort: {type: 'array', default: null}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'value', default: null}, + // layout parameters + mode: {type: 'value', default: 'tidy'}, // tidy, cluster, partition + size: {type: 'array', default: require('./screen').size}, + nodesize: {type: 'array', default: null}, + orient: {type: 'value', default: 'cartesian'} + }); + + this._mode = null; + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth' + }; + return this.mutates(true); + } + + var PARTITION = 'partition'; + + var SEPARATION = { + cartesian: function(a, b) { return (a.parent === b.parent ? 1 : 2); }, + radial: function(a, b) { return (a.parent === b.parent ? 1 : 2) / a.depth; } + }; + + var prototype = (Hierarchy.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Hierarchy; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['hierarchy layout']); + + // get variables + var layout = this._layout, + output = this._output, + mode = this.param('mode'), + sort = this.param('sort'), + nodesz = this.param('nodesize'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + if (mode !== this._mode) { + this._mode = mode; + if (mode === 'tidy') mode = 'tree'; + layout = (this._layout = d3.layout[mode]()); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.depth] = 1; + if (mode === PARTITION) { + input.fields[output.width] = 1; + input.fields[output.height] = 1; + layout.value(this.param('field').accessor); + } else { + layout.separation(SEPARATION[this.param('orient')]); + } + + if (nodesz.length && mode !== PARTITION) { + layout.nodeSize(nodesz); + } else { + layout.size(this.param('size')); + } + + layout + .sort(sort.field.length ? dl.comparator(sort.field) : null) + .children(this.param('children').accessor) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.depth, n.depth); + if (mode === PARTITION) { + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + } + }); + + // return changeset + return input; + }; + + module.exports = Hierarchy; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],132:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple, + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Impute(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + orderby: {type: 'array'}, + field: {type: 'field'}, + method: {type: 'value', default: 'value'}, + value: {type: 'value', default: 0} + }); + + return this.router(true).produces(true); + } + + var prototype = (Impute.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Impute; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['imputing']); + + var groupby = this.param('groupby'), + orderby = this.param('orderby'), + method = this.param('method'), + value = this.param('value'), + field = this.param('field'), + get = field.accessor, + name = field.field, + prev = this._imputed || [], curr = [], + groups = partition(data, groupby.accessor, orderby.accessor), + domain = groups.domain, + group, i, j, n, m, t; + + function getval(x) { + return x == null ? null : get(x); + } + + for (j=0, m=groups.length; j Math.PI ? ta <= sa : ta > sa; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'A' + sr + ',' + sr + ' 0 0,' + (sf?1:0) + + ' ' + (sr*tc) + ',' + (sr*ts) + + 'L' + (tr*tc) + ',' + (tr*ts); + } + + function diagonalX(sx, sy, tx, ty) { + var m = (sx + tx) / 2; + return 'M' + sx + ',' + sy + + 'C' + m + ',' + sy + + ' ' + m + ',' + ty + + ' ' + tx + ',' + ty; + } + + function diagonalY(sx, sy, tx, ty) { + var m = (sy + ty) / 2; + return 'M' + sx + ',' + sy + + 'C' + sx + ',' + m + + ' ' + tx + ',' + m + + ' ' + tx + ',' + ty; + } + + function diagonalR(sa, sr, ta, tr) { + var sc = Math.cos(sa), + ss = Math.sin(sa), + tc = Math.cos(ta), + ts = Math.sin(ta), + mr = (sr + tr) / 2; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'C' + (mr*sc) + ',' + (mr*ss) + + ' ' + (mr*tc) + ',' + (mr*ts) + + ' ' + (tr*tc) + ',' + (tr*ts); + } + + var shapes = { + line: line, + curve: curve, + cornerX: cornerX, + cornerY: cornerY, + cornerR: cornerR, + diagonalX: diagonalX, + diagonalY: diagonalY, + diagonalR: diagonalR + }; + + prototype.transform = function(input) { + log.debug(input, ['linkpath']); + + var output = this._output, + shape = shapes[this.param('shape')] || shapes.line, + sourceX = this.param('sourceX').accessor, + sourceY = this.param('sourceY').accessor, + targetX = this.param('targetX').accessor, + targetY = this.param('targetY').accessor, + tension = this.param('tension'); + + function set(t) { + var path = shape(sourceX(t), sourceY(t), targetX(t), targetY(t), tension); + Tuple.set(t, output.path, path); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = LinkPath; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],134:[function(require,module,exports){ + var Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Lookup(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + on: {type: 'data'}, + onKey: {type: 'field', default: null}, + as: {type: 'array'}, + keys: {type: 'array', default: ['data']}, + default: {type: 'value'} + }); + + return this.mutates(true); + } + + var prototype = (Lookup.prototype = Object.create(Transform.prototype)); + prototype.constructor = Lookup; + + prototype.transform = function(input, reset) { + log.debug(input, ['lookup']); + + var on = this.param('on'), + onLast = on.source.last(), + onData = on.source.values(), + onKey = this.param('onKey'), + onF = onKey.field, + keys = this.param('keys'), + get = keys.accessor, + as = this.param('as'), + defaultValue = this.param('default'), + lut = this._lut, + i, v; + + // build lookup table on init, withKey modified, or tuple add/rem + if (lut == null || this._on !== onF || onF && onLast.fields[onF] || + onLast.add.length || onLast.rem.length) + { + if (onF) { // build hash from withKey field + onKey = onKey.accessor; + for (lut={}, i=0; i'} }); + this.router(true); + } + + var prototype = (Sort.prototype = Object.create(Transform.prototype)); + prototype.constructor = Sort; + + prototype.transform = function(input) { + log.debug(input, ['sorting']); + + if (input.add.length || input.mod.length || input.rem.length) { + input.sort = dl.comparator(this.param('by').field); + } + return input; + }; + + module.exports = Sort; +},{"./Transform":139,"datalib":26,"vega-logging":47}],138:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Stack(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + sortby: {type: 'array'}, + field: {type: 'field'}, + offset: {type: 'value', default: 'zero'} + }); + + this._output = { + 'start': 'layout_start', + 'end': 'layout_end', + 'mid': 'layout_mid' + }; + return this.mutates(true); + } + + var prototype = (Stack.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Stack; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['stacking']); + + var groupby = this.param('groupby').accessor, + sortby = dl.comparator(this.param('sortby').field), + field = this.param('field').accessor, + offset = this.param('offset'), + output = this._output; + + // partition, sum, and sort the stack groups + var groups = partition(data, groupby, sortby, field); + + // compute stack layouts per group + for (var i=0, max=groups.max; i max) max = s; + if (sortby != null) g.sort(sortby); + } + groups.max = max; + + return groups; + } + + module.exports = Stack; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],139:[function(require,module,exports){ + var df = require('vega-dataflow'), + Base = df.Node.prototype, // jshint ignore:line + Deps = df.Dependencies, + Parameter = require('./Parameter'); + + function Transform(graph) { + if (graph) Base.init.call(this, graph); + } + + Transform.addParameters = function(proto, params) { + proto._parameters = proto._parameters || {}; + for (var name in params) { + var p = params[name], + param = new Parameter(name, p.type, proto); + + proto._parameters[name] = param; + + if (p.type === 'custom') { + if (p.set) param.set = p.set.bind(param); + if (p.get) param.get = p.get.bind(param); + } + + if (p.hasOwnProperty('default')) param.set(p.default); + } + }; + + var prototype = (Transform.prototype = Object.create(Base)); + prototype.constructor = Transform; + + prototype.param = function(name, value) { + var param = this._parameters[name]; + return (param === undefined) ? this : + (arguments.length === 1) ? param.get() : param.set(value); + }; + +// Perform transformation. Subclasses should override. + prototype.transform = function(input/*, reset */) { + return input; + }; + + prototype.evaluate = function(input) { + // Many transforms store caches that must be invalidated if + // a signal value has changed. + var reset = this._stamp < input.stamp && + this.dependency(Deps.SIGNALS).reduce(function(c, s) { + return c += input.signals[s] ? 1 : 0; + }, 0); + return this.transform(input, reset); + }; + + prototype.output = function(map) { + for (var key in this._output) { + if (map[key] !== undefined) { + this._output[key] = map[key]; + } + } + return this; + }; + + module.exports = Transform; +},{"./Parameter":135,"vega-dataflow":41}],140:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Treeify(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'} + }); + + this._output = { + 'children': 'children', + 'parent': 'parent' + }; + return this.router(true).produces(true); + } + + var prototype = (Treeify.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treeify; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treeifying']); + + var fields = this.param('groupby').field, + childField = this._output.children, + parentField = this._output.parent, + summary = [{name:'*', ops: ['values'], as: [childField]}], + aggrs = fields.map(function(f) { + return dl.groupby(f).summarize(summary); + }), + prev = this._internal || [], curr = [], i, n; + + function level(index, node, values) { + var vals = aggrs[index].execute(values); + + node[childField] = vals; + vals.forEach(function(n) { + n[parentField] = node; + curr.push(Tuple.ingest(n)); + if (index+1 < fields.length) level(index+1, n, n[childField]); + else n[childField].forEach(function(c) { c[parentField] = n; }); + }); + } + + var root = Tuple.ingest({}); + root[parentField] = null; + curr.push(root); + level(0, root, data); + + // update changeset with internal nodes + for (i=0, n=curr.length; i', default: ['-value']}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'field', default: 'value'}, + // treemap parameters + size: {type: 'array', default: require('./screen').size}, + round: {type: 'value', default: true}, + sticky: {type: 'value', default: false}, + ratio: {type: 'value', default: defaultRatio}, + padding: {type: 'value', default: null}, + mode: {type: 'value', default: 'squarify'} + }); + + this._layout = d3.layout.treemap(); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth', + }; + return this.mutates(true); + } + + var prototype = (Treemap.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treemap; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treemap']); + + // get variables + var layout = this._layout, + output = this._output, + sticky = this.param('sticky'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + // layout.sticky resets state _regardless_ of input value + // so, we perform out own check first + if (layout.sticky() !== sticky) { layout.sticky(sticky); } + + // configure layout + layout + .sort(dl.comparator(this.param('sort').field)) + .children(this.param('children').accessor) + .value(this.param('field').accessor) + .size(this.param('size')) + .round(this.param('round')) + .ratio(this.param('ratio')) + .padding(this.param('padding')) + .mode(this.param('mode')) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + Tuple.set(n, output.depth, n.depth); + }); + + // return changeset + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.width] = 1; + input.fields[output.height] = 1; + input.fields[output.depth] = 1; + return input; + }; + + module.exports = Treemap; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],142:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + Tuple = require('vega-dataflow/src/Tuple'), + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Voronoi(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + clipExtent: {type: 'array', default: require('./screen').extent}, + x: {type: 'field', default: 'layout_x'}, + y: {type: 'field', default: 'layout_y'} + }); + + this._layout = d3.geom.voronoi(); + this._output = {'path': 'layout_path'}; + + return this.mutates(true); + } + + var prototype = (Voronoi.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Voronoi; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['voronoi']); + + // get variables + var pathname = this._output.path; + + // configure layout + var polygons = this._layout + .clipExtent(this.param('clipExtent')) + .x(this.param('x').accessor) + .y(this.param('y').accessor) + (data); + + // build and assign path strings + for (var i=0; i', default: require('./screen').size}, + text: {type: 'field', default: 'data'}, + rotate: {type: 'field|value', default: 0}, + font: {type: 'field|value', default: {value: 'sans-serif'}}, + fontSize: {type: 'field|value', default: 14}, + fontStyle: {type: 'field|value', default: {value: 'normal'}}, + fontWeight: {type: 'field|value', default: {value: 'normal'}}, + fontScale: {type: 'array', default: [10, 50]}, + padding: {type: 'value', default: 1}, + spiral: {type: 'value', default: 'archimedean'} + }); + + this._layout = d3_cloud().canvas(canvas.instance); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'font': 'layout_font', + 'fontSize': 'layout_fontSize', + 'fontStyle': 'layout_fontStyle', + 'fontWeight': 'layout_fontWeight', + 'rotate': 'layout_rotate', + }; + + return this.mutates(true); + } + + var prototype = (Wordcloud.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Wordcloud; + + function get(p) { + return (p && p.accessor) || p; + } + + function wrap(tuple) { + var x = Object.create(tuple); + x._tuple = tuple; + return x; + } + + prototype.batchTransform = function(input, data) { + log.debug(input, ['wordcloud']); + + // get variables + var layout = this._layout, + output = this._output, + fontSize = this.param('fontSize'), + range = fontSize.accessor && this.param('fontScale'), + size, scale; + fontSize = fontSize.accessor || d3.functor(fontSize); + + // create font size scaling function as needed + if (range.length) { + scale = d3.scale.sqrt() + .domain(dl.extent(data, size=fontSize)) + .range(range); + fontSize = function(x) { return scale(size(x)); }; + } + + // configure layout + layout + .size(this.param('size')) + .text(get(this.param('text'))) + .padding(this.param('padding')) + .spiral(this.param('spiral')) + .rotate(get(this.param('rotate'))) + .font(get(this.param('font'))) + .fontStyle(get(this.param('fontStyle'))) + .fontWeight(get(this.param('fontWeight'))) + .fontSize(fontSize) + .words(data.map(wrap)) // wrap to avoid tuple writes + .on('end', function(words) { + var size = layout.size(), + dx = size[0] >> 1, + dy = size[1] >> 1, + w, t, i, len; + + for (i=0, len=words.length; i - org.wso2.carbon.event-processing:org.wso2.carbon.event.processor.feature:${carbon.event-processing.version} + org.wso2.carbon.event-processing:org.wso2.carbon.event.processor.server.feature:${carbon.event-processing.version} org.wso2.carbon.analytics-common:org.wso2.carbon.event.tracer.feature:${carbon.analytics.common.version} @@ -1617,7 +1617,7 @@ ${carbon.analytics.common.version} - org.wso2.carbon.event.processor.feature.group + org.wso2.carbon.event.processor.server.feature.group ${carbon.event-processing.version} diff --git a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java index 2924a442..eb51bf19 100644 --- a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java +++ b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java @@ -147,11 +147,13 @@ public class DoorManagerControllerService { @FormParam("policy") String policy, @FormParam("cardNumber") String cardNumber, @FormParam("userName") String userName, + @FormParam("emailAddress") String emailAddress, @Context HttpServletResponse response) { try { if (userName != null && cardNumber != null && deviceId != null) { try { UserStoreManager userStoreManager = this.getUserStoreManager(); + DoorLockSafe doorLockSafe = new DoorLockSafe(); if (userStoreManager.isExistingUser(userName)) { TokenClient accessTokenClient = new TokenClient(DoorManagerConstants.DEVICE_TYPE); AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(deviceId, userName); @@ -165,7 +167,35 @@ public class DoorManagerControllerService { claims.put("http://wso2.org/claims/lock/refreshtoken", accessTokenInfo.getRefresh_token()); claims.put("http://wso2.org/claims/lock/cardnumber", cardNumber); userStoreManager.setUserClaimValues(userName, claims, null); - //TODO: Add content to dto + doorLockSafe.setAccessToken(accessTokenInfo.getAccess_token()); + doorLockSafe.setRefreshToken(accessTokenInfo.getRefresh_token()); + doorLockSafe.setDeviceId(deviceId); + doorLockSafe.setOwner(owner); + doorLockSafe.setEmailAddress(emailAddress); + doorLockSafe.setUIDofUser(cardNumber); + doorLockSafe.setPolicy(policy); + doorLockSafe.setSerialNumber(deviceId); + boolean status; + try { + DoorManagerDAO.beginTransaction(); + status = DOOR_MANAGER_DAO.getAutomaticDoorLockerDeviceDAO().registerDoorLockSafe(doorLockSafe); + DoorManagerDAO.commitTransaction(); + if (status) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.FORBIDDEN.getStatusCode()); + } + } catch (DoorManagerDeviceMgtPluginException e) { + try { + DoorManagerDAO.rollbackTransaction(); + } catch (DoorManagerDeviceMgtPluginException e1) { + String msg = "Error while updating the enrollment of the Door Manager Locker device : " + + doorLockSafe.getOwner(); + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.error(msg, e); + } + } + response.setStatus(Response.Status.OK.getStatusCode()); } else { response.setStatus(Response.Status.NOT_FOUND.getStatusCode()); @@ -184,7 +214,7 @@ public class DoorManagerControllerService { } } - @Path("controller/registerNewUser") + /* @Path("controller/registerNewUser") @POST @Feature(code = "registerNewUser", name = "Assign to new user", type = "operation", description = "Assign to new user") @@ -241,7 +271,7 @@ public class DoorManagerControllerService { response.setStatus(Response.Status.BAD_REQUEST.getStatusCode()); log.error(e); } - } + }*/ /*@Path("controller/registerNewUser") @POST diff --git a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java index fd1919a2..bf61fdb8 100644 --- a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java +++ b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java @@ -12,6 +12,7 @@ import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; +import javax.ws.rs.core.Response; import java.io.File; import java.util.Calendar; import java.util.UUID; @@ -80,12 +81,16 @@ public class DoorManagerMQTTConnector extends MQTTTransportHandler { } if (messageData.length == 2) { log.warn("-------------------------------------------"); - log.warn(messageData[2]); + log.warn(messageData[0]); log.warn(messageData[1]); String lockerCurrentState = messageData[1]; try { SensorDataManager.getInstance().setSensorRecord(deviceId, "door_locker_state", String.valueOf(1), Calendar.getInstance().getTimeInMillis()); + if (!DoorManagerServiceUtils.publishToDASCurrent(owner, deviceId, 1)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + owner + "]"); + } } catch(Exception e){ log.error(e); } @@ -110,6 +115,21 @@ public class DoorManagerMQTTConnector extends MQTTTransportHandler { String payload = operation + param; try { publishToAutomaticDoorLocker(topic, payload, 2, false); + if(param.equals("LOCK")){ + if (!DoorManagerServiceUtils.publishToDASCurrent(deviceOwner, deviceId, 0)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + deviceOwner + "]"); + } + }else{ + if (!DoorManagerServiceUtils.publishToDASCurrent(deviceOwner, deviceId, 1)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + deviceOwner + "]"); + } + } + if (!DoorManagerServiceUtils.publishToDASCurrent(deviceOwner, deviceId, 1)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + deviceOwner + "]"); + } } catch (TransportHandlerException e) { String errorMessage = "Error publishing data to device with ID " + deviceId; throw new DoorManagerException(errorMessage, e); diff --git a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java new file mode 100644 index 00000000..7775005a --- /dev/null +++ b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.doormanager.controller.api.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.doormanager.plugin.constants.DoorManagerConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService; + +public class DoorManagerServiceUtils { + private static final Log log = LogFactory.getLog(DoorManagerServiceUtils.class); + + //TODO; replace this tenant domain + private static final String SUPER_TENANT = "carbon.super"; + private static final String CURRENT_STREAM_DEFINITION = "org.wso2.iot.devices.sensor"; + + public static boolean publishToDASCurrent(String owner, String deviceId, float current) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setTenantDomain(SUPER_TENANT, true); + DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService( + DeviceAnalyticsService.class, null); + Object metdaData[] = {owner, DoorManagerConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()}; + Object payloadCurrent[] = {current}; + + try { + deviceAnalyticsService.publishEvent(CURRENT_STREAM_DEFINITION, "1.0.0", metdaData, new Object[0], payloadCurrent); + } catch (DataPublisherConfigurationException e) { + return false; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return true; + } + +} diff --git a/modules/samples/doormanager/component/manager/pom.xml b/modules/samples/doormanager/component/manager/pom.xml index 3efeb0df..130acacd 100644 --- a/modules/samples/doormanager/component/manager/pom.xml +++ b/modules/samples/doormanager/component/manager/pom.xml @@ -228,5 +228,10 @@ json-simple 1.1.wso2v1 + + com.google.code.gson + gson + 2.2.4 + \ No newline at end of file diff --git a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java index 359b035b..a6183dc3 100644 --- a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java +++ b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java @@ -18,9 +18,16 @@ package org.homeautomation.doormanager.manager.api; +import com.google.gson.JsonObject; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.mail.util.Base64; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.SystemDefaultHttpClient; import org.homeautomation.doormanager.manager.api.dto.UserInfo; import org.homeautomation.doormanager.plugin.constants.DoorManagerConstants; import org.homeautomation.doormanager.plugin.exception.DoorManagerDeviceMgtPluginException; @@ -54,6 +61,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.*; @@ -265,18 +273,22 @@ public class DoorManagerManagerService { log.warn(userInfo.userName); log.warn(userInfo.cardNumber); log.warn(userInfo.deviceId); - response.addHeader("REMOTE_USER", "ppppppppppppppppppppp"); - //response.addDateHeader("Authentication","55555555555555555555"); if (userInfo.userName != null && userInfo.cardNumber != null && userInfo.deviceId != null) { try { UserStoreManager userStoreManager = this.getUserStoreManager(); if (userStoreManager.isExistingUser(userInfo.userName)) { String accessToken = userStoreManager.getUserClaimValue(userInfo.userName, "http://wso2.org/claims/lock/accesstoken", null); String cardNumber = userStoreManager.getUserClaimValue(userInfo.userName, "http://wso2.org/claims/lock/cardnumber", null); + log.warn(accessToken); + log.warn(cardNumber); if(cardNumber.equals(userInfo.cardNumber)){ - if(accessToken != null){ + if(accessToken != null && doorManagerDAO.getAutomaticDoorLockerDeviceDAO(). + checkCardDoorAssociation(cardNumber, userInfo.deviceId)){ JSONObject credentials = new JSONObject(); credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); + credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); + sendCEPEvent(userInfo.deviceId, cardNumber, true); + log.warn(doorManagerDAO.getAutomaticDoorLockerDeviceDAO().getUserEmailAddress(cardNumber)); return Response.ok(credentials, MediaType.APPLICATION_JSON_TYPE).build(); } } @@ -299,6 +311,39 @@ public class DoorManagerManagerService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } + private void sendCEPEvent(String deviceId, String cardId, boolean accessStatus){ + String cepEventReciever = "http://localhost:9768/endpoints/LockEventReciever"; + + HttpClient httpClient = new SystemDefaultHttpClient(); + HttpPost method = new HttpPost(cepEventReciever); + JsonObject event = new JsonObject(); + JsonObject metaData = new JsonObject(); + + metaData.addProperty("deviceID", deviceId); + metaData.addProperty("cardID", cardId); + + event.add("metaData", metaData); + + String eventString = "{\"event\": " + event + "}"; + + try { + StringEntity entity = new StringEntity(eventString); + method.setEntity(entity); + if (cepEventReciever.startsWith("https")) { + method.setHeader("Authorization", "Basic " + Base64.encode(("admin" + ":" + "admin").getBytes())); + } + httpClient.execute(method).getEntity().getContent().close(); + } catch (UnsupportedEncodingException e) { + log.error("Error while constituting CEP event"+ e.getMessage()); + } catch (ClientProtocolException e) { + log.error("Error while sending message to CEP "+ e.getMessage()); + } catch (IOException e) { + log.error("Error while sending message to CEP "+ e.getMessage()); + } + + + } + @POST @Path("manager/get_user_info") @Produces(MediaType.APPLICATION_JSON) diff --git a/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java b/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java index 7876773b..56d5affa 100644 --- a/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java +++ b/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java @@ -261,6 +261,56 @@ public class DoorManagerDAOImpl { return status; } + public boolean checkCardDoorAssociation(String cardNum, String deviceID) throws DoorManagerDeviceMgtPluginException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + try { + conn = DoorManagerDAO.getConnection(); + String selectDBQuery = "SELECT * FROM REGISTERED_DOORLOCK_SAFE WHERE UID_of_USER = ? AND doormanager_DEVICE_ID = ?"; + stmt = conn.prepareStatement(selectDBQuery); + stmt.setString(1, cardNum); + stmt.setString(2, deviceID); + resultSet = stmt.executeQuery(); + String result; + if(resultSet.next()){ + return true; + }else{ + return false; + } + } catch (SQLException e) { + String msg = "No associations were found between lock : "+ deviceID +" and card : "+ cardNum; + throw new DoorManagerDeviceMgtPluginException(msg, e); + } finally { + DoorManagerUtils.cleanupResources(stmt, null); + } + } + + + public String getUserEmailAddress(String cardNum) throws DoorManagerDeviceMgtPluginException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + String email; + try { + conn = DoorManagerDAO.getConnection(); + String selectDBQuery = "SELECT EMAIL_ADDRESS FROM REGISTERED_DOORLOCK_SAFE WHERE UID_of_USER = ?"; + stmt = conn.prepareStatement(selectDBQuery); + stmt.setString(1, cardNum); + resultSet = stmt.executeQuery(); + if(resultSet.next()){ + email = resultSet.getString("EMAIL_ADDRESS"); + log.warn(email); + return email; + } + return null; + } catch (SQLException e) { + String msg = "No email found for the and card : "+ cardNum; + throw new DoorManagerDeviceMgtPluginException(msg, e); + } finally { + DoorManagerUtils.cleanupResources(stmt, null); + } + } public List getUserCredentials(String deviceId, String UIDofUser) throws DoorManagerDeviceMgtPluginException { Connection conn = null; diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs index 7506942d..4fc403d6 100644 --- a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs +++ b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs @@ -25,7 +25,7 @@ {{/zone}} {{#zone "device-thumbnail"}} - + {{/zone}} {{#zone "operation-status"}} diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png index fe706514..a44f50fc 100644 Binary files a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png and b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png differ diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/thumb.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/thumb.png index 510859d8..a44f50fc 100644 Binary files a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/thumb.png and b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/thumb.png differ diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png new file mode 100644 index 00000000..0c7744ff Binary files /dev/null and b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png differ diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png index ee5152dc..dc5f9a7d 100644 Binary files a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png and b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png differ diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/thumb.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/thumb.png index b74b20f9..a44f50fc 100644 Binary files a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/thumb.png and b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/thumb.png differ diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs index 16c36759..cab924e0 100644 --- a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs +++ b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs @@ -4,7 +4,7 @@
- +
diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/carbonapps/Sensor.car b/modules/samples/doormanager/feature/feature/src/main/resources/carbonapps/Sensor.car new file mode 100644 index 00000000..af22e266 Binary files /dev/null and b/modules/samples/doormanager/feature/feature/src/main/resources/carbonapps/Sensor.car differ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/database/doormanagerDM_DB.h2.db b/modules/samples/doormanager/feature/feature/src/main/resources/database/doormanagerDM_DB.h2.db new file mode 100644 index 00000000..6be5a907 Binary files /dev/null and b/modules/samples/doormanager/feature/feature/src/main/resources/database/doormanagerDM_DB.h2.db differ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doorManager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doorManager-icon.png new file mode 100644 index 00000000..a44f50fc Binary files /dev/null and b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doorManager-icon.png differ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png index fe706514..a44f50fc 100644 Binary files a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png and b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png differ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doorManager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doorManager-icon.png index 0c7744ff..a44f50fc 100644 Binary files a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doorManager-icon.png and b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doorManager-icon.png differ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png new file mode 100644 index 00000000..a44f50fc Binary files /dev/null and b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png differ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png index ee5152dc..dc5f9a7d 100644 Binary files a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png and b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png differ diff --git a/modules/samples/doormanager/pom.xml b/modules/samples/doormanager/pom.xml index 506af0cf..d3f1f1fd 100644 --- a/modules/samples/doormanager/pom.xml +++ b/modules/samples/doormanager/pom.xml @@ -140,6 +140,11 @@ 4.1 provided + + com.google.code.gson + gson + 2.2.4 + @@ -254,4 +259,4 @@ 1.8 1.7.2 - \ No newline at end of file + diff --git a/modules/samples/firealarm/component/analytics/build.xml b/modules/samples/firealarm/component/analytics/build.xml new file mode 100644 index 00000000..2f3be332 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/build.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/analytics/pom.xml b/modules/samples/firealarm/component/analytics/pom.xml new file mode 100644 index 00000000..d587c1ae --- /dev/null +++ b/modules/samples/firealarm/component/analytics/pom.xml @@ -0,0 +1,90 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.analytics + 1.0.0-SNAPSHOT + pom + ${groupId}.firealarm.analytics + http://wso2.org + + + + maven-clean-plugin + ${maven-clean-plugin.version} + + + auto-clean + initialize + + clean + + + + + + maven-antrun-plugin + ${wso2.maven.compiler.source} + + + process-resources + + + + + + + run + + + + + + maven-assembly-plugin + ${maven-assembly-plugin.version} + + ${project.artifactId}-1.0.0-SNAPSHOT + false + + src/assembly/src.xml + + + + + create-archive + package + + single + + + + + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/assembly/src.xml b/modules/samples/firealarm/component/analytics/src/assembly/src.xml new file mode 100644 index 00000000..b7735b0b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/assembly/src.xml @@ -0,0 +1,36 @@ + + + + src + + zip + + false + ${basedir}/src + + + ${basedir}/target/carbonapps + / + true + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml new file mode 100644 index 00000000..8f117bdb --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml @@ -0,0 +1,27 @@ + + + + + + false + + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml new file mode 100644 index 00000000..59756609 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + EventReceiver_humidity.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml new file mode 100644 index 00000000..484978bb --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_devices_humidity.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml new file mode 100644 index 00000000..5d490868 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml @@ -0,0 +1,62 @@ + + + + + + org.wso2.iot.devices.humidity:1.0.0 + + EVENT_STORE + + + meta_owner + true + true + false + STRING + + + meta_deviceType + true + true + false + STRING + + + meta_deviceId + true + true + false + STRING + + + meta_time + true + true + false + LONG + + + humidity + false + false + false + FLOAT + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml new file mode 100644 index 00000000..84836c69 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml @@ -0,0 +1,24 @@ + + + + + org.wso2.iot.devices.humidity_1.0.0.json + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json new file mode 100644 index 00000000..fd9ea41b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json @@ -0,0 +1,33 @@ +{ + "name": "org.wso2.iot.devices.humidity", + "version": "1.0.0", + "nickName": "Humidity Data", + "description": "Humidity data received from the Device", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceType", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "time", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "humidity", + "type": "FLOAT" + } + ] +} + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml new file mode 100644 index 00000000..ed215baa --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml @@ -0,0 +1,37 @@ + + + + + IoTServer_Sensor_Script + + 0 * * * * ? + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml new file mode 100644 index 00000000..1d92c387 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + Humidity_Sensor_Script.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml new file mode 100644 index 00000000..d89620e4 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml new file mode 100644 index 00000000..b4026b4e --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml @@ -0,0 +1,27 @@ + + + + + + false + + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml new file mode 100644 index 00000000..7cac6e0b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + EventReceiver_temperature.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml new file mode 100644 index 00000000..02990e3c --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_devices_temperature.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml new file mode 100644 index 00000000..9e41647b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml @@ -0,0 +1,62 @@ + + + + + + org.wso2.iot.devices.temperature:1.0.0 + + EVENT_STORE + + + meta_owner + true + true + false + STRING + + + meta_deviceType + true + true + false + STRING + + + meta_deviceId + true + true + false + STRING + + + meta_time + true + true + false + LONG + + + temperature + false + false + false + FLOAT + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml new file mode 100644 index 00000000..6f41292b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml @@ -0,0 +1,24 @@ + + + + + org.wso2.iot.devices.temperature_1.0.0.json + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json new file mode 100644 index 00000000..b851e5bb --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json @@ -0,0 +1,33 @@ +{ + "name": "org.wso2.iot.devices.temperature", + "version": "1.0.0", + "nickName": "Temperature Data", + "description": "Temperature data received from the Device", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceType", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "time", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "temperature", + "type": "FLOAT" + } + ] +} + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml new file mode 100644 index 00000000..d184528c --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml @@ -0,0 +1,37 @@ + + + + + IoTServer_Sensor_Script + + 0 * * * * ? + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml new file mode 100644 index 00000000..fa653516 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + Temperature_Sensor_Script.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml new file mode 100644 index 00000000..4fa4b796 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/controller/pom.xml b/modules/samples/firealarm/component/controller/pom.xml new file mode 100644 index 00000000..0ffa899e --- /dev/null +++ b/modules/samples/firealarm/component/controller/pom.xml @@ -0,0 +1,226 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.controller + 1.0.0-SNAPSHOT + war + ${groupId}.firealarm.controller + http://wso2.com + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + maven-war-plugin + ${maven-war-plugin.version} + + ${groupId}.firealarm.controller + + + + + + + org.homeautomation + ${project-base-package}.plugin + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + org.apache.cxf + cxf-rt-transports-http + + + + + org.apache.httpcomponents + httpasyncclient + 4.1 + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + + + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + + + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-jaxrs + + + javax + javaee-web-api + + + javax.ws.rs + jsr311-api + + + commons-httpclient.wso2 + commons-httpclient + + + + org.wso2.carbon + org.wso2.carbon.utils + + + org.bouncycastle.wso2 + bcprov-jdk15on + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.queuing + + + org.wso2.carbon + org.wso2.carbon.base + + + org.apache.axis2.wso2 + axis2 + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + jaxen + jaxen + + + commons-fileupload.wso2 + commons-fileupload + + + org.apache.ant.wso2 + ant + + + org.apache.ant.wso2 + ant + + + commons-httpclient.wso2 + commons-httpclient + + + org.eclipse.equinox + javax.servlet + + + org.wso2.carbon + org.wso2.carbon.registry.api + + + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + + + org.json.wso2 + json + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java new file mode 100644 index 00000000..20fdcd86 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java @@ -0,0 +1,220 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.homeautomation.firealarm.controller.api; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.controller.api.dto.DeviceJSON; +import org.homeautomation.firealarm.controller.api.exception.DeviceTypeException; +import org.homeautomation.firealarm.controller.api.transport.MQTTConnector; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.apimgt.annotations.api.API; +import org.wso2.carbon.apimgt.annotations.device.DeviceType; +import org.wso2.carbon.apimgt.annotations.device.feature.Feature; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.iot.DeviceManagement; +import org.wso2.carbon.device.mgt.iot.DeviceValidator; +import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * This is the controller API which is used to control agent side functionality + */ +@SuppressWarnings("NonJaxWsWebServices") +@API(name = "firealarm", version = "1.0.0", context = "/firealarm") +@DeviceType(value = "firealarm") +public class ControllerService { + + private static Log log = LogFactory.getLog(ControllerService.class); + private MQTTConnector mqttConnector; + + private boolean waitForServerStartup() { + while (!DeviceManagement.isServerReady()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + return true; + } + } + return false; + } + + @SuppressWarnings("unused") + public MQTTConnector getMQTTConnector() { + return mqttConnector; + } + + @SuppressWarnings("unused") + public void setMQTTConnector(final MQTTConnector MQTTConnector) { + Runnable connector = new Runnable() { + public void run() { + if (waitForServerStartup()) { + return; + } + ControllerService.this.mqttConnector = MQTTConnector; + if (MqttConfig.getInstance().isEnabled()) { + mqttConnector.connect(); + } else { + log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, MQTTConnector" + + " not started."); + } + } + }; + Thread connectorThread = new Thread(connector); + connectorThread.setDaemon(true); + connectorThread.start(); + } + + /** + * @param agentInfo device owner,id and sensor value + * @return device registration status + */ + @Path("controller/register") + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response registerDevice(final DeviceJSON agentInfo) { + if ((agentInfo.deviceId != null) && (agentInfo.owner != null)) { + return Response.status(Response.Status.OK).entity("Device has been registered successfully").build(); + } + return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Message body not " + + "well-formed and still invalid").build(); + } + + /** + * @param owner device owner + * @param deviceId unique identifier for given device type + * @param protocol name of supported protocol. here MQTT is used + * @param response to request + * @return sensor record + */ + @Path("controller/read-temperature") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Feature(code = "read-temperature", name = "Temperature", type = "monitor", + description = "Request temperature reading from device") + public SensorRecord readTemperature(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @Context HttpServletResponse response) { + SensorRecord sensorRecord = null; + if (isPermitted(owner, deviceId, response)) { + try { + sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, + DeviceTypeConstants.SENSOR_TEMPERATURE); + } catch (DeviceControllerException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + response.setStatus(Response.Status.OK.getStatusCode()); + } + return sensorRecord; + } + + /** + * @param owner device owner + * @param deviceId unique identifier for given device type + * @param protocol name of supported protocol. here MQTT is used + * @param response to request + * @return sensor record + */ + @Path("controller/read-humidity") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Feature(code = "read-humidity", name = "Humidity", type = "monitor", + description = "Request humidity reading from device") + public SensorRecord readHumidity(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @Context HttpServletResponse response) { + SensorRecord sensorRecord = null; + if (isPermitted(owner, deviceId, response)) { + try { + sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, + DeviceTypeConstants.SENSOR_HUMIDITY); + } catch (DeviceControllerException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + response.setStatus(Response.Status.OK.getStatusCode()); + } + return sensorRecord; + } + + /** + * @param owner device owner + * @param deviceId unique identifier for given device type + * @param protocol name of supported protocol. Here MQTT is used + * @param state change status of buzzer: on/off + * @param response to request + */ + @Path("controller/change-status") + @POST + @Feature(code = "change-status", name = "Buzzer: on/off", type = "operation", + description = "Switch on/off Fire Alarm Buzzer. (On / Off)") + public void changeBuzzerState(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @FormParam("state") String state, + @Context HttpServletResponse response) { + if (isPermitted(owner, deviceId, response)) { + try { + mqttConnector.sendCommandViaMQTT(owner, deviceId, "buzzer:", state.toUpperCase()); + response.setStatus(Response.Status.OK.getStatusCode()); + } catch (DeviceManagementException e) { + log.error(e); + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + } catch (DeviceTypeException e) { + log.error(e); + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + } + } + + private boolean isPermitted(String owner, String deviceId, HttpServletResponse response) { + DeviceValidator deviceValidator = new DeviceValidator(); + try { + String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if (!deviceValidator.isExist(owner, tenantDomain, new DeviceIdentifier( + deviceId, DeviceTypeConstants.DEVICE_TYPE))) { + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + } else { + return true; + } + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + return false; + } +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java new file mode 100644 index 00000000..db95b8ea --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.controller.api.dto; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * These information are sent by agent in each request to server + */ +@XmlRootElement +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeviceJSON { + @XmlElement(required = true) + public String owner; + @XmlElement(required = true) + public String deviceId; + @XmlElement(required = true) + public Float sensorValue; +} diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java new file mode 100644 index 00000000..e790a4fc --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.controller.api.exception; + +public class DeviceTypeException extends Exception { + + private static final long serialVersionUID = 2736466230451105441L; + + private String errorMessage; + + public DeviceTypeException(String msg, DeviceTypeException nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public DeviceTypeException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public DeviceTypeException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public DeviceTypeException() { + super(); + } + + public DeviceTypeException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } +} diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java new file mode 100644 index 00000000..803e4a97 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.controller.api.transport; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.homeautomation.firealarm.controller.api.exception.DeviceTypeException; +import org.homeautomation.firealarm.controller.api.util.ServiceUtils; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; +import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; +import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; + +import java.io.File; +import java.util.Calendar; +import java.util.UUID; + +/** + * MQTT is used as transport protocol. So this will provide basic functional requirement in order to communicate over + * MQTT + */ +@SuppressWarnings("no JAX-WS annotation") +public class MQTTConnector extends MQTTTransportHandler { + + private static final String publisherContext = "publisher"; + private static final String subscriberContext = "subscriber"; + private static final String subscribeTopic = + "wso2" + File.separator + "iot" + File.separator + "+" + File.separator + + DeviceTypeConstants.DEVICE_TYPE + File.separator + "+" + File.separator + + publisherContext; + private static Log log = LogFactory.getLog(MQTTConnector.class); + private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); + String publisher = "wso2/iot/%s/firealarm/%s/" + subscriberContext; + + private MQTTConnector() { + super(iotServerSubscriber, DeviceTypeConstants.DEVICE_TYPE, + MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic); + } + + /** + * This method will initialize connection with message broker + */ + @Override + public void connect() { + Runnable connector = new Runnable() { + public void run() { + while (!isConnected()) { + try { + String brokerUsername = MqttConfig.getInstance().getMqttQueueUsername(); + String brokerPassword = MqttConfig.getInstance().getMqttQueuePassword(); + setUsernameAndPassword(brokerUsername, brokerPassword); + connectToQueue(); + } catch (TransportHandlerException e) { + log.error("Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e); + try { + Thread.sleep(timeoutInterval); + } catch (InterruptedException ex) { + log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex); + } + } + try { + subscribeToQueue(); + } catch (TransportHandlerException e) { + log.warn("Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e); + } + } + } + }; + Thread connectorThread = new Thread(connector); + connectorThread.setDaemon(true); + connectorThread.start(); + } + + /** + * This callback function will be called by message broker when some messages available to subscribed topic + * + * @param message mqtt message which is coming form agent side + * @param messageParams metadata of mqtt message + */ + @Override + public void processIncomingMessage(MqttMessage message, String... messageParams) { + String topic = messageParams[0]; + String ownerAndId = topic.replace("wso2" + File.separator + "iot" + File.separator, ""); + ownerAndId = ownerAndId.replace(File.separator + DeviceTypeConstants.DEVICE_TYPE + + File.separator, ":"); + ownerAndId = ownerAndId.replace(File.separator + publisherContext, ""); + String owner = ownerAndId.split(":")[0]; + String deviceId = ownerAndId.split(":")[1]; + String[] messageData = message.toString().split(":"); + if (log.isDebugEnabled()) { + log.debug("Received MQTT message for: [OWNER-" + owner + "] & [DEVICE.ID-" + deviceId + "]"); + } + if (messageData.length == 4) { + SensorDataManager.getInstance().setSensorRecord(deviceId, DeviceTypeConstants.SENSOR_TEMPERATURE, + messageData[1], Calendar.getInstance().getTimeInMillis()); + SensorDataManager.getInstance().setSensorRecord(deviceId, DeviceTypeConstants.SENSOR_HUMIDITY, + messageData[3], Calendar.getInstance().getTimeInMillis()); + + + if (!ServiceUtils.publishTemperatureToDAS(owner, deviceId, messageData[1])) { + log.error("MQTT Subscriber: Publishing data to DAS failed."); + } + + if (!ServiceUtils.publishHumidityToDAS(owner, deviceId, messageData[3])) { + log.error("MQTT Subscriber: Publishing data to DAS failed."); + } + + if (log.isDebugEnabled()) { + log.debug("Temperature: " + messageData[1]); + log.debug("Humidity: " + messageData[3]); + } + } + } + + /** + * Publish a MQTT message to device through message broker + * + * @param topic mqtt topic which will be used to uniquely identify who are the subscribers to this topic + * @param payLoad message is to be published + * @param qos level of qos(quality of service):1,2,3 + * @param retained life status + * @throws TransportHandlerException + */ + private void publishToAgent(String topic, String payLoad, int qos, boolean retained) + throws TransportHandlerException { + if (log.isDebugEnabled()) { + log.debug("Publishing message [" + payLoad + "to topic [" + topic + "]."); + } + publishToQueue(topic, payLoad, qos, retained); + } + + /** + * Publish a MQTT message to device through message broker + * + * @param deviceOwner person who own the device + * @param deviceId unique identifier for each device + * @param operation command is to executed at agent side e.g: off, on + * @param param additional payload + * @throws DeviceManagementException + * @throws DeviceTypeException + */ + public void sendCommandViaMQTT(String deviceOwner, String deviceId, String operation, + String param) + throws DeviceManagementException, DeviceTypeException { + String topic = String.format(publisher, deviceOwner, deviceId); + String payload = operation + param; + try { + publishToAgent(topic, payload, 2, false); + } catch (TransportHandlerException e) { + String errorMessage = "Error publishing data to device with ID " + deviceId; + throw new DeviceTypeException(errorMessage, e); + } + } + + /** + * connection with message broker can be terminated + */ + @Override + public void disconnect() { + Runnable stopConnection = new Runnable() { + public void run() { + while (isConnected()) { + try { + closeConnection(); + } catch (MqttException e) { + if (log.isDebugEnabled()) { + log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint); + } + try { + Thread.sleep(timeoutInterval); + } catch (InterruptedException e1) { + log.error("MQTT-Terminator: Thread Sleep Interrupt Exception"); + } + } + } + } + }; + Thread terminatorThread = new Thread(stopConnection); + terminatorThread.setDaemon(true); + terminatorThread.start(); + } + + + @Override + public void publishDeviceData() throws TransportHandlerException { + + } + + @Override + public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException { + + } + + @Override + public void publishDeviceData(String... publishData) throws TransportHandlerException { + + } + + @Override + public void processIncomingMessage() { + + } + + @Override + public void processIncomingMessage(MqttMessage message) throws TransportHandlerException { + + } + +} diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java new file mode 100644 index 00000000..98ad99c2 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.controller.api.util; + +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService; + +public class ServiceUtils { + + private static final String ORG_WSO2_IOT_DEVICES_TEMPERATURE = "org.wso2.iot.devices.temperature"; + private static final String ORG_WSO2_IOT_DEVICES_HUMIDITY = "org.wso2.iot.devices.humidity"; + private static final String SENSOR_STREAM_VERSION = "1.0.0"; + + /** + * sensor data are published to DAS + * + * @param owner name of device owner + * @param deviceId unique identifier of the device + * @param sensorValue current value of sensor which is set at agent side + * @return status + */ + public static boolean publishTemperatureToDAS(String owner, String deviceId, + String sensorValue) { + float temperature = Float.parseFloat(sensorValue); + Object payloadCurrent[] = {temperature}; + return publishToDAS(owner, deviceId, payloadCurrent, ORG_WSO2_IOT_DEVICES_TEMPERATURE); + } + + /** + * sensor data are published to DAS + * + * @param owner name of device owner + * @param deviceId unique identifier of the device + * @param sensorValue current value of sensor which is set at agent side + * @return status + */ + public static boolean publishHumidityToDAS(String owner, String deviceId, + String sensorValue) { + float humidity = Float.parseFloat(sensorValue); + Object payloadCurrent[] = {humidity}; + return publishToDAS(owner, deviceId, payloadCurrent, ORG_WSO2_IOT_DEVICES_HUMIDITY); + } + + private static boolean publishToDAS(String owner, String deviceId, Object[] payloadCurrent, + String definition) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setUsername(owner); + if (ctx.getTenantDomain(true) == null) { + ctx.setTenantDomain("carbon.super", true); + } + DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService( + DeviceAnalyticsService.class, null); + Object metaData[] = {owner, DeviceTypeConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()}; + try { + deviceAnalyticsService.publishEvent(definition, SENSOR_STREAM_VERSION, metaData, + new Object[0], payloadCurrent); + } catch (DataPublisherConfigurationException e) { + return false; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return true; + } +} diff --git a/modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml b/modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 00000000..b410b426 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 00000000..46a71e29 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..7f6126d2 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,68 @@ + + + + + + Sample-Webapp-Controller + + JAX-WS/JAX-RS Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + 1 + + + CXFServlet + /* + + + isAdminService + false + + + doAuthentication + false + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + managed-api-context-template + /firealarm/{version} + + + managed-api-application + firealarm + + + managed-api-isSecured + true + + diff --git a/modules/samples/firealarm/component/manager/pom.xml b/modules/samples/firealarm/component/manager/pom.xml new file mode 100644 index 00000000..fd549767 --- /dev/null +++ b/modules/samples/firealarm/component/manager/pom.xml @@ -0,0 +1,231 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.manager + war + 1.0.0-SNAPSHOT + ${groupId}.firealarm.manager + http://wso2.org + + ${basedir}/src/main/java + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + maven-war-plugin + ${maven-war-plugin.version} + + ${groupId}.firealarm.manager_mgt + + + + + + + org.homeautomation + ${project-base-package}.plugin + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + + + commons-codec.wso2 + commons-codec + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + org.apache.cxf + cxf-rt-transports-http + + + + org.apache.httpcomponents + httpasyncclient + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-jaxrs + + + javax + javaee-web-api + + + javax.ws.rs + jsr311-api + + + commons-httpclient.wso2 + commons-httpclient + + + org.wso2.carbon + org.wso2.carbon.utils + + + org.bouncycastle.wso2 + bcprov-jdk15on + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.queuing + + + org.wso2.carbon + org.wso2.carbon.base + + + org.apache.axis2.wso2 + axis2 + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + jaxen + jaxen + + + commons-fileupload.wso2 + commons-fileupload + + + org.apache.ant.wso2 + ant + + + org.apache.ant.wso2 + ant + + + commons-httpclient.wso2 + commons-httpclient + + + org.eclipse.equinox + javax.servlet + + + org.wso2.carbon + org.wso2.carbon.registry.api + + + + + commons-codec + commons-codec + + + commons-io + commons-io + + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.webapp.publisher + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java new file mode 100644 index 00000000..9c4cc572 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.manager.api; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.io.FileUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.manager.api.util.APIUtil; +import org.homeautomation.firealarm.manager.api.util.ResponsePayload; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.apimgt.annotations.device.DeviceType; +import org.wso2.carbon.apimgt.webapp.publisher.KeyGenerationUtil; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.iot.apimgt.AccessTokenInfo; +import org.wso2.carbon.device.mgt.iot.apimgt.TokenClient; +import org.wso2.carbon.device.mgt.iot.exception.AccessTokenException; +import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; +import org.wso2.carbon.device.mgt.iot.util.ZipArchive; +import org.wso2.carbon.device.mgt.iot.util.ZipUtil; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@SuppressWarnings("NonJaxWsWebServices") +@DeviceType(value = "firealarm") +public class ManagerService { + + private static Log log = LogFactory.getLog(ManagerService.class); + + @Context //injected response proxy supporting multiple thread + private HttpServletResponse response; + + /** + * Generate UUID + * + * @return generated UUID + */ + private static String shortUUID() { + UUID uuid = UUID.randomUUID(); + long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong(); + return Long.toString(l, Character.MAX_RADIX); + } + + /** + * Register new device into IoT Server + * + * @param deviceId unique identifier for device + * @param name name of new device + * @return registration status + */ + @Path("manager/device/register") + @PUT + public boolean register(@QueryParam("deviceId") String deviceId, + @QueryParam("name") String name) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + if (APIUtil.getDeviceManagementService().isEnrolled(deviceIdentifier)) { + response.setStatus(Response.Status.CONFLICT.getStatusCode()); + return false; + } + + String owner = APIUtil.getAuthenticatedUser(); + Device device = new Device(); + device.setDeviceIdentifier(deviceId); + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setDateOfEnrolment(new Date().getTime()); + enrolmentInfo.setDateOfLastUpdate(new Date().getTime()); + enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD); + device.setName(name); + device.setType(DeviceTypeConstants.DEVICE_TYPE); + enrolmentInfo.setOwner(owner); + device.setEnrolmentInfo(enrolmentInfo); + KeyGenerationUtil.createApplicationKeys(DeviceTypeConstants.DEVICE_TYPE); + TokenClient accessTokenClient = new TokenClient(DeviceTypeConstants.DEVICE_TYPE); + AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId); + + //create token + String accessToken = accessTokenInfo.getAccess_token(); + String refreshToken = accessTokenInfo.getRefresh_token(); + List properties = new ArrayList<>(); + Device.Property accessTokenProperty = new Device.Property(); + accessTokenProperty.setName("accessToken"); + accessTokenProperty.setValue(accessToken); + Device.Property refreshTokenProperty = new Device.Property(); + refreshTokenProperty.setName("refreshToken"); + refreshTokenProperty.setValue(refreshToken); + properties.add(accessTokenProperty); + properties.add(refreshTokenProperty); + device.setProperties(properties); + + boolean added = APIUtil.getDeviceManagementService().enrollDevice(device); + if (added) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + return added; + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.error(e.getErrorMessage(), e); + return false; + } catch (AccessTokenException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.error("Unable to obtain access token", e); + return false; + } + } + + /** + * Remove installed device + * + * @param deviceId unique identifier for device + * @param response to request + */ + @Path("manager/device/remove/{device_id}") + @DELETE + public void removeDevice(@PathParam("device_id") String deviceId, + @Context HttpServletResponse response) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + boolean removed = APIUtil.getDeviceManagementService().disenrollDevice( + deviceIdentifier); + if (removed) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + } + + /** + * Update device name + * + * @param deviceId unique identifier for device + * @param name new name of the device + * @param response to request + * @return update status + */ + @Path("manager/device/update/{device_id}") + @POST + public boolean updateDevice(@PathParam("device_id") String deviceId, + @QueryParam("name") String name, + @Context HttpServletResponse response) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + Device device = APIUtil.getDeviceManagementService().getDevice(deviceIdentifier); + device.setDeviceIdentifier(deviceId); + device.getEnrolmentInfo().setDateOfLastUpdate(new Date().getTime()); + device.setName(name); + device.setType(DeviceTypeConstants.DEVICE_TYPE); + boolean updated = APIUtil.getDeviceManagementService().modifyEnrollment(device); + if (updated) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + return updated; + } catch (DeviceManagementException e) { + log.error(e.getErrorMessage()); + return false; + } + } + + /** + * Get device information + * + * @param deviceId unique identifier for device + * @return device + */ + @Path("manager/device/{device_id}") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Device getDevice(@PathParam("device_id") String deviceId) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + return APIUtil.getDeviceManagementService().getDevice(deviceIdentifier); + } catch (DeviceManagementException ex) { + log.error("Error occurred while retrieving device with Id " + deviceId + "\n" + ex); + return null; + } + } + + /** + * This will download the agent for given device type + * + * @param deviceName name of the device which is to be created + * @param sketchType name of sketch type + * @return agent archive + */ + @Path("manager/device/{sketch_type}/download") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response downloadSketch(@QueryParam("deviceName") String deviceName, + @PathParam("sketch_type") String sketchType) { + try { + ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); + Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile())); + response.type("application/zip"); + response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\""); + return response.build(); + } catch (IllegalArgumentException ex) { + return Response.status(400).entity(ex.getMessage()).build();//bad request + } catch (DeviceManagementException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } catch (AccessTokenException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } catch (DeviceControllerException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } catch (IOException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } + } + + /** + * This will give link to generated agent + * + * @param deviceName name of the device which is to be created + * @param sketchType name of sketch type + * @return link to generated agent + */ + @Path("manager/device/{sketch_type}/generate_link") + @GET + public Response generateSketchLink(@QueryParam("deviceName") String deviceName, + @PathParam("sketch_type") String sketchType) { + + try { + ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); + ResponsePayload responsePayload = new ResponsePayload(); + responsePayload.setStatusCode(HttpStatus.SC_OK); + responsePayload.setMessageFromServer("Sending Requested sketch by type: " + sketchType + + " and id: " + zipFile.getDeviceId() + "."); + responsePayload.setResponseContent(zipFile.getDeviceId()); + return Response.status(HttpStatus.SC_OK).entity(responsePayload).build(); + } catch (IllegalArgumentException ex) { + return Response.status(HttpStatus.SC_BAD_REQUEST).entity(ex.getMessage()).build(); + } catch (DeviceManagementException ex) { + log.error("Error occurred while creating device with name " + deviceName + "\n", ex); + return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build(); + } catch (AccessTokenException ex) { + log.error(ex.getMessage(), ex); + return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build(); + } catch (DeviceControllerException ex) { + log.error(ex.getMessage(), ex); + return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build(); + } + } + + /** + * Make zip file which include all the agent source codes and configuration file + * + * @param owner owner of the device + * @param deviceName name of device + * @param sketchType name of sketch type + * @return zip archive file + * @throws DeviceManagementException + * @throws AccessTokenException + * @throws DeviceControllerException + */ + private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType) + throws DeviceManagementException, AccessTokenException, DeviceControllerException { + if (owner == null) { + throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!"); + } + //create new device id + String deviceId = shortUUID(); + KeyGenerationUtil.createApplicationKeys(DeviceTypeConstants.DEVICE_TYPE); + TokenClient accessTokenClient = new TokenClient(DeviceTypeConstants.DEVICE_TYPE); + AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId); + //create token + String accessToken = accessTokenInfo.getAccess_token(); + String refreshToken = accessTokenInfo.getRefresh_token(); + //adding registering data + boolean status; + //Register the device with CDMF + status = register(deviceId, deviceName); + if (!status) { + String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner; + throw new DeviceManagementException(msg); + } + ZipUtil ziputil = new ZipUtil(); + ZipArchive zipFile = ziputil.createZipFile(owner, APIUtil.getTenantDomainOfUser(), sketchType, deviceId, deviceName, accessToken, + refreshToken); + zipFile.setDeviceId(deviceId); + return zipFile; + } + +} diff --git a/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java new file mode 100644 index 00000000..c3699691 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.homeautomation.firealarm.manager.api.util; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; + +/** + * This class provides utility functions used by REST-API. + */ +public class APIUtil { + + public static String getAuthenticatedUser() { + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + String username = threadLocalCarbonContext.getUsername(); + String tenantDomain = threadLocalCarbonContext.getTenantDomain(); + if (username.endsWith(tenantDomain)) { + return username.substring(0, username.lastIndexOf("@")); + } + return username; + } + + public static String getTenantDomainOfUser() { + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + return threadLocalCarbonContext.getTenantDomain(); + } + + public static DeviceManagementProviderService getDeviceManagementService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceManagementProviderService deviceManagementProviderService = + (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null); + if (deviceManagementProviderService == null) { + String msg = "Device Management service has not initialized."; + throw new IllegalStateException(msg); + } + return deviceManagementProviderService; + } +} diff --git a/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java new file mode 100644 index 00000000..684e9374 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.manager.api.util; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class ResponsePayload { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public static ResponsePayload.ResponsePayloadBuilder statusCode(int statusCode) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().statusCode(statusCode); + } + + public static ResponsePayload.ResponsePayloadBuilder messageFromServer( + String messageFromServer) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().messageFromServer(messageFromServer); + } + + public static ResponsePayload.ResponsePayloadBuilder responseContent(String responseContent) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().responseContent(responseContent); + } + + @XmlElement + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + @XmlElement + public String getMessageFromServer() { + return messageFromServer; + } + + public void setMessageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + } + + @XmlElement + public Object getResponseContent() { + return responseContent; + } + + public void setResponseContent(Object responseContent) { + this.responseContent = responseContent; + } + + private ResponsePayload.ResponsePayloadBuilder getBuilder() { + return new ResponsePayload.ResponsePayloadBuilder(); + } + + public class ResponsePayloadBuilder { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public ResponsePayloadBuilder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + public ResponsePayloadBuilder messageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + return this; + } + + public ResponsePayloadBuilder responseContent(String responseContent) { + this.responseContent = responseContent; + return this; + } + + public ResponsePayload build() { + ResponsePayload payload = new ResponsePayload(); + payload.setStatusCode(statusCode); + payload.setMessageFromServer(messageFromServer); + payload.setResponseContent(responseContent); + return payload; + } + } + +} diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 00000000..a98f6a8e --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,73 @@ + + + + + + + + + + Get device + /device-mgt/user/devices/list + /manager/device/* + GET + emm_admin,emm_user + + + Add device + /device-mgt/user/devices/add + /manager/device/register + PUT + emm_admin,emm_user + + + Download device + /device-mgt/user/devices/add + /manager/device/firealarm/download + GET + emm_admin,emm_user + + + Generate link to download + /device-mgt/user/devices/add + /manager/device/firealarm/generate_link + GET + emm_admin,emm_user + + + Update device + /device-mgt/user/devices/update + /manager/device/update/* + POST + emm_admin,emm_user + + + Remove device + /device-mgt/user/devices/remove + /manager/device/remove/* + DELETE + emm_admin,emm_user + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 00000000..b410b426 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 00000000..854b0248 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..a5f0c0c6 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,68 @@ + + + + + + Firealarm-Webapp-Manager + + JAX-WS/JAX-RS Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + 1 + + + CXFServlet + /* + + + isAdminService + false + + + doAuthentication + true + + + + managed-api-enabled + false + + + managed-api-owner + admin + + + managed-api-context-template + /firealarm/{version} + + + managed-api-application + firealarm + + + managed-api-isSecured + true + + diff --git a/modules/samples/firealarm/component/plugin/pom.xml b/modules/samples/firealarm/component/plugin/pom.xml new file mode 100644 index 00000000..492d5a4e --- /dev/null +++ b/modules/samples/firealarm/component/plugin/pom.xml @@ -0,0 +1,114 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + 1.0.0-SNAPSHOT + ${groupId}.firealarm.plugin + bundle + ${groupId}.firealarm.plugin + http://wso2.org + + + + org.apache.felix + maven-scr-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + org.apache.felix + maven-bundle-plugin + ${org.apache.felix.version} + true + + + ${groupId}.firealarm.plugin + ${groupId}.firealarm.plugin + 1.0.0-SNAPSHOT + IoT Server Impl Bundle + ${project-base-package}.plugin.internal + + org.osgi.framework, + org.osgi.service.component, + org.apache.commons.logging, + javax.naming, + javax.sql, + javax.xml.parsers, + javax.net, + javax.net.ssl, + org.w3c.dom, + org.wso2.carbon.device.mgt.common.*, + org.wso2.carbon.context.*, + org.wso2.carbon.ndatasource.core, + org.wso2.carbon.device.mgt.iot.*, + + + !${project-base-package}.plugin.internal, + ${project-base-package}.plugin.* + + + + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.osgi + org.eclipse.osgi.services + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon + org.wso2.carbon.ndatasource.core + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java new file mode 100644 index 00000000..48db43cf --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.constants; + +public class DeviceTypeConstants { + + public final static String DEVICE_TYPE = "firealarm"; + public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME"; + public final static String DEVICE_PLUGIN_DEVICE_ID = "firealarm_DEVICE_ID"; + public final static String SENSOR_TEMPERATURE = "temperature"; + public final static String SENSOR_HUMIDITY = "humidity"; + public static final String DATA_SOURCE_NAME = "jdbc/firealarmDM_DB"; + + public final static String DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN = "accessToken"; + public final static String DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN = "refreshToken"; + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java new file mode 100644 index 00000000..60b41c98 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.exception; + +public class FirealarmPluginException extends Exception { + + private String errorMessage; + + public FirealarmPluginException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public FirealarmPluginException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public FirealarmPluginException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public FirealarmPluginException() { + super(); + } + + public FirealarmPluginException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java new file mode 100644 index 00000000..63063cc6 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.exception.FirealarmPluginException; +import org.homeautomation.firealarm.plugin.impl.dao.DeviceTypeDAO; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.DeviceManager; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.FeatureManager; +import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration; +import org.wso2.carbon.device.mgt.common.license.mgt.License; +import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException; + +import java.util.List; + +/** + * + */ +public class DeviceTypeManager implements DeviceManager { + + private static final Log log = LogFactory.getLog(DeviceTypeManager.class); + + private static final DeviceTypeDAO connectedCupDAO = new DeviceTypeDAO(); + + @Override + public FeatureManager getFeatureManager() { + return null; + } + + @Override + public boolean saveConfiguration(TenantConfiguration tenantConfiguration) + throws DeviceManagementException { + //TODO implement this + return false; + } + + @Override + public TenantConfiguration getConfiguration() throws DeviceManagementException { + //TODO implement this + return null; + } + + @Override + public boolean enrollDevice(Device device) throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug("Enrolling a new Connected Cup device : " + device.getDeviceIdentifier()); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().addDevice(device); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the device enrol transaction :" + device.toString(); + log.warn(msg, iotDAOEx); + } + String msg = "Error while enrolling the Connected Cup device : " + device.getDeviceIdentifier(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public boolean modifyEnrollment(Device device) throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug("Modifying the Connected Cup device enrollment data"); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().updateDevice(device); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the update device transaction :" + device.toString(); + log.warn(msg, iotDAOEx); + } + String msg = "Error while updating the enrollment of the Connected Cup device : " + + device.getDeviceIdentifier(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug("Dis-enrolling Connected Cup device : " + deviceId); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().deleteDevice(deviceId.getId()); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the device dis enrol transaction :" + deviceId.toString(); + log.warn(msg, iotDAOEx); + } + String msg = "Error while removing the Connected Cup device : " + deviceId.getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public boolean isEnrolled(DeviceIdentifier deviceId) throws DeviceManagementException { + boolean isEnrolled = false; + try { + if (log.isDebugEnabled()) { + log.debug("Checking the enrollment of Connected Cup device : " + deviceId.getId()); + } + Device iotDevice = connectedCupDAO.getConnectedCupDeviceDAO().getDevice(deviceId.getId()); + if (iotDevice != null) { + isEnrolled = true; + } + } catch (FirealarmPluginException e) { + String msg = "Error while checking the enrollment status of Connected Cup device : " + + deviceId.getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return isEnrolled; + } + + @Override + public boolean isActive(DeviceIdentifier deviceId) throws DeviceManagementException { + return true; + } + + @Override + public boolean setActive(DeviceIdentifier deviceId, boolean status) + throws DeviceManagementException { + return true; + } + + @Override + public Device getDevice(DeviceIdentifier deviceId) throws DeviceManagementException { + Device device; + try { + if (log.isDebugEnabled()) { + log.debug("Getting the details of Connected Cup device : " + deviceId.getId()); + } + device = connectedCupDAO.getConnectedCupDeviceDAO().getDevice(deviceId.getId()); + + } catch (FirealarmPluginException e) { + String msg = "Error while fetching the Connected Cup device : " + deviceId.getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return device; + } + + @Override + public boolean setOwnership(DeviceIdentifier deviceId, String ownershipType) + throws DeviceManagementException { + return true; + } + + public boolean isClaimable(DeviceIdentifier deviceIdentifier) throws DeviceManagementException { + return false; + } + + @Override + public boolean setStatus(DeviceIdentifier deviceId, String currentOwner, + EnrolmentInfo.Status status) throws DeviceManagementException { + return false; + } + + @Override + public License getLicense(String s) throws LicenseManagementException { + return null; + } + + @Override + public void addLicense(License license) throws LicenseManagementException { + + } + + @Override + public boolean requireDeviceAuthorization() { + return false; + } + + @Override + public boolean updateDeviceInfo(DeviceIdentifier deviceIdentifier, Device device) + throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug( + "updating the details of Connected Cup device : " + deviceIdentifier); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().updateDevice(device); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the update device info transaction :" + device.toString(); + log.warn(msg, iotDAOEx); + } + String msg = + "Error while updating the Connected Cup device : " + deviceIdentifier; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public List getAllDevices() throws DeviceManagementException { + List devices; + try { + if (log.isDebugEnabled()) { + log.debug("Fetching the details of all Connected Cup devices"); + } + devices = connectedCupDAO.getConnectedCupDeviceDAO().getAllDevices(); + } catch (FirealarmPluginException e) { + String msg = "Error while fetching all Connected Cup devices."; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return devices; + } + +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java new file mode 100644 index 00000000..86d7351b --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.impl; + +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.DeviceManager; +import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; + +import java.util.List; + +public class DeviceTypeManagerService implements DeviceManagementService { + private DeviceManager deviceManager; + + @Override + public String getType() { + return DeviceTypeConstants.DEVICE_TYPE; + } + + + @Override + public String getProviderTenantDomain() { + return "carbon.super"; + } + + @Override + public boolean isSharedWithAllTenants() { + return true; + } + + @Override + public String[] getSharedTenantsDomain() { + return new String[0]; + } + + @Override + public void init() throws DeviceManagementException { + this.deviceManager = new DeviceTypeManager(); + } + + @Override + public DeviceManager getDeviceManager() { + return deviceManager; + } + + @Override + public ApplicationManager getApplicationManager() { + return null; + } + + @Override + public void notifyOperationToDevices(Operation operation, List deviceIds) + throws DeviceManagementException { + + } + + @Override + public Application[] getApplications(String domain, int pageNumber, int size) + throws ApplicationManagementException { + return new Application[0]; + } + + @Override + public void updateApplicationStatus(DeviceIdentifier deviceId, Application application, + String status) throws ApplicationManagementException { + + } + + @Override + public String getApplicationStatus(DeviceIdentifier deviceId, Application application) + throws ApplicationManagementException { + return null; + } + + @Override + public void installApplicationForDevices(Operation operation, + List deviceIdentifiers) + throws ApplicationManagementException { + + } + + @Override + public void installApplicationForUsers(Operation operation, List userNameList) + throws ApplicationManagementException { + + } + + @Override + public void installApplicationForUserRoles(Operation operation, List userRoleList) + throws ApplicationManagementException { + + } +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java new file mode 100644 index 00000000..e78b3ab0 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.impl.dao; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.homeautomation.firealarm.plugin.exception.FirealarmPluginException; +import org.homeautomation.firealarm.plugin.impl.dao.impl.DeviceTypeDAOImpl; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +public class DeviceTypeDAO { + + private static final Log log = LogFactory.getLog(DeviceTypeDAO.class); + private static DataSource dataSource; + private static ThreadLocal currentConnection = new ThreadLocal<>(); + + public DeviceTypeDAO() { + initConnectedCupDAO(); + } + + public static void initConnectedCupDAO() { + try { + Context ctx = new InitialContext(); + dataSource = (DataSource) ctx.lookup(DeviceTypeConstants.DATA_SOURCE_NAME); + } catch (NamingException e) { + log.error("Error while looking up the data source: " + + DeviceTypeConstants.DATA_SOURCE_NAME); + } + + } + + public static void beginTransaction() throws FirealarmPluginException { + try { + Connection conn = dataSource.getConnection(); + conn.setAutoCommit(false); + currentConnection.set(conn); + } catch (SQLException e) { + throw new FirealarmPluginException( + "Error occurred while retrieving datasource connection", e); + } + } + + public static Connection getConnection() throws FirealarmPluginException { + if (currentConnection.get() == null) { + try { + currentConnection.set(dataSource.getConnection()); + } catch (SQLException e) { + throw new FirealarmPluginException( + "Error occurred while retrieving data source connection", e); + } + } + return currentConnection.get(); + } + + public static void commitTransaction() throws FirealarmPluginException { + try { + Connection conn = currentConnection.get(); + if (conn != null) { + conn.commit(); + } else { + if (log.isDebugEnabled()) { + log.debug("Datasource connection associated with the current thread is null, " + + "hence commit has not been attempted"); + } + } + } catch (SQLException e) { + throw new FirealarmPluginException( + "Error occurred while committing the transaction", e); + } finally { + closeConnection(); + } + } + + public static void closeConnection() throws FirealarmPluginException { + + Connection con = currentConnection.get(); + if (con != null) { + try { + con.close(); + } catch (SQLException e) { + log.error("Error occurred while close the connection"); + } + } + currentConnection.remove(); + } + + public static void rollbackTransaction() throws FirealarmPluginException { + try { + Connection conn = currentConnection.get(); + if (conn != null) { + conn.rollback(); + } else { + if (log.isDebugEnabled()) { + log.debug( + "Datasource connection associated with the current thread is null, " + + "hence rollback has not been attempted"); + } + } + } catch (SQLException e) { + throw new FirealarmPluginException("Error occurred while rollback the transaction", e); + } finally { + closeConnection(); + } + } + + public DeviceTypeDAOImpl getConnectedCupDeviceDAO() { + return new DeviceTypeDAOImpl(); + } +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java new file mode 100644 index 00000000..e9b09baa --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.impl.dao.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.homeautomation.firealarm.plugin.exception.FirealarmPluginException; +import org.homeautomation.firealarm.plugin.impl.dao.DeviceTypeDAO; +import org.homeautomation.firealarm.plugin.impl.dao.util.DeviceTypeUtils; +import org.wso2.carbon.device.mgt.common.Device; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * Device Dao for Firealarm Devices. + */ +public class DeviceTypeDAOImpl { + + private static final Log log = LogFactory.getLog(DeviceTypeDAOImpl.class); + + public Device getDevice(String deviceId) throws FirealarmPluginException { + Connection conn; + PreparedStatement stmt = null; + Device connectedCupDevice = null; + ResultSet resultSet = null; + try { + conn = DeviceTypeDAO.getConnection(); + String selectDBQuery = + "SELECT firealarm_DEVICE_ID, DEVICE_NAME, ACCESS_TOKEN, REFRESH_TOKEN" + + " FROM firealarm_DEVICE WHERE firealarm_DEVICE_ID = ?"; + stmt = conn.prepareStatement(selectDBQuery); + stmt.setString(1, deviceId); + resultSet = stmt.executeQuery(); + + if (resultSet.next()) { + connectedCupDevice = new Device(); + connectedCupDevice.setName(resultSet.getString( + DeviceTypeConstants.DEVICE_PLUGIN_DEVICE_NAME)); + List propertyList = new ArrayList<>(); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, + resultSet.getString("ACCESS_TOKEN"))); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN, + resultSet.getString("REFRESH_TOKEN"))); + connectedCupDevice.setProperties(propertyList); + + if (log.isDebugEnabled()) { + log.debug("Firealarm service " + deviceId + " data has been fetched from" + + "Firealarm database."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while fetching Firealarm device : '" + deviceId + "'"; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, resultSet); + DeviceTypeDAO.closeConnection(); + } + return connectedCupDevice; + } + + public boolean addDevice(Device connectedCupDevice) throws FirealarmPluginException { + boolean status = false; + Connection conn; + PreparedStatement stmt = null; + try { + conn = DeviceTypeDAO.getConnection(); + String createDBQuery = + "INSERT INTO firealarm_DEVICE(firealarm_DEVICE_ID, DEVICE_NAME, " + + "ACCESS_TOKEN, REFRESH_TOKEN) VALUES (?, ?, ?, ?)"; + + stmt = conn.prepareStatement(createDBQuery); + stmt.setString(1, connectedCupDevice.getDeviceIdentifier()); + stmt.setString(2, connectedCupDevice.getName()); + stmt.setString(3, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN)); + stmt.setString(4, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN)); + + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Connected Cup device " + connectedCupDevice.getDeviceIdentifier() + + " data has been added to the Connected Cup database."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while adding the Connected Cup device '" + + connectedCupDevice.getDeviceIdentifier() + "' to the Connected Cup db."; + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, null); + } + return status; + } + + public boolean updateDevice(Device connectedCupDevice) throws FirealarmPluginException { + boolean status = false; + Connection conn; + PreparedStatement stmt = null; + try { + conn = DeviceTypeDAO.getConnection(); + String updateDBQuery = + "UPDATE firealarm_DEVICE SET DEVICE_NAME = ?, ACCESS_TOKEN=?, " + + "REFRESH_TOKEN=? WHERE firealarm_DEVICE_ID = ?"; + + stmt = conn.prepareStatement(updateDBQuery); + + if (connectedCupDevice.getProperties() == null) { + connectedCupDevice.setProperties(new ArrayList()); + } + stmt.setString(1, connectedCupDevice.getName()); + stmt.setString(2, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN)); + stmt.setString(3, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN)); + stmt.setString(4, connectedCupDevice.getDeviceIdentifier()); + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Connected Cup device " + connectedCupDevice.getDeviceIdentifier() + + " data has been modified."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while modifying the Connected Cup device '" + + connectedCupDevice.getDeviceIdentifier() + "' data."; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, null); + } + return status; + } + + public boolean deleteDevice(String deviceId) throws FirealarmPluginException { + boolean status = false; + Connection conn; + PreparedStatement stmt = null; + try { + conn = DeviceTypeDAO.getConnection(); + String deleteDBQuery = + "DELETE FROM firealarm_DEVICE WHERE firealarm_DEVICE_ID = ?"; + stmt = conn.prepareStatement(deleteDBQuery); + stmt.setString(1, deviceId); + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Connected Cup device " + deviceId + " data has deleted" + + " from the Connected Cup database."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Connected Cup device " + deviceId; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, null); + } + return status; + } + + public List getAllDevices() throws FirealarmPluginException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + Device connectedCupDevice; + List iotDevices = new ArrayList<>(); + + try { + conn = DeviceTypeDAO.getConnection(); + String selectDBQuery = + "SELECT firealarm_DEVICE_ID, DEVICE_NAME, ACCESS_TOKEN, REFRESH_TOKEN" + + "FROM firealarm_DEVICE"; + stmt = conn.prepareStatement(selectDBQuery); + resultSet = stmt.executeQuery(); + while (resultSet.next()) { + connectedCupDevice = new Device(); + connectedCupDevice.setDeviceIdentifier(resultSet.getString( + DeviceTypeConstants.DEVICE_PLUGIN_DEVICE_ID)); + connectedCupDevice.setName(resultSet.getString( + DeviceTypeConstants.DEVICE_PLUGIN_DEVICE_NAME)); + + List propertyList = new ArrayList<>(); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, + resultSet.getString("ACCESS_TOKEN"))); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN, + resultSet.getString("REFRESH_TOKEN"))); + connectedCupDevice.setProperties(propertyList); + } + if (log.isDebugEnabled()) { + log.debug("All Connected Cup device details have fetched from Connected Cup database" + + "."); + } + return iotDevices; + } catch (SQLException e) { + String msg = "Error occurred while fetching all Connected Cup device data'"; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, resultSet); + DeviceTypeDAO.closeConnection(); + } + } + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java new file mode 100644 index 00000000..e8c5c6c9 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.impl.dao.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.Device; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * Contains utility methods used by FireAlarm plugin. + */ +public class DeviceTypeUtils { + + private static Log log = LogFactory.getLog(DeviceTypeUtils.class); + + public static String getDeviceProperty(List deviceProperties, + String propertyKey) { + String deviceProperty = ""; + for (Device.Property property : deviceProperties) { + if (propertyKey.equals(property.getName())) { + deviceProperty = property.getValue(); + } + } + return deviceProperty; + } + + public static Device.Property getProperty(String property, String value) { + if (property != null) { + Device.Property prop = new Device.Property(); + prop.setName(property); + prop.setValue(value); + return prop; + } + return null; + } + + public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing result set", e); + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing prepared statement", e); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing database connection", e); + } + } + } + + public static void cleanupResources(PreparedStatement stmt, ResultSet rs) { + cleanupResources(null, stmt, rs); + } + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java new file mode 100644 index 00000000..d949e6a8 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.homeautomation.firealarm.plugin.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.impl.DeviceTypeManagerService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; + +/** + * @scr.component name="org.homeautomation.firealarm.plugin.internal.ServiceComponent" + * immediate="true" + */ + +public class ServiceComponent { + + private static final Log log = LogFactory.getLog(ServiceComponent.class); + private ServiceRegistration serviceRegistration; + + protected void activate(ComponentContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Activating firealarm Management Service Component"); + } + try { + BundleContext bundleContext = ctx.getBundleContext(); + serviceRegistration = + bundleContext.registerService(DeviceManagementService.class.getName(), new + DeviceTypeManagerService(), null); + if (log.isDebugEnabled()) { + log.debug("firealarm Management Service Component has been successfully activated"); + } + } catch (Throwable e) { + log.error("Error occurred while activating Current Sensor Management Service Component", e); + } + } + + protected void deactivate(ComponentContext ctx) { + if (log.isDebugEnabled()) { + log.debug("De-activating firealarm Management Service Component"); + } + try { + if (serviceRegistration != null) { + serviceRegistration.unregister(); + } + if (log.isDebugEnabled()) { + log.debug("Current Sensor Management Service Component has been successfully de-activated"); + } + } catch (Throwable e) { + log.error("Error occurred while de-activating Iot Device Management bundle", e); + } + } + +} diff --git a/modules/samples/firealarm/component/pom.xml b/modules/samples/firealarm/component/pom.xml new file mode 100644 index 00000000..45d5e76c --- /dev/null +++ b/modules/samples/firealarm/component/pom.xml @@ -0,0 +1,268 @@ + + + + + + + org.homeautomation + firealarm + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + 1.0.0-SNAPSHOT + firealarm-component + pom + + + + + org.apache.felix + maven-scr-plugin + ${maven-scr-plugin.version} + + + generate-scr-scrdescriptor + + scr + + + + + + + + + + + org.homeautomation + ${project-base-package}.plugin + 1.0.0-SNAPSHOT + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.webapp.publisher + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.apimgt.webapp.publisher_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon + org.wso2.carbon.ndatasource.core + ${carbon.kernel.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.ndatasource.core_${carbon.kernel.version}.jar + + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + ${carbon.iot.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.iot_${carbon.iot.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.core_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.common_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.certificate.mgt.core_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.apimgt.annotations_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.analytics_${carbon.device.mgt.jar.version}.jar + + + + commons-httpclient.wso2 + commons-httpclient + ${commons-httpclient.orbit.version} + system + + ${basedir}/../../../../repository/components/plugins/commons-httpclient_3.1.0.wso2v2.jar + + + + commons-httpclient.wso2 + commons-httpclient + ${commons-httpclient.orbit.version} + system + + ${basedir}/../../../../repository/components/plugins/commons-httpclient_3.1.0.wso2v2.jar + + + + org.wso2.carbon + org.wso2.carbon.utils + ${carbon.kernel.version} + + + org.bouncycastle.wso2 + bcprov-jdk15on + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.queuing + + + org.wso2.carbon + org.wso2.carbon.base + + + org.apache.axis2.wso2 + axis2 + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + jaxen + jaxen + + + commons-fileupload.wso2 + commons-fileupload + + + org.apache.ant.wso2 + ant + + + org.apache.ant.wso2 + ant + + + commons-httpclient.wso2 + commons-httpclient + + + org.eclipse.equinox + javax.servlet + + + org.wso2.carbon + org.wso2.carbon.registry.api + + + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.utils_${carbon.kernel.version}.jar + + + + org.igniterealtime.smack.wso2 + smack + ${smack.wso2.version} + system + + ${basedir}/../../../../repository/components/plugins/smack_3.0.4.wso2v1.jar + + + + org.igniterealtime.smack.wso2 + smackx + ${smackx.wso2.version} + system + + ${basedir}/../../../../repository/components/plugins/smackx_3.0.4.wso2v1.jar + + + + org.json.wso2 + json + ${commons-json.version} + system + + ${basedir}/../../../../repository/components/plugins/json_2.0.0.wso2v1.jar + + + + commons-codec + commons-codec + 1.4.0.wso2v1 + system + + ${basedir}/../../../../repository/components/plugins/commons-codec_1.4.0.wso2v1.jar + + + + commons-io + commons-io + ${commons-io.version} + + + + + plugin + controller + manager + analytics + ui + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/pom.xml b/modules/samples/firealarm/component/ui/pom.xml new file mode 100644 index 00000000..3e6076d1 --- /dev/null +++ b/modules/samples/firealarm/component/ui/pom.xml @@ -0,0 +1,58 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.ui + ${groupId}.firealarm.ui + pom + + + + maven-assembly-plugin + ${maven-assembly-plugin.version} + + ${project.artifactId}-1.0.0-SNAPSHOT + false + + src/assembly/src.xml + + + + + create-archive + package + + single + + + + + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/assembly/src.xml b/modules/samples/firealarm/component/ui/src/assembly/src.xml new file mode 100644 index 00000000..3f381cbe --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/assembly/src.xml @@ -0,0 +1,38 @@ + + + + + + src + + zip + + false + ${basedir}/src + + + ${basedir}/src/main/resources/jaggeryapps/ + / + true + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs new file mode 100644 index 00000000..429c632a --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs @@ -0,0 +1,130 @@ + +{{#zone "topCss"}} + +{{/zone}} + +{{#zone "device-thumbnail"}} + +{{/zone}} + +{{#zone "operation-status"}} + +{{/zone}} + +{{#zone "device-opetations"}} +
+ Operations +
+
+ {{unit "iot.unit.device.operation-bar" device=device}} +
+{{/zone}} + +{{#zone "device-detail-properties"}} +
+ +
+
+
+
Device Statistics
+ {{unit "iot.unit.device.stats" device=device}} +
+
+
Policy Compliance +
+
+
Policies
+
+ +
+
+ No policies found +
+
+
+
+
+ + + + + Add device specific policy +
+
+
Operations Log
+
+ +
+
+ Not available yet +
+
+
+
+
+
+
+
+{{/zone}} + + + diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js new file mode 100644 index 00000000..9cf48f5e --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +function onRequest(context) { + + var log = new Log("device-view.js"); + var deviceType = context.uriParams.deviceType; + var deviceId = request.getParameter("id"); + + var getProperty = require("process").getProperty; + var port = getProperty("carbon.https.port"); + var host = getProperty("carbon.local.ip"); + var sessionId = session.getId(); + if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) { + var deviceModule = require("/app/modules/device.js").deviceModule; + var device = deviceModule.viewDevice(deviceType, deviceId); + + if (device && device.status != "error") { + log.info(device); + return {"device": device, "port": port, "host": host, "sessionId": sessionId}; + } + } +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/public/images/current-sensor.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/public/images/current-sensor.png new file mode 100644 index 00000000..b1ce4901 Binary files /dev/null and b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/public/images/current-sensor.png differ diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs new file mode 100644 index 00000000..cf80b006 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs @@ -0,0 +1,18 @@ + +{{unit "iot.unit.policy.edit"}} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs new file mode 100644 index 00000000..c2a4706b --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs @@ -0,0 +1,18 @@ + +{{unit "iot.unit.policy.view"}} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs new file mode 100644 index 00000000..7b94f953 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs @@ -0,0 +1,18 @@ + +{{unit "iot.unit.policy.wizard"}} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/deviceType.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/deviceType.png new file mode 100644 index 00000000..7c580869 Binary files /dev/null and b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/deviceType.png differ diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/myDevices_analytics.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/myDevices_analytics.png new file mode 100644 index 00000000..0aafe6e7 Binary files /dev/null and b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/myDevices_analytics.png differ diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/schematicsGuide.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/schematicsGuide.png new file mode 100644 index 00000000..db4d0adb Binary files /dev/null and b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/schematicsGuide.png differ diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/thumb.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/thumb.png new file mode 100644 index 00000000..80696049 Binary files /dev/null and b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/thumb.png differ diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/download.js b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/download.js new file mode 100644 index 00000000..21251e2f --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/download.js @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var modalPopup = ".wr-modalpopup"; +var modalPopupContainer = modalPopup + " .modalpopup-container"; +var modalPopupContent = modalPopup + " .modalpopup-content"; +var body = "body"; + +/* + * set popup maximum height function. + */ +function setPopupMaxHeight() { + $(modalPopupContent).css('max-height', ($(body).height() - ($(body).height() / 100 * 30))); + $(modalPopupContainer).css('margin-top', (-($(modalPopupContainer).height() / 2))); +} + +/* + * show popup function. + */ +function showPopup() { + $(modalPopup).show(); + setPopupMaxHeight(); + $('#downloadForm').validate({ + rules: { + deviceName: { + minlength: 4, + required: true + } + }, + highlight: function (element) { + $(element).closest('.control-group').removeClass('success').addClass('error'); + }, + success: function (element) { + $(element).closest('.control-group').removeClass('error').addClass('success'); + $('label[for=deviceName]').remove(); + } + }); + var deviceType = ""; + $('.deviceType').each(function () { + if (this.value != "") { + deviceType = this.value; + } + }); +} + +/* + * hide popup function. + */ +function hidePopup() { + $('label[for=deviceName]').remove(); + $('.control-group').removeClass('success').removeClass('error'); + $(modalPopupContent).html(''); + $(modalPopup).hide(); +} + +/* + * DOM ready functions. + */ +$(document).ready(function () { + attachEvents(); +}); + +function attachEvents() { + /** + * Following click function would execute + * when a user clicks on "Download" link + * on Device Management page in WSO2 DC Console. + */ + $("a.download-link").click(function () { + var sketchType = $(this).data("sketchtype"); + var deviceType = $(this).data("devicetype"); + var downloadDeviceAPI = "/devicemgt/api/devices/sketch/generate_link"; + var payload = {"sketchType": sketchType, "deviceType": deviceType}; + $(modalPopupContent).html($('#download-device-modal-content').html()); + showPopup(); + var deviceName; + $("a#download-device-download-link").click(function () { + $('.new-device-name').each(function () { + if (this.value != "") { + deviceName = this.value; + } + }); + $('label[for=deviceName]').remove(); + if (deviceName && deviceName.length >= 4) { + payload.deviceName = deviceName; + invokerUtil.post( + downloadDeviceAPI, + payload, + function (data, textStatus, jqxhr) { + doAction(data); + }, + function (data) { + doAction(data); + } + ); + } else if (deviceName) { + $('.controls').append(''); + $('.control-group').removeClass('success').addClass('error'); + } else { + $('.controls').append(''); + $('.control-group').removeClass('success').addClass('error'); + } + }); + + $("a#download-device-cancel-link").click(function () { + hidePopup(); + }); + + }); +} + +function downloadAgent() { + var deviceName = ""; + $('.new-device-name').each(function () { + if (this.value != "") { + deviceName = this.value; + } + }); + var deviceType = ""; + $('.deviceType').each(function () { + if (this.value != "") { + deviceType = this.value; + } + }); + var sketchType = ""; + $('.sketchType').each(function () { + if (this.value != "") { + sketchType = this.value; + } + }); + var deviceNameFormat = /^[^~?!#$:;%^*`+={}\[\]\\()|<>,'"]{1,30}$/; + if (deviceName && deviceNameFormat.test(deviceName)) { + $(modalPopupContent).html($('#device-agent-downloading-content').html()); + var successCallback = function (data) { + data = JSON.parse(data); + hidePopup(); + window.location = "/devicemgt/api/devices/sketch/download/" + data.responseContent; + }; + var generateLink = "/" + deviceType + "_mgt/manager/device/" + sketchType + + "/generate_link?deviceName=" + deviceName; + invokerUtil.get(generateLink, successCallback, function (message) { + console.log(message.content); + hidePopup(); + doAction(data); + }); + } else { + $("#invalid-username-error-msg span").text("Invalid device name"); + $("#invalid-username-error-msg").removeClass("hidden"); + } +} + +function doAction(data) { + //if it is saml redirection response + if (data.status == null) { + document.write(data); + } + + if (data.status == "401") { + $(modalPopupContent).html($('#device-401-content').html()); + $("#device-401-link").click(function () { + window.location = "/devicemgt/login"; + }); + showPopup(); + } else if (data == "403") { + $(modalPopupContent).html($('#device-403-content').html()); + $("#device-403-link").click(function () { + window.location = "/devicemgt/login"; + }); + showPopup(); + } else { + $(modalPopupContent).html($('#device-unexpected-error-content').html()); + $("a#device-unexpected-error-link").click(function () { + hidePopup(); + }); + } +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js new file mode 100644 index 00000000..ae92b49e --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js @@ -0,0 +1,1234 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +(function ($) { + + $.extend($.fn, { + // http://docs.jquery.com/Plugins/Validation/validate + validate: function (options) { + + // if nothing is selected, return nothing; can't chain anyway + if (!this.length) { + if (options && options.debug && window.console) { + console.warn("Nothing selected, can't validate, returning nothing."); + } + return; + } + + // check if a validator for this form was already created + var validator = $.data(this[0], "validator"); + if (validator) { + return validator; + } + + // Add novalidate tag if HTML5. + this.attr("novalidate", "novalidate"); + + validator = new $.validator(options, this[0]); + $.data(this[0], "validator", validator); + + if (validator.settings.onsubmit) { + + this.validateDelegate(":submit", "click", function (event) { + if (validator.settings.submitHandler) { + validator.submitButton = event.target; + } + // allow suppressing validation by adding a cancel class to the submit button + if ($(event.target).hasClass("cancel")) { + validator.cancelSubmit = true; + } + }); + + // validate the form on submit + this.submit(function (event) { + if (validator.settings.debug) { + // prevent form submit to be able to see console output + event.preventDefault(); + } + function handle() { + var hidden; + if (validator.settings.submitHandler) { + if (validator.submitButton) { + // insert a hidden input as a replacement for the missing submit button + hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); + } + validator.settings.submitHandler.call(validator, validator.currentForm, event); + if (validator.submitButton) { + // and clean up afterwards; thanks to no-block-scope, hidden can be referenced + hidden.remove(); + } + return false; + } + return true; + } + + // prevent submit for invalid forms or custom submit handlers + if (validator.cancelSubmit) { + validator.cancelSubmit = false; + return handle(); + } + if (validator.form()) { + if (validator.pendingRequest) { + validator.formSubmitted = true; + return false; + } + return handle(); + } else { + validator.focusInvalid(); + return false; + } + }); + } + + return validator; + }, + // http://docs.jquery.com/Plugins/Validation/valid + valid: function () { + if ($(this[0]).is("form")) { + return this.validate().form(); + } else { + var valid = true; + var validator = $(this[0].form).validate(); + this.each(function () { + valid &= validator.element(this); + }); + return valid; + } + }, + // attributes: space seperated list of attributes to retrieve and remove + removeAttrs: function (attributes) { + var result = {}, + $element = this; + $.each(attributes.split(/\s/), function (index, value) { + result[value] = $element.attr(value); + $element.removeAttr(value); + }); + return result; + }, + // http://docs.jquery.com/Plugins/Validation/rules + rules: function (command, argument) { + var element = this[0]; + + if (command) { + var settings = $.data(element.form, "validator").settings; + var staticRules = settings.rules; + var existingRules = $.validator.staticRules(element); + switch (command) { + case "add": + $.extend(existingRules, $.validator.normalizeRule(argument)); + staticRules[element.name] = existingRules; + if (argument.messages) { + settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages); + } + break; + case "remove": + if (!argument) { + delete staticRules[element.name]; + return existingRules; + } + var filtered = {}; + $.each(argument.split(/\s/), function (index, method) { + filtered[method] = existingRules[method]; + delete existingRules[method]; + }); + return filtered; + } + } + + var data = $.validator.normalizeRules( + $.extend( + {}, + $.validator.classRules(element), + $.validator.attributeRules(element), + $.validator.dataRules(element), + $.validator.staticRules(element) + ), element); + + // make sure required is at front + if (data.required) { + var param = data.required; + delete data.required; + data = $.extend({required: param}, data); + } + + return data; + } + }); + +// Custom selectors + $.extend($.expr[":"], { + // http://docs.jquery.com/Plugins/Validation/blank + blank: function (a) { + return !$.trim("" + a.value); + }, + // http://docs.jquery.com/Plugins/Validation/filled + filled: function (a) { + return !!$.trim("" + a.value); + }, + // http://docs.jquery.com/Plugins/Validation/unchecked + unchecked: function (a) { + return !a.checked; + } + }); + +// constructor for validator + $.validator = function (options, form) { + this.settings = $.extend(true, {}, $.validator.defaults, options); + this.currentForm = form; + this.init(); + }; + + $.validator.format = function (source, params) { + if (arguments.length === 1) { + return function () { + var args = $.makeArray(arguments); + args.unshift(source); + return $.validator.format.apply(this, args); + }; + } + if (arguments.length > 2 && params.constructor !== Array) { + params = $.makeArray(arguments).slice(1); + } + if (params.constructor !== Array) { + params = [params]; + } + $.each(params, function (i, n) { + source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () { + return n; + }); + }); + return source; + }; + + $.extend($.validator, { + + defaults: { + messages: {}, + groups: {}, + rules: {}, + errorClass: "error", + validClass: "valid", + errorElement: "label", + focusInvalid: true, + errorContainer: $([]), + errorLabelContainer: $([]), + onsubmit: true, + ignore: ":hidden", + ignoreTitle: false, + onfocusin: function (element, event) { + this.lastActive = element; + + // hide error label and remove error class on focus if enabled + if (this.settings.focusCleanup && !this.blockFocusCleanup) { + if (this.settings.unhighlight) { + this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass); + } + this.addWrapper(this.errorsFor(element)).hide(); + } + }, + onfocusout: function (element, event) { + if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { + this.element(element); + } + }, + onkeyup: function (element, event) { + if (event.which === 9 && this.elementValue(element) === "") { + return; + } else if (element.name in this.submitted || element === this.lastElement) { + this.element(element); + } + }, + onclick: function (element, event) { + // click on selects, radiobuttons and checkboxes + if (element.name in this.submitted) { + this.element(element); + } + // or option elements, check parent select in that case + else if (element.parentNode.name in this.submitted) { + this.element(element.parentNode); + } + }, + highlight: function (element, errorClass, validClass) { + if (element.type === "radio") { + this.findByName(element.name).addClass(errorClass).removeClass(validClass); + } else { + $(element).addClass(errorClass).removeClass(validClass); + } + }, + unhighlight: function (element, errorClass, validClass) { + if (element.type === "radio") { + this.findByName(element.name).removeClass(errorClass).addClass(validClass); + } else { + $(element).removeClass(errorClass).addClass(validClass); + } + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults + setDefaults: function (settings) { + $.extend($.validator.defaults, settings); + }, + + messages: { + required: "This field is required.", + remote: "Please fix this field.", + email: "Please enter a valid email address.", + url: "Please enter a valid URL.", + date: "Please enter a valid date.", + dateISO: "Please enter a valid date (ISO).", + number: "Please enter a valid number.", + digits: "Please enter only digits.", + creditcard: "Please enter a valid credit card number.", + equalTo: "Please enter the same value again.", + maxlength: $.validator.format("Please enter no more than {0} characters."), + minlength: $.validator.format("Please enter at least {0} characters."), + rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), + range: $.validator.format("Please enter a value between {0} and {1}."), + max: $.validator.format("Please enter a value less than or equal to {0}."), + min: $.validator.format("Please enter a value greater than or equal to {0}.") + }, + + autoCreateRanges: false, + + prototype: { + + init: function () { + this.labelContainer = $(this.settings.errorLabelContainer); + this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); + this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer); + this.submitted = {}; + this.valueCache = {}; + this.pendingRequest = 0; + this.pending = {}; + this.invalid = {}; + this.reset(); + + var groups = (this.groups = {}); + $.each(this.settings.groups, function (key, value) { + if (typeof value === "string") { + value = value.split(/\s/); + } + $.each(value, function (index, name) { + groups[name] = key; + }); + }); + var rules = this.settings.rules; + $.each(rules, function (key, value) { + rules[key] = $.validator.normalizeRule(value); + }); + + function delegate(event) { + var validator = $.data(this[0].form, "validator"), + eventType = "on" + event.type.replace(/^validate/, ""); + if (validator.settings[eventType]) { + validator.settings[eventType].call(validator, this[0], event); + } + } + + $(this.currentForm) + .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " + + "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + + "[type='email'], [type='datetime'], [type='date'], [type='month'], " + + "[type='week'], [type='time'], [type='datetime-local'], " + + "[type='range'], [type='color'] ", + "focusin focusout keyup", delegate) + .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); + + if (this.settings.invalidHandler) { + $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/form + form: function () { + this.checkForm(); + $.extend(this.submitted, this.errorMap); + this.invalid = $.extend({}, this.errorMap); + if (!this.valid()) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + } + this.showErrors(); + return this.valid(); + }, + + checkForm: function () { + this.prepareForm(); + for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) { + this.check(elements[i]); + } + return this.valid(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/element + element: function (element) { + element = this.validationTargetFor(this.clean(element)); + this.lastElement = element; + this.prepareElement(element); + this.currentElements = $(element); + var result = this.check(element) !== false; + if (result) { + delete this.invalid[element.name]; + } else { + this.invalid[element.name] = true; + } + if (!this.numberOfInvalids()) { + // Hide error containers on last error + this.toHide = this.toHide.add(this.containers); + } + this.showErrors(); + return result; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/showErrors + showErrors: function (errors) { + if (errors) { + // add items to error list and map + $.extend(this.errorMap, errors); + this.errorList = []; + for (var name in errors) { + this.errorList.push({ + message: errors[name], + element: this.findByName(name)[0] + }); + } + // remove items from success list + this.successList = $.grep(this.successList, function (element) { + return !(element.name in errors); + }); + } + if (this.settings.showErrors) { + this.settings.showErrors.call(this, this.errorMap, this.errorList); + } else { + this.defaultShowErrors(); + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/resetForm + resetForm: function () { + if ($.fn.resetForm) { + $(this.currentForm).resetForm(); + } + this.submitted = {}; + this.lastElement = null; + this.prepareForm(); + this.hideErrors(); + this.elements().removeClass(this.settings.errorClass).removeData("previousValue"); + }, + + numberOfInvalids: function () { + return this.objectLength(this.invalid); + }, + + objectLength: function (obj) { + var count = 0; + for (var i in obj) { + count++; + } + return count; + }, + + hideErrors: function () { + this.addWrapper(this.toHide).hide(); + }, + + valid: function () { + return this.size() === 0; + }, + + size: function () { + return this.errorList.length; + }, + + focusInvalid: function () { + if (this.settings.focusInvalid) { + try { + $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) + .filter(":visible") + .focus() + // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find + .trigger("focusin"); + } catch (e) { + // ignore IE throwing errors when focusing hidden elements + } + } + }, + + findLastActive: function () { + var lastActive = this.lastActive; + return lastActive && $.grep(this.errorList, function (n) { + return n.element.name === lastActive.name; + }).length === 1 && lastActive; + }, + + elements: function () { + var validator = this, + rulesCache = {}; + + // select all valid inputs inside the form (no submit or reset buttons) + return $(this.currentForm) + .find("input, select, textarea") + .not(":submit, :reset, :image, [disabled]") + .not(this.settings.ignore) + .filter(function () { + if (!this.name) { + if (window.console) { + console.error("%o has no name assigned", this); + } + throw new Error("Failed to validate, found an element with no name assigned. See console for element reference."); + } + + // select only the first element for each name, and only those with rules specified + if (this.name in rulesCache || !validator.objectLength($(this).rules())) { + return false; + } + + rulesCache[this.name] = true; + return true; + }); + }, + + clean: function (selector) { + return $(selector)[0]; + }, + + errors: function () { + var errorClass = this.settings.errorClass.replace(" ", "."); + return $(this.settings.errorElement + "." + errorClass, this.errorContext); + }, + + reset: function () { + this.successList = []; + this.errorList = []; + this.errorMap = {}; + this.toShow = $([]); + this.toHide = $([]); + this.currentElements = $([]); + }, + + prepareForm: function () { + this.reset(); + this.toHide = this.errors().add(this.containers); + }, + + prepareElement: function (element) { + this.reset(); + this.toHide = this.errorsFor(element); + }, + + elementValue: function (element) { + var type = $(element).attr("type"), + val = $(element).val(); + + if (type === "radio" || type === "checkbox") { + return $("input[name='" + $(element).attr("name") + "']:checked").val(); + } + + if (typeof val === "string") { + return val.replace(/\r/g, ""); + } + return val; + }, + + check: function (element) { + element = this.validationTargetFor(this.clean(element)); + + var rules = $(element).rules(); + var dependencyMismatch = false; + var val = this.elementValue(element); + var result; + + for (var method in rules) { + var rule = {method: method, parameters: rules[method]}; + try { + + result = $.validator.methods[method].call(this, val, element, rule.parameters); + + // if a method indicates that the field is optional and therefore valid, + // don't mark it as valid when there are no other rules + if (result === "dependency-mismatch") { + dependencyMismatch = true; + continue; + } + dependencyMismatch = false; + + if (result === "pending") { + this.toHide = this.toHide.not(this.errorsFor(element)); + return; + } + + if (!result) { + this.formatAndAdd(element, rule); + return false; + } + } catch (e) { + if (this.settings.debug && window.console) { + console.log("Exception occured when checking element " + element.id + ", check the '" + rule.method + "' method.", e); + } + throw e; + } + } + if (dependencyMismatch) { + return; + } + if (this.objectLength(rules)) { + this.successList.push(element); + } + return true; + }, + + // return the custom message for the given element and validation method + // specified in the element's HTML5 data attribute + customDataMessage: function (element, method) { + return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); + }, + + // return the custom message for the given element name and validation method + customMessage: function (name, method) { + var m = this.settings.messages[name]; + return m && (m.constructor === String ? m : m[method]); + }, + + // return the first defined argument, allowing empty strings + findDefined: function () { + for (var i = 0; i < arguments.length; i++) { + if (arguments[i] !== undefined) { + return arguments[i]; + } + } + return undefined; + }, + + defaultMessage: function (element, method) { + return this.findDefined( + this.customMessage(element.name, method), + this.customDataMessage(element, method), + // title is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[method], + "Warning: No message defined for " + element.name + "" + ); + }, + + formatAndAdd: function (element, rule) { + var message = this.defaultMessage(element, rule.method), + theregex = /\$?\{(\d+)\}/g; + if (typeof message === "function") { + message = message.call(this, rule.parameters, element); + } else if (theregex.test(message)) { + message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); + } + this.errorList.push({ + message: message, + element: element + }); + + this.errorMap[element.name] = message; + this.submitted[element.name] = message; + }, + + addWrapper: function (toToggle) { + if (this.settings.wrapper) { + toToggle = toToggle.add(toToggle.parent(this.settings.wrapper)); + } + return toToggle; + }, + + defaultShowErrors: function () { + var i, elements; + for (i = 0; this.errorList[i]; i++) { + var error = this.errorList[i]; + if (this.settings.highlight) { + this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass); + } + this.showLabel(error.element, error.message); + } + if (this.errorList.length) { + this.toShow = this.toShow.add(this.containers); + } + if (this.settings.success) { + for (i = 0; this.successList[i]; i++) { + this.showLabel(this.successList[i]); + } + } + if (this.settings.unhighlight) { + for (i = 0, elements = this.validElements(); elements[i]; i++) { + this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass); + } + } + this.toHide = this.toHide.not(this.toShow); + this.hideErrors(); + this.addWrapper(this.toShow).show(); + }, + + validElements: function () { + return this.currentElements.not(this.invalidElements()); + }, + + invalidElements: function () { + return $(this.errorList).map(function () { + return this.element; + }); + }, + + showLabel: function (element, message) { + var label = this.errorsFor(element); + if (label.length) { + // refresh error/success class + label.removeClass(this.settings.validClass).addClass(this.settings.errorClass); + + // check if we have a generated label, replace the message then + if (label.attr("generated")) { + label.html(message); + } + } else { + // create label + label = $("<" + this.settings.errorElement + "/>") + .attr({"for": this.idOrName(element), generated: true}) + .addClass(this.settings.errorClass) + .html(message || ""); + if (this.settings.wrapper) { + // make sure the element is visible, even in IE + // actually showing the wrapped element is handled elsewhere + label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); + } + if (!this.labelContainer.append(label).length) { + if (this.settings.errorPlacement) { + this.settings.errorPlacement(label, $(element)); + } else { + label.insertAfter(element); + } + } + } + if (!message && this.settings.success) { + label.text(""); + if (typeof this.settings.success === "string") { + label.addClass(this.settings.success); + } else { + this.settings.success(label, element); + } + } + this.toShow = this.toShow.add(label); + }, + + errorsFor: function (element) { + var name = this.idOrName(element); + return this.errors().filter(function () { + return $(this).attr("for") === name; + }); + }, + + idOrName: function (element) { + return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); + }, + + validationTargetFor: function (element) { + // if radio/checkbox, validate first element in group instead + if (this.checkable(element)) { + element = this.findByName(element.name).not(this.settings.ignore)[0]; + } + return element; + }, + + checkable: function (element) { + return (/radio|checkbox/i).test(element.type); + }, + + findByName: function (name) { + return $(this.currentForm).find("[name='" + name + "']"); + }, + + getLength: function (value, element) { + switch (element.nodeName.toLowerCase()) { + case "select": + return $("option:selected", element).length; + case "input": + if (this.checkable(element)) { + return this.findByName(element.name).filter(":checked").length; + } + } + return value.length; + }, + + depend: function (param, element) { + return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; + }, + + dependTypes: { + "boolean": function (param, element) { + return param; + }, + "string": function (param, element) { + return !!$(param, element.form).length; + }, + "function": function (param, element) { + return param(element); + } + }, + + optional: function (element) { + var val = this.elementValue(element); + return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; + }, + + startRequest: function (element) { + if (!this.pending[element.name]) { + this.pendingRequest++; + this.pending[element.name] = true; + } + }, + + stopRequest: function (element, valid) { + this.pendingRequest--; + // sometimes synchronization fails, make sure pendingRequest is never < 0 + if (this.pendingRequest < 0) { + this.pendingRequest = 0; + } + delete this.pending[element.name]; + if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) { + $(this.currentForm).submit(); + this.formSubmitted = false; + } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.formSubmitted = false; + } + }, + + previousValue: function (element) { + return $.data(element, "previousValue") || $.data(element, "previousValue", { + old: null, + valid: true, + message: this.defaultMessage(element, "remote") + }); + } + + }, + + classRuleSettings: { + required: {required: true}, + email: {email: true}, + url: {url: true}, + date: {date: true}, + dateISO: {dateISO: true}, + number: {number: true}, + digits: {digits: true}, + creditcard: {creditcard: true} + }, + + addClassRules: function (className, rules) { + if (className.constructor === String) { + this.classRuleSettings[className] = rules; + } else { + $.extend(this.classRuleSettings, className); + } + }, + + classRules: function (element) { + var rules = {}; + var classes = $(element).attr("class"); + if (classes) { + $.each(classes.split(" "), function () { + if (this in $.validator.classRuleSettings) { + $.extend(rules, $.validator.classRuleSettings[this]); + } + }); + } + return rules; + }, + + attributeRules: function (element) { + var rules = {}; + var $element = $(element); + + for (var method in $.validator.methods) { + var value; + + // support for in both html5 and older browsers + if (method === "required") { + value = $element.get(0).getAttribute(method); + // Some browsers return an empty string for the required attribute + // and non-HTML5 browsers might have required="" markup + if (value === "") { + value = true; + } + // force non-HTML5 browsers to return bool + value = !!value; + } else { + value = $element.attr(method); + } + + if (value) { + rules[method] = value; + } else if ($element[0].getAttribute("type") === method) { + rules[method] = true; + } + } + + // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs + if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { + delete rules.maxlength; + } + + return rules; + }, + + dataRules: function (element) { + var method, value, + rules = {}, $element = $(element); + for (method in $.validator.methods) { + value = $element.data("rule-" + method.toLowerCase()); + if (value !== undefined) { + rules[method] = value; + } + } + return rules; + }, + + staticRules: function (element) { + var rules = {}; + var validator = $.data(element.form, "validator"); + if (validator.settings.rules) { + rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; + } + return rules; + }, + + normalizeRules: function (rules, element) { + // handle dependency check + $.each(rules, function (prop, val) { + // ignore rule when param is explicitly false, eg. required:false + if (val === false) { + delete rules[prop]; + return; + } + if (val.param || val.depends) { + var keepRule = true; + switch (typeof val.depends) { + case "string": + keepRule = !!$(val.depends, element.form).length; + break; + case "function": + keepRule = val.depends.call(element, element); + break; + } + if (keepRule) { + rules[prop] = val.param !== undefined ? val.param : true; + } else { + delete rules[prop]; + } + } + }); + + // evaluate parameters + $.each(rules, function (rule, parameter) { + rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; + }); + + // clean number parameters + $.each(["minlength", "maxlength", "min", "max"], function () { + if (rules[this]) { + rules[this] = Number(rules[this]); + } + }); + $.each(["rangelength", "range"], function () { + var parts; + if (rules[this]) { + if ($.isArray(rules[this])) { + rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; + } else if (typeof rules[this] === "string") { + parts = rules[this].split(/[\s,]+/); + rules[this] = [Number(parts[0]), Number(parts[1])]; + } + } + }); + + if ($.validator.autoCreateRanges) { + // auto-create ranges + if (rules.min && rules.max) { + rules.range = [rules.min, rules.max]; + delete rules.min; + delete rules.max; + } + if (rules.minlength && rules.maxlength) { + rules.rangelength = [rules.minlength, rules.maxlength]; + delete rules.minlength; + delete rules.maxlength; + } + } + + return rules; + }, + + // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} + normalizeRule: function (data) { + if (typeof data === "string") { + var transformed = {}; + $.each(data.split(/\s/), function () { + transformed[this] = true; + }); + data = transformed; + } + return data; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/addMethod + addMethod: function (name, method, message) { + $.validator.methods[name] = method; + $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; + if (method.length < 3) { + $.validator.addClassRules(name, $.validator.normalizeRule(name)); + } + }, + + methods: { + + // http://docs.jquery.com/Plugins/Validation/Methods/required + required: function (value, element, param) { + // check if dependency is met + if (!this.depend(param, element)) { + return "dependency-mismatch"; + } + if (element.nodeName.toLowerCase() === "select") { + // could be an array for select-multiple or a string, both are fine this way + var val = $(element).val(); + return val && val.length > 0; + } + if (this.checkable(element)) { + return this.getLength(value, element) > 0; + } + return $.trim(value).length > 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/remote + remote: function (value, element, param) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name]) { + this.settings.messages[element.name] = {}; + } + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param === "string" && {url: param} || param; + + if (previous.old === value) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + $.ajax($.extend(true, { + url: param, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function (response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + var valid = response === true || response === "true"; + if (valid) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + delete validator.invalid[element.name]; + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage(element, "remote"); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.invalid[element.name] = true; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return "pending"; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/minlength + minlength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || length >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/maxlength + maxlength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || length <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/rangelength + rangelength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || ( length >= param[0] && length <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/min + min: function (value, element, param) { + return this.optional(element) || value >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/max + max: function (value, element, param) { + return this.optional(element) || value <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/range + range: function (value, element, param) { + return this.optional(element) || ( value >= param[0] && value <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/email + email: function (value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/url + url: function (value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ + return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/date + date: function (value, element) { + return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/dateISO + dateISO: function (value, element) { + return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/number + number: function (value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/digits + digits: function (value, element) { + return this.optional(element) || /^\d+$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/creditcard + // based on http://en.wikipedia.org/wiki/Luhn + creditcard: function (value, element) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + // accept only spaces, digits and dashes + if (/[^0-9 \-]+/.test(value)) { + return false; + } + var nCheck = 0, + nDigit = 0, + bEven = false; + + value = value.replace(/\D/g, ""); + + for (var n = value.length - 1; n >= 0; n--) { + var cDigit = value.charAt(n); + nDigit = parseInt(cDigit, 10); + if (bEven) { + if ((nDigit *= 2) > 9) { + nDigit -= 9; + } + } + nCheck += nDigit; + bEven = !bEven; + } + + return (nCheck % 10) === 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/equalTo + equalTo: function (value, element, param) { + // bind to the blur event of the target in order to revalidate whenever the target field is updated + // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead + var target = $(param); + if (this.settings.onfocusout) { + target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function () { + $(element).valid(); + }); + } + return value === target.val(); + } + + } + + }); + +// deprecated, use $.validator.format instead + $.format = $.validator.format; + +}(jQuery)); + +// ajax mode: abort +// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); +// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() +(function ($) { + var pendingRequests = {}; + // Use a prefilter if available (1.5+) + if ($.ajaxPrefilter) { + $.ajaxPrefilter(function (settings, _, xhr) { + var port = settings.port; + if (settings.mode === "abort") { + if (pendingRequests[port]) { + pendingRequests[port].abort(); + } + pendingRequests[port] = xhr; + } + }); + } else { + // Proxy ajax + var ajax = $.ajax; + $.ajax = function (settings) { + var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, + port = ( "port" in settings ? settings : $.ajaxSettings ).port; + if (mode === "abort") { + if (pendingRequests[port]) { + pendingRequests[port].abort(); + } + return (pendingRequests[port] = ajax.apply(this, arguments)); + } + return ajax.apply(this, arguments); + }; + } +}(jQuery)); + +// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation +// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target +(function ($) { + $.extend($.fn, { + validateDelegate: function (delegate, type, handler) { + return this.bind(type, function (event) { + var target = $(event.target); + if (target.is(delegate)) { + return handler.apply(target, arguments); + } + }); + } + }); +}(jQuery)); diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs new file mode 100644 index 00000000..8299b21e --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs @@ -0,0 +1,378 @@ +
+

Fire Alarm

+
+
+ +
+ +
+ +
+ +

What it Does

+
+

Connect your Fire Alarm to WSO2 IoT Server.

+
+

An ESP8266 based fire alarm device. Once run, the Fire alarm will connect to WSO2 IoTServer + and push Temperature and Humidity readings via MQTT. You can also on/off fire alarm buzzer + remotely with IoTServer. +

+
+

What You Need

+
+
    +
  • + STEP 01 +    NodeMCU loaded ESP8266 201 Module. +
  • +
  • + STEP 02 +    DHT11 Temperature & Humidity Sensor. +
  • +
  • + STEP 03 +    Buzzer. +
  • +
  • + STEP 04 +    USB to TTL converter. +
  • +
  • + STEP 05 +    ESPlorer software. If you don't have please click + [here] + to download. +
  • +
+
+ View API   + Download + Agent + +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

+
+ +
+

Prepare

+
+
    +
  • + 01 +    Connect USB to TTL converter and other component with ESP8266 201 + module + as schematic in FIRE ALARM SETUP. +
  • +
  • + 02 +    Download Agent files from [Download Agent] link above. +
  • +
  • + 03 +    Unzip the downloaded Fire Alarm Agent +
  • +
  • + 04 +    Open wifi-connect.lua and provide appropriate values for + [SSID] and + [Password] + variables according to your network. +
  • +
  • + 05 +    Upload all .lua files to ESP8266 using ESPlorer in following order. + Then restart the ESP8266. +
    +                + + + + +    dht_lib.lua +
    +                + + + + +    wifi-connect.lua +
    +                + + + + +    read-sensor.lua +
    +                + + + + +    init.lua +

    +
  • +
  • + 06 +    Now you can remove USB to TTL module and fix fire alarm device in any + place you want. +

    +                + + + + +    ESP8266 will publish temperature and humidity from DHT11 to + WSO2-IoT-Server +

    +                + + + + +    Buzzer can be controlled from Device Management page. +
  • +
+
+
+ +
+

Fire alarm Setup

+
+

Click on the image to zoom

+
+ + + +
+
+
+ +
+

Try Out

+
+
    +
  • 01   You can view + all your connected + devices at [Device + Management] + page. +
  • +
  • 02   Select one of + connected devices and check for + available control operations. +
  • +
+
+ +
+ + + +{{#zone "bottomJs"}} + {{js "/js/download.js"}} + {{js "/js/jquery.validate.js"}} +{{/zone}} + diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/pom.xml b/modules/samples/firealarm/feature/feature/pom.xml new file mode 100644 index 00000000..aa60607d --- /dev/null +++ b/modules/samples/firealarm/feature/feature/pom.xml @@ -0,0 +1,244 @@ + + + + + + + org.homeautomation + firealarm-feature + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + 1.0.0-SNAPSHOT + ${groupId}.firealarm.feature + pom + ${project.artifactId} + http://wso2.org + + + org.homeautomation + ${project-base-package}.plugin + 1.0.0-SNAPSHOT + + + org.homeautomation + ${project-base-package}.manager + 1.0.0-SNAPSHOT + war + + + org.homeautomation + ${project-base-package}.controller + 1.0.0-SNAPSHOT + war + + + com.h2database.wso2 + h2-database-engine + 1.2.140.wso2v3 + + + + + + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + package + + unpack + + + + + org.homeautomation + ${project-base-package}.analytics + 1.0.0-SNAPSHOT + zip + true + + ${project.build.directory}/maven-shared-archive-resources/carbonapps + + **/* + + + org.homeautomation + ${project-base-package}.ui + + ${project.version} + zip + true + + ${project.build.directory}/maven-shared-archive-resources/jaggeryapps + + **/* + + + + + + copy-jaxrs-manager-war + package + + copy + + + + + org.homeautomation + ${project-base-package}.manager + war + true + + + ${project.build.directory}/maven-shared-archive-resources/webapps/ + + firealarm_mgt.war + + + + + + copy-jaxrs-controller-war + package + + copy + + + + + org.homeautomation + ${project-base-package}.controller + war + true + + + ${project.build.directory}/maven-shared-archive-resources/webapps/ + + firealarm.war + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + create-firealarm-plugin-mgt-schema + package + + run + + + + + + + + + + + + + + + + + + + + + org.wso2.maven + carbon-p2-plugin + + + p2-feature-generation + package + + p2-feature-gen + + + ${project-base-package} + ../../../features/etc/feature.properties + + + + org.wso2.carbon.p2.category.type:server + + org.eclipse.equinox.p2.type.group:false + + + + + + org.homeautomation:${project-base-package}.plugin:1.0.0-SNAPSHOT + + + + + org.wso2.carbon.core.server:${carbon.kernel.version} + + + org.wso2.carbon.device.mgt.server:${carbon.device.mgt.version} + + + + + + + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua new file mode 100644 index 00000000..643cd05d --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua @@ -0,0 +1,65 @@ +local dht_lib = {} + +local humidity +local temperature + +local bitStream = {} + +function dht_lib.read(pin) + for j = 1, 40, 1 do + bitStream[j]=0 + end + bitlength=0 + + gpio.mode(pin, gpio.OUTPUT) + gpio.write(pin, gpio.LOW) + tmr.delay(20000) + + gpio_read=gpio.read + gpio_write=gpio.write + + gpio.mode(pin, gpio.INPUT) + + while (gpio_read(pin)==0 ) do end + + c=0 + while (gpio_read(pin)==1 and c<100) do c=c+1 end + + while (gpio_read(pin)==0 ) do end + + c=0 + while (gpio_read(pin)==1 and c<100) do c=c+1 end + + for j = 1, 40, 1 do + while (gpio_read(pin)==1 and bitlength<10 ) do + bitlength=bitlength+1 + end + bitStream[j]=bitlength + bitlength=0 + while (gpio_read(pin)==0) do end + end + + humidity = 0 + temperature = 0 + + for i = 1, 8, 1 do + if (bitStream[i+0] > 2) then + humidity = humidity+2^(8-i) + end + end + for i = 1, 8, 1 do + if (bitStream[i+16] > 2) then + temperature = temperature+2^(8-i) + end + end +end + +function dht_lib.getTemperature() + return temperature +end + +function dht_lib.getHumidity() + return humidity +end + +return dht_lib diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua new file mode 100644 index 00000000..31ece4ba --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua @@ -0,0 +1,4 @@ +tmr.alarm(0,1000,0,function() + dofile("wifi-connect.lua"); + dofile("read-sensor.lua"); +end) diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua new file mode 100644 index 00000000..99727b9e --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua @@ -0,0 +1,74 @@ +DHT= require("dht_lib") + +dht_data = 2 +buzzer = 1 +gpio.mode(buzzer, gpio.OUTPUT) +client_connected = false +m = mqtt.Client("ESP8266-"..node.chipid(), 120, "", "") + +tmr.alarm(0,10000,1,function() + DHT.read(dht_data) + + t = DHT.getTemperature() + h = DHT.getHumidity() + + if t == nil then + print("Error reading from DHTxx") + else + if (client_connected) then + m:publish("wso2/iot/${DEVICE_OWNER}/firealarm/${DEVICE_ID}/publisher", "Temperature:"..t..":Humidity:"..h, 0, 0, function(client) + print("Published> Temperature: "..t.."C Humidity: "..h.."%") + end) + else + connectMQTTClient() + end + end +end) + +function connectMQTTClient() + ip = wifi.sta.getip() + if ip == nil then + print("Waiting for network") + else + print("Client IP: "..ip) + print("Trying to connect MQTT client") + m:connect("${SERVER_IP}", 1883, 0, function(client) + client_connected = true + print("MQTT client connected") + subscribeToMQTTQueue() + end) + end +end + +function subscribeToMQTTQueue() + m:subscribe("wso2/iot/${DEVICE_OWNER}/firealarm/${DEVICE_ID}/subscriber", 0, function(client, topic, message) + print("Subscribed to MQTT Queue") + end) + m:on("message", function(client, topic, message) + print("MQTT message received") + print(message) + buzz(message == "buzzer:ON") + end) + m:on("offline", function(client) + print("Disconnected") + client_connected = false + end) +end + +function buzz(status) + buzzerOn=true + if (status) then + tmr.alarm(1,500,1,function() + if buzzerOn then + buzzerOn=false + gpio.write(buzzer, gpio.HIGH) + else + buzzerOn=true + gpio.write(buzzer, gpio.LOW) + end + end) + else + tmr.stop(1) + gpio.write(buzzer, gpio.LOW) + end +end \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties b/modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties new file mode 100644 index 00000000..5485808b --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties @@ -0,0 +1,16 @@ +#/* +# * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +# * WSO2 Inc. licenses this file to you under the Apache License, +# * Version 2.0 (the "License"); you may not use this file except +# * in compliance with the License. +# * You may obtain a copy of the License at +# * http://www.apache.org/licenses/LICENSE-2.0 +# * Unless required by applicable law or agreed to in writing, +# * software distributed under the License is distributed on an +# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# * KIND, either express or implied. See the License for the +# * specific language governing permissions and limitations +# * under the License. +# */ +templates=read-sensor.lua +zipfilename=firealarm.zip diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua new file mode 100644 index 00000000..1c4498b9 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua @@ -0,0 +1,2 @@ +wifi.setmode(wifi.STATION) +wifi.sta.config("SSID","Password") \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/build.properties b/modules/samples/firealarm/feature/feature/src/main/resources/build.properties new file mode 100644 index 00000000..a7e289bc --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/build.properties @@ -0,0 +1,18 @@ +# +custom = true diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json new file mode 100644 index 00000000..b627d223 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json @@ -0,0 +1,54 @@ +{ + "deviceType": { + "label": "Fire Alarm", + "category": "iot" + }, + "analyticStreams": [ + { + "name": "Temperature", + "table": "DEVICE_TEMPERATURE_SUMMARY", + "ui_unit": { + "name": "cdmf.unit.analytics.line-chart", + "data": [ + { + "column": { + "name": "TIME", + "label": "time", + "ui-mapping": "x-axis" + } + }, + { + "column": { + "name": "TEMPERATURE", + "label": "Temperature", + "ui-mapping": "y-axis" + } + } + ] + } + }, + { + "name": "Humidity", + "table": "DEVICE_HUMIDITY_SUMMARY", + "ui_unit": { + "name": "cdmf.unit.analytics.line-chart", + "data": [ + { + "column": { + "name": "TIME", + "label": "time", + "ui-mapping": "x-axis" + } + }, + { + "column": { + "name": "HUMIDITY", + "label": "Humidity", + "ui-mapping": "y-axis" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml new file mode 100644 index 00000000..b505b3ff --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml @@ -0,0 +1,25 @@ + + + + + + + jdbc/firealarmDM_DB + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml b/modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml new file mode 100644 index 00000000..7d219601 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml @@ -0,0 +1,48 @@ + + + + + + + org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader + + + + firealarmDM_DB + The datasource used for the this device type + + jdbc/firealarmDM_DB + + + + jdbc:h2:repository/database/firealarmDM_DB;DB_CLOSE_ON_EXIT=FALSE + + wso2carbon + wso2carbon + org.h2.Driver + 50 + 60000 + true + SELECT 1 + 30000 + + + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql new file mode 100644 index 00000000..df4b2214 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql @@ -0,0 +1,13 @@ + +-- ----------------------------------------------------- +-- Agent Database +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `firealarm_DEVICE` ( + `firealarm_DEVICE_ID` VARCHAR(45) NOT NULL , + `DEVICE_NAME` VARCHAR(100) NULL DEFAULT NULL, + `ACCESS_TOKEN` VARCHAR(50) NOT NULL, + `REFRESH_TOKEN` VARCHAR(50) NOT NULL, + PRIMARY KEY (`firealarm_DEVICE_ID`) ); + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql new file mode 100644 index 00000000..344812ba --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql @@ -0,0 +1,12 @@ + +CREATE TABLE IF NOT EXISTS `firealarm_DEVICE` ( + `firealarm_DEVICE_ID` VARCHAR(45) NOT NULL , + `DEVICE_NAME` VARCHAR(100) NULL DEFAULT NULL, + `ACCESS_TOKEN` VARCHAR(50) NOT NULL, + `REFRESH_TOKEN` VARCHAR(50) NOT NULL, + PRIMARY KEY (`firealarm_DEVICE_ID`) ) +ENGINE = InnoDB; + + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/p2.inf b/modules/samples/firealarm/feature/feature/src/main/resources/p2.inf new file mode 100644 index 00000000..f747e63a --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/p2.inf @@ -0,0 +1,16 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/device-types/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/configs/,target:${installFolder}/../../conf/device-types/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/webapps/,target:${installFolder}/../../deployment/server/webapps/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/sketches/);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/sketches/firealarm/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/agent/,target:${installFolder}/../../resources/sketches/firealarm/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/dbscripts/,target:${installFolder}/../../../dbscripts/cdm/plugins/firealarm,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/datasources/,target:${installFolder}/../../conf/datasources/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/jaggeryapps/,target:${installFolder}/../../deployment/server/jaggeryapps/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../database/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/database/,target:${installFolder}/../../database/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/carbonapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/carbonapps/,target:${installFolder}/../../deployment/server/carbonapps/,overwrite:true);\ diff --git a/modules/samples/firealarm/feature/pom.xml b/modules/samples/firealarm/feature/pom.xml new file mode 100644 index 00000000..86265530 --- /dev/null +++ b/modules/samples/firealarm/feature/pom.xml @@ -0,0 +1,37 @@ + + + + + + + org.homeautomation + firealarm + 1.0.0-SNAPSHOT + ../pom.xml + + firealarm-feature + 4.0.0 + pom + 1.0.0-SNAPSHOT + + feature + + \ No newline at end of file diff --git a/modules/samples/firealarm/pom.xml b/modules/samples/firealarm/pom.xml new file mode 100644 index 00000000..4d5c36dd --- /dev/null +++ b/modules/samples/firealarm/pom.xml @@ -0,0 +1,257 @@ + + + + + + + org.wso2 + wso2 + 1 + + org.homeautomation + firealarm + 1.0.0-SNAPSHOT + pom + 4.0.0 + http://wso2.com + + component + feature + + + + + org.eclipse.osgi + org.eclipse.osgi + ${eclipse.osgi.version} + provided + + + org.eclipse.equinox + org.eclipse.equinox.common + ${eclipse.equinox.common.version} + provided + + + org.testng + testng + ${testng.version} + + + junit + junit + + + org.beanshell + bsh + + + org.yaml + snakeyaml + + + provided + + + org.eclipse.osgi + org.eclipse.osgi.services + 3.3.100.v20120522-1822 + provided + + + org.wso2.carbon + org.wso2.carbon.logging + ${carbon.kernel.version} + + + org.apache.log4j.wso2 + log4j + + + commons-logging + commons-logging + + + org.wso2.carbon + org.wso2.carbon.bootstrap + + + provided + + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf.version} + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + ${cxf.version} + provided + + + org.apache.cxf + cxf-rt-transports-http + ${cxf.version} + provided + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + ${paho.mqtt.version} + provided + + + org.codehaus.jackson + jackson-core-asl + ${jackson.version} + + + org.codehaus.jackson + jackson-jaxrs + ${jackson.version} + + + javax + javaee-web-api + 6.0 + provided + + + javax.ws.rs + jsr311-api + ${javax.ws.rs.version} + provided + + + org.apache.httpcomponents + httpasyncclient + 4.1 + provided + + + + + + wso2.releases + WSO2 internal Repository + http://maven.wso2.org/nexus/content/repositories/releases/ + + true + daily + ignore + + + + wso2.snapshots + Apache Snapshot Repository + http://maven.wso2.org/nexus/content/repositories/snapshots/ + + true + daily + + + false + + + + wso2-nexus + WSO2 internal Repository + http://maven.wso2.org/nexus/content/groups/wso2-public/ + + true + daily + ignore + + + + + + wso2-nexus + WSO2 internal Repository + http://maven.wso2.org/nexus/content/groups/wso2-public/ + + true + daily + ignore + + + + wso2.releases + WSO2 internal Repository + http://maven.wso2.org/nexus/content/repositories/releases/ + + true + daily + ignore + + + + wso2.snapshots + WSO2 Snapshot Repository + http://maven.wso2.org/nexus/content/repositories/snapshots/ + + true + daily + + + false + + + + gcm-server-repository + GCM Server repository - GitHub + https://github.com/slorber/gcm-server-repository/raw/master/releases/ + + + + 4.4.3 + 1.1.0-SNAPSHOT + 1.1.0.SNAPSHOT + 1.0.2 + 3.0.0.wso2v1 + 3.8.1.v20120830-144521 + 2.0.4-SNAPSHOT + 2.0.4.SNAPSHOT + 1.1.1 + 2.4 + + 3.0.4.wso2v1 + 3.0.4.wso2v1 + 2.6.1 + 1.9.0 + 3.1.0.wso2v2 + 3.6.100.v20120522-1841 + 1.7 + 1.7 + org.homeautomation.firealarm + 3.8.1 + 1.4.0 + 2.4.1 + 2.3.2 + 2.6 + 1.8 + 1.7.2 + 2.5.5 + + \ No newline at end of file diff --git a/modules/samples/installer/device-deployer.xml b/modules/samples/installer/device-deployer.xml index 583a9282..4a437faa 100644 --- a/modules/samples/installer/device-deployer.xml +++ b/modules/samples/installer/device-deployer.xml @@ -32,9 +32,10 @@ http://wso2.org - + samples/connectedcup samples/currentsensor + samples/firealarm @@ -43,7 +44,6 @@ org.wso2.maven carbon-p2-plugin 1.5.3 - 2-p2-repo-generation @@ -59,12 +59,15 @@ - + org.wso2.carbon.devicemgt-plugins:org.coffeeking.connectedcup.feature:2.0.4-SNAPSHOT org.homeautomation:org.homeautomation.currentsensor.feature:2.0.4-SNAPSHOT + + org.homeautomation:org.homeautomation.firealarm.feature:1.0.0-SNAPSHOT + @@ -89,7 +92,7 @@ repository/components true - + org.coffeeking.connectedcup.feature.group 2.0.4-SNAPSHOT @@ -98,6 +101,10 @@ org.homeautomation.currentsensor.feature.group 2.0.4-SNAPSHOT + + org.homeautomation.firealarm.feature.group + 1.0.0-SNAPSHOT + diff --git a/modules/tools/cdmf-devicetype-archetype/README.md b/modules/tools/cdmf-devicetype-archetype/README.md index c72d2e90..8ee77d26 100644 --- a/modules/tools/cdmf-devicetype-archetype/README.md +++ b/modules/tools/cdmf-devicetype-archetype/README.md @@ -1,16 +1,18 @@ # cdmf-devicetype-archetype To install this maven archetype - go to this folder cdmf-devicetype-archetype + +go to this folder `cdmf-devicetype-archetype` mvn clean install To create new project - go to this folder /wso2iots-1.0.0-SNAPSHOT/samples + +go to this folder `/wso2iots-1.0.0-SNAPSHOT/samples` mvn archetype:generate -DarchetypeCatalog=local -Then select the cdmf.devicetype:cdmf-devicetype-archetype as new archetype. Then you need to provide groupId, artifactId, +Then select the `cdmf.devicetype:cdmf-devicetype-archetype` as new archetype. Then you need to provide groupId, artifactId, version, packaging, name of your device type and name for sensor as shown bellow. Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 3 @@ -30,20 +32,28 @@ version, packaging, name of your device type and name for sensor as shown bellow To install sample app into IOTS - open '`device-deployer.xml` which is located in wso2iots-1.0.0-SNAPSHOT directory - Under featureArtifacts tag add feature artifact definition as below + open `device-deployer.xml` which is located in wso2iots-1.0.0-SNAPSHOT directory + +Under modules tag add name of sample which you created as module + + samples/safeLocker + +Under featureArtifacts tag add feature artifact definition as below org.homeautomation:org.homeautomation.safeLocker.feature:1.0.0-SNAPSHOT - Under features tag add feature group definition as below +Under features tag add feature group definition as below org.homeautomation.safeLocker.feature.group 1.0.0-SNAPSHOT - mvn clean install -f device-deployer.xml - +Finally to deploy sample device type into IoT Server + + mvn clean install -f device-deployer.xml + +Note: This command should be executed place where `device-deployer.xml` is located diff --git a/modules/tools/cdmf-devicetype-archetype/pom.xml b/modules/tools/cdmf-devicetype-archetype/pom.xml index d9255a41..4f4cbfb8 100644 --- a/modules/tools/cdmf-devicetype-archetype/pom.xml +++ b/modules/tools/cdmf-devicetype-archetype/pom.xml @@ -28,8 +28,8 @@ cdmf.devicetype cdmf-devicetype-archetype 1.0.0-SNAPSHOT - Archetype of WSO2 CDMF Device Type - Archetype of WSO2 CDMF Device Type + WSO2 CDMF Device Type Archetype + WSO2 CDMF Device Type Archetype maven-archetype WSO2 Inc.