diff --git a/.codacy.yml b/.codacy.yml index 458d2f39617..766d982a8f6 100644 --- a/.codacy.yml +++ b/.codacy.yml @@ -7,11 +7,9 @@ exclude_paths: - 'frontend/express/public/localization/**' - 'frontend/express/public/fonts/**' - 'frontend/express/public/images/**' - - 'frontend/express/public/stylesheets/amaranjs/**' - 'frontend/express/public/stylesheets/font-awesome/**' - 'frontend/express/public/stylesheets/ionicons/**' - 'frontend/express/public/stylesheets/material/**' - - 'frontend/express/public/stylesheets/selectize/**' - 'bin/backup/**' - 'bin/upgrade/**' - 'bin/**' diff --git a/.eslintrc.json b/.eslintrc.json index 8948a31958e..162dc7b5913 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,7 @@ { "extends": "eslint:recommended", "rules": { + // "quotes": ["warn", "single", { "avoidEscape": true }], "require-atomic-updates": "off", "block-spacing": [ "error", @@ -118,6 +119,240 @@ "unicode-bom": [ "error", "never" + ], + "no-restricted-properties": [ + "warn", + { + "object": "Promise", + "property": "map", + "message": "Bluebird-specific method 'Promise.map' detected. Suggestion: use native arrays with Promise.all or a library like 'p-map'." + }, + { + "object": "Promise", + "property": "reduce", + "message": "Bluebird-specific method 'Promise.reduce' detected. Suggestion: use Array.reduce plus async/await or a concurrency library." + }, + { + "object": "Promise", + "property": "filter", + "message": "Bluebird-specific method 'Promise.filter' detected. Suggestion: use Array.filter plus async/await or a concurrency library." + }, + { + "object": "Promise", + "property": "each", + "message": "Bluebird-specific method 'Promise.each' detected. Suggestion: use a for-loop/forEach with async/await." + }, + { + "object": "Promise", + "property": "props", + "message": "Bluebird-specific method 'Promise.props' detected. Suggestion: use Promise.all with Object.entries or a custom approach." + }, + { + "object": "Promise", + "property": "join", + "message": "Bluebird-specific method 'Promise.join' detected. Suggestion: use Promise.all([...]) and destructuring in .then." + }, + { + "object": "Promise", + "property": "try", + "message": "Bluebird-specific method 'Promise.try' detected. Suggestion: use a try/catch block or an async function." + }, + { + "object": "Promise", + "property": "attempt", + "message": "Bluebird-specific method 'Promise.attempt' detected. Suggestion: same as 'Promise.try'—use try/catch or async." + }, + { + "object": "Promise", + "property": "method", + "message": "Bluebird-specific method 'Promise.method' detected. Suggestion: define an async function or return a native Promise." + }, + { + "object": "Promise", + "property": "promisify", + "message": "Bluebird-specific method 'Promise.promisify' detected. Suggestion: use native 'util.promisify' or wrap in a new Promise." + }, + { + "object": "Promise", + "property": "promisifyAll", + "message": "Bluebird-specific method 'Promise.promisifyAll' detected. Suggestion: consider 'util.promisify' for each function or a similar library." + }, + { + "object": "Promise", + "property": "fromCallback", + "message": "Bluebird-specific method 'Promise.fromCallback' detected. Suggestion: use new Promise(...) or 'util.promisify'." + }, + { + "object": "Promise", + "property": "coroutine", + "message": "Bluebird-specific method 'Promise.coroutine' detected. Suggestion: use native async/await." + }, + { + "object": "Promise", + "property": "spawn", + "message": "Bluebird-specific method 'Promise.spawn' detected. Suggestion: use native async/await." + }, + { + "object": "Promise", + "property": "using", + "message": "Bluebird-specific method 'Promise.using' detected. Suggestion: use try/finally or a resource-management library." + }, + { + "object": "Promise", + "property": "disposer", + "message": "Bluebird-specific method 'Promise.disposer' detected. Suggestion: use try/finally or a resource-management library." + }, + { + "object": "Promise", + "property": "settle", + "message": "Bluebird-specific method 'Promise.settle' detected. Suggestion: use native 'Promise.allSettled'." + }, + + /* ---------- Same methods on the Bluebird object itself ---------- */ + { + "object": "Bluebird", + "property": "map", + "message": "Bluebird-specific method 'Bluebird.map' detected. Suggestion: use array mapping + Promise.all or 'p-map'." + }, + { + "object": "Bluebird", + "property": "reduce", + "message": "Bluebird-specific method 'Bluebird.reduce' detected. Suggestion: use array reduce + async/await or concurrency library." + }, + { + "object": "Bluebird", + "property": "filter", + "message": "Bluebird-specific method 'Bluebird.filter' detected. Suggestion: use array filter + async/await or concurrency library." + }, + { + "object": "Bluebird", + "property": "each", + "message": "Bluebird-specific method 'Bluebird.each' detected. Suggestion: use a for-loop or forEach + async/await." + }, + { + "object": "Bluebird", + "property": "props", + "message": "Bluebird-specific method 'Bluebird.props' detected. Suggestion: use Promise.all with object entries or a custom approach." + }, + { + "object": "Bluebird", + "property": "join", + "message": "Bluebird-specific method 'Bluebird.join' detected. Suggestion: use Promise.all([...]) and destructuring." + }, + { + "object": "Bluebird", + "property": "try", + "message": "Bluebird-specific method 'Bluebird.try' detected. Suggestion: use a try/catch block or async function." + }, + { + "object": "Bluebird", + "property": "attempt", + "message": "Bluebird-specific method 'Bluebird.attempt' detected. Suggestion: use a try/catch block or async function." + }, + { + "object": "Bluebird", + "property": "method", + "message": "Bluebird-specific method 'Bluebird.method' detected. Suggestion: define an async function or return a native Promise." + }, + { + "object": "Bluebird", + "property": "promisify", + "message": "Bluebird-specific method 'Bluebird.promisify' detected. Suggestion: use native 'util.promisify' or wrap in a new Promise." + }, + { + "object": "Bluebird", + "property": "promisifyAll", + "message": "Bluebird-specific method 'Bluebird.promisifyAll' detected. Suggestion: consider 'util.promisify' or a similar library." + }, + { + "object": "Bluebird", + "property": "fromCallback", + "message": "Bluebird-specific method 'Bluebird.fromCallback' detected. Suggestion: use new Promise(...) or 'util.promisify'." + }, + { + "object": "Bluebird", + "property": "coroutine", + "message": "Bluebird-specific method 'Bluebird.coroutine' detected. Suggestion: use native async/await." + }, + { + "object": "Bluebird", + "property": "spawn", + "message": "Bluebird-specific method 'Bluebird.spawn' detected. Suggestion: use native async/await." + }, + { + "object": "Bluebird", + "property": "using", + "message": "Bluebird-specific method 'Bluebird.using' detected. Suggestion: use try/finally or a resource-management library." + }, + { + "object": "Bluebird", + "property": "disposer", + "message": "Bluebird-specific method 'Bluebird.disposer' detected. Suggestion: use try/finally or a resource-management library." + }, + { + "object": "Bluebird", + "property": "settle", + "message": "Bluebird-specific method 'Bluebird.settle' detected. Suggestion: use native 'Promise.allSettled'." + } + ], + "no-restricted-syntax": [ + "warn", + { + "selector": "CallExpression[callee.property.name='tap']", + "message": "Bluebird-specific instance method '.tap()' detected. Suggestion: use '.then(value => { ...; return value; })'." + }, + { + "selector": "CallExpression[callee.property.name='tapCatch']", + "message": "Bluebird-specific instance method '.tapCatch()' detected. Suggestion: use '.catch(error => { ...; throw error; })'." + }, + { + "selector": "CallExpression[callee.property.name='spread']", + "message": "Bluebird-specific instance method '.spread()' detected. Suggestion: use '.then(([a, b]) => ... )' with array destructuring." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.property.name='bind'][callee.object.name=/^(Promise|Bluebird|BPromise)$/]", + "message": "Bluebird-specific '.bind()' detected on a Bluebird promise. Suggestion: manually bind 'this' or use arrow functions." + }, + { + "selector": "CallExpression[callee.property.name='delay']", + "message": "Bluebird-specific instance method '.delay()' detected. Suggestion: use setTimeout() or a library (e.g., p-delay)." + }, + { + "selector": "CallExpression[callee.property.name='timeout']", + "message": "Bluebird-specific instance method '.timeout()' detected. Suggestion: use p-timeout or similar library." + }, + { + "selector": "CallExpression[callee.property.name='return']", + "message": "Bluebird-specific instance method '.return()' detected. Suggestion: use '.then(() => someValue)' or rewrite chain." + }, + { + "selector": "CallExpression[callee.property.name='throw']", + "message": "Bluebird-specific instance method '.throw()' detected. Suggestion: use '.then(() => { throw error; })'." + }, + { + "selector": "CallExpression[callee.property.name='asCallback']", + "message": "Bluebird-specific instance method '.asCallback()' detected. Suggestion: use 'util.callbackify' or rewrite manually." + }, + { + "selector": "CallExpression[callee.property.name='nodeify']", + "message": "Bluebird-specific instance method '.nodeify()' detected. Suggestion: use 'util.callbackify' or rewrite manually." + }, + { + "selector": "CallExpression[callee.property.name='reflect']", + "message": "Bluebird-specific instance method '.reflect()' detected. Suggestion: use 'Promise.allSettled' or custom handling." + }, + { + "selector": "CallExpression[callee.property.name='caught']", + "message": "Bluebird-specific instance method '.caught()' detected. Suggestion: use '.catch()' with condition or separate logic." + }, + { + "selector": "CallExpression[callee.property.name='catchReturn']", + "message": "Bluebird-specific instance method '.catchReturn()' detected. Suggestion: use '.catch(err => fallbackValue)' or similar." + }, + { + "selector": "CallExpression[callee.property.name='catchThrow']", + "message": "Bluebird-specific instance method '.catchThrow()' detected. Suggestion: use '.catch(err => { throw newError; })'." + } ] }, "overrides": [ @@ -142,28 +377,16 @@ { "files": [ "plugins/content/frontend/content-blocks/**/*.js", - "plugins/journey_engine/frontend/builder/**/*.js", - "plugins/content/frontend/content-blocks/**/*.vue", - "plugins/journey_engine/frontend/builder/**/*.vue" - ], - "plugins": [ - "vue", - "@stylistic" + "plugins/journey_engine/frontend/builder/**/*.js" ], "extends": [ - "eslint:recommended", - "plugin:vue/vue3-essential", - "plugin:vue/vue3-strongly-recommended", - "plugin:vue/vue3-recommended" + "eslint:recommended" ], "rules": { - // override these post initial content release, to make them fit with countly convention "no-console": ["error"], - "@stylistic/quotes": ["error", "single"], - "@stylistic/quote-props": ["error", "as-needed"], - "no-unused-vars": "off", - "vue/no-unused-vars": ["error", { - "ignorePattern": "^_" + "no-unused-vars": ["error", { + "argsIgnorePattern": "^_", // unused function args + "varsIgnorePattern": "^_" // unused variables }] }, "parserOptions": { diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6e9af8aa073..7101e68dc5a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,318 +1,443 @@ version: 2 updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 - reviewers: - - ar2rsawseen - assignees: - - ar2rsawseen - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/alerts" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/assistant" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/browser" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/compare" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/compliance-hub" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/consolidate" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/crashes" - schedule: - interval: daily - open-pull-requests-limit: 10 - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/dashboards" - schedule: - interval: daily - open-pull-requests-limit: 10 - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/data_migration" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/data-manager" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/dbviewer" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/density" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/desktop" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/enterpriseinfo" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/errorlogs" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/hooks" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/locale" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/logger" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/mobile" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/onboarding" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/plugin-upload" - schedule: - interval: daily - open-pull-requests-limit: 10 - reviewers: - - Cookiezaurs - assignees: - - Cookiezaurs - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/plugins" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/populator" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/push" - schedule: - interval: daily - open-pull-requests-limit: 10 - reviewers: - - cihadtekin - assignees: - - cihadtekin - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/recaptcha" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/remote-config" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/reports" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/server-stats" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/slipping-away-users" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/sources" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/star-rating" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/system-utility" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/systemlogs" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/times-of-day" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/two-factor-auth" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/views" - schedule: - interval: daily - open-pull-requests-limit: 10 - reviewers: - - Cookiezaurs - assignees: - - Cookiezaurs - labels: - - dependencies - versioning-strategy: increase-if-necessary -- package-ecosystem: npm - directory: "/plugins/web" - schedule: - interval: daily - open-pull-requests-limit: 10 - labels: - - dependencies - versioning-strategy: increase-if-necessary + # NPM dependencies + - package-ecosystem: npm + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + reviewers: + - ar2rsawseen + assignees: + - ar2rsawseen + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/ui-tests" + schedule: + interval: daily + open-pull-requests-limit: 10 + reviewers: + - can-angun + assignees: + - can-angun + labels: + - dependencies + versioning-strategy: increase-if-necessary + + # API utilities + - package-ecosystem: npm + directory: "/api/utils/countly-request" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/api/utils/countly-root" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + # Scripts + - package-ecosystem: npm + directory: "/bin/scripts/device_list" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/bin/scripts/timezones" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + # Plugins + - package-ecosystem: npm + directory: "/plugins/alerts" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/browser" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/compare" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/compliance-hub" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/consolidate" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/crashes" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/dashboards" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/data_migration" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/data-manager" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/dbviewer" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/density" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/desktop" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/enterpriseinfo" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/errorlogs" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/guides" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/hooks" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/ip_store" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/locale" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/logger" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/mobile" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/onboarding" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/plugins" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/populator" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/push" + schedule: + interval: daily + open-pull-requests-limit: 10 + reviewers: + - cihadtekin + assignees: + - cihadtekin + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/recaptcha" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/remote-config" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/reports" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/sdk" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/server-stats" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/slipping-away-users" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/sources" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/star-rating" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/system-utility" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/systemlogs" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/times-of-day" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/two-factor-auth" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/views" + schedule: + interval: daily + open-pull-requests-limit: 10 + reviewers: + - Cookiezaurs + assignees: + - Cookiezaurs + labels: + - dependencies + versioning-strategy: increase-if-necessary + + - package-ecosystem: npm + directory: "/plugins/web" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + versioning-strategy: increase-if-necessary + + # Keep GitHub Actions up to date + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + - "github-actions" + reviewers: + - "ar2rsawseen" + groups: + actions: + patterns: + - "*" + + # Keep Docker dependencies up to date + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + - "docker" + reviewers: + - "ar2rsawseen" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7b673659d1a..e650cdacc1d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -37,11 +37,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -52,7 +52,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -66,4 +66,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 73a66a78ecc..6deaa4f28db 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,7 +19,7 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Enable command line shell: bash @@ -45,16 +45,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 with: push: true file: ./Dockerfile-core diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 48f66a2d308..d953ad414ac 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set output id: vars @@ -26,13 +26,13 @@ jobs: echo ${{ steps.vars.outputs.tag }} - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 with: context: . push: true @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set output id: vars @@ -57,13 +57,13 @@ jobs: echo ${{ steps.vars.outputs.tag }} - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 with: push: true file: ./Dockerfile-api @@ -74,7 +74,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set output id: vars @@ -88,13 +88,13 @@ jobs: echo ${{ steps.vars.outputs.tag }} - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 with: push: true file: ./Dockerfile-frontend @@ -105,7 +105,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set output id: vars @@ -119,13 +119,13 @@ jobs: echo ${{ steps.vars.outputs.tag }} - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 with: push: true file: ./Dockerfile-core diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1c5a2fcecd0..d2d6c050bc5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Copy code shell: bash @@ -96,7 +96,7 @@ jobs: COUNTLY_CONFIG_API_PREVENT_JOBS: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Copy code shell: bash @@ -153,7 +153,7 @@ jobs: COUNTLY_CONFIG_API_PREVENT_JOBS: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Prepare tests shell: bash @@ -205,7 +205,7 @@ jobs: COUNTLY_CONFIG_API_PREVENT_JOBS: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Copy code shell: bash @@ -263,7 +263,7 @@ jobs: COUNTLY_CONFIG_API_PREVENT_JOBS: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install Chrome shell: bash @@ -275,7 +275,12 @@ jobs: - name: Copy code shell: bash - run: cp -rf ./* /opt/countly + run: | + rm -rf /opt/countly/frontend + rm -rf /opt/countly/plugins/old-ui-compatibility + cp -rf ./* /opt/countly + cp /opt/countly/frontend/express/config.sample.js /opt/countly/frontend/express/config.js + cp /opt/countly/frontend/express/public/javascripts/countly/countly.config.sample.js /opt/countly/frontend/express/public/javascripts/countly/countly.config.js - name: Prepare files to use correct MongoDB host shell: bash @@ -346,7 +351,7 @@ jobs: COUNTLY_CONFIG_API_PREVENT_JOBS: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install Chrome shell: bash @@ -358,8 +363,13 @@ jobs: - name: Copy code shell: bash - run: cp -rf ./* /opt/countly - + run: | + rm -rf /opt/countly/frontend + rm -rf /opt/countly/plugins/old-ui-compatibility + cp -rf ./* /opt/countly + cp /opt/countly/frontend/express/config.sample.js /opt/countly/frontend/express/config.js + cp /opt/countly/frontend/express/public/javascripts/countly/countly.config.sample.js /opt/countly/frontend/express/public/javascripts/countly/countly.config.js + - name: Prepare files to use correct MongoDB host shell: bash run: "sed -i 's/mongosh --quiet/mongosh --host mongodb --quiet/' /opt/countly/bin/backup/import_events.sh && sed -i 's/mongoimport --db/mongoimport --host mongodb --db/' /opt/countly/bin/backup/import_events.sh" diff --git a/.github/workflows/release_notice.yml b/.github/workflows/release_notice.yml index 0f959e9b5a9..1ed20567cf0 100644 --- a/.github/workflows/release_notice.yml +++ b/.github/workflows/release_notice.yml @@ -14,7 +14,7 @@ jobs: run: echo "$GITHUB_CONTEXT" - name: Send custom JSON data to Slack workflow id: slack - uses: slackapi/slack-github-action@v1.23.0 + uses: slackapi/slack-github-action@v2.1.0 with: # This data can be any valid JSON from a previous step in the GitHub Action payload: | @@ -28,7 +28,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_RELEASE }} - name: Send custom JSON data to Discord - uses: sarisia/actions-status-discord@v1.13.0 + uses: sarisia/actions-status-discord@v1.15.3 with: webhook: ${{ secrets.DISCORD_WEBHOOK_URL }} nodetail: true diff --git a/.github/workflows/stable-je-deploy.yml b/.github/workflows/stable-je-deploy.yml index 6393bd70357..e7fbe5ab92e 100644 --- a/.github/workflows/stable-je-deploy.yml +++ b/.github/workflows/stable-je-deploy.yml @@ -19,7 +19,7 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Deploy server shell: bash diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000000..4af22ddd479 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged --verbose \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f5f8a15156..e9c843f31fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,35 @@ ## Version 25.03.x +Enterprise Fixes: +- [content] Asset URL was wrongly constructed when user switches between apps +- [ab-testing] Updates + - Do not wait for result calculation when requesting experiments + - Do not calculate result for completed experiments + +Dependencies: +- Bump lint-staged from 15.5.2 to 16.0.0 +- Bump nodemailer from 6.10.1 to 7.0.3 +- Bump puppeteer from 24.8.0 to 24.8.2 +- Bump sass from 1.87.0 to 1.88.0 +- Bump semver from 7.7.1 to 7.7.2 +- Bump supertest from 7.1.0 to 7.1.1 + +## Version 25.03.5 Fixes: +- [core] Changes for event omit script to validate data in new model and use countly-request. +- [core] Changes to top events job. Fetching data from aggregated event totals. +- [crashes] Fix unescaped SDK logs - [feedback] Uniformize drawer internal name input texts +- [feedback] Uniformize feedback widgets status tag +- [localization] Fixed grammatical errors - [star-rating] Added missing columns to Rating Widgets table edit +- [star-rating] Allow bulk update of widget status - [star-rating] Fix rating score and responses table sorting - [ui] Fix alignment of drawers title and close icon +- [UI] Remove white background from input character amount suffix + +Enterprise Fixes: +- [heatmaps] Get heatmap data from new drill events collection +- [retention] Fixed report loading Dependencies: - Bump countly-sdk-web from 25.1.0 to 25.4.0 diff --git a/Gruntfile.js b/Gruntfile.js index 4c7c1a98986..3331af6f83f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,21 +14,8 @@ module.exports = function(grunt) { dom: { src: [ 'frontend/express/public/javascripts/dom/jquery/jquery.js', - 'frontend/express/public/javascripts/dom/jquery.form.js', - 'frontend/express/public/javascripts/dom/tipsy/jquery.tipsy.js', - 'frontend/express/public/javascripts/dom/jquery.noisy.min.js', - 'frontend/express/public/javascripts/dom/jquery.sticky.headers.js', - 'frontend/express/public/javascripts/dom/jqueryui/jquery-ui.js', - 'frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js', 'frontend/express/public/javascripts/dom/gridstack/gridstack-h5.js', - 'frontend/express/public/javascripts/dom/slimScroll.min.js', - 'frontend/express/public/javascripts/dom/jquery.easing.1.3.js', - 'frontend/express/public/javascripts/dom/dataTables/js/jquery.dataTables.js', - 'frontend/express/public/javascripts/dom/dataTables/js/ZeroClipboard.js', - 'frontend/express/public/javascripts/dom/dataTables/js/TableTools.js', 'frontend/express/public/javascripts/dom/pace/pace.min.js', - 'frontend/express/public/javascripts/dom/drop/tether.min.js', - 'frontend/express/public/javascripts/dom/drop/drop.min.js' ], dest: 'frontend/express/public/javascripts/min/countly.dom.concat.js' }, @@ -39,22 +26,13 @@ module.exports = function(grunt) { 'frontend/express/public/javascripts/utils/lodash.merge.js', 'frontend/express/public/javascripts/utils/prefixfree.min.js', 'frontend/express/public/javascripts/utils/moment/moment-with-locales.min.js', - 'frontend/express/public/javascripts/utils/handlebars.js', 'frontend/express/public/javascripts/utils/backbone-min.js', 'frontend/express/public/javascripts/utils/jquery.i18n.properties.js', - 'frontend/express/public/javascripts/utils/jstz.min.js', 'frontend/express/public/javascripts/utils/store+json2.min.js', 'frontend/express/public/javascripts/utils/jquery.idle-timer.js', - 'frontend/express/public/javascripts/utils/textcounter.min.js', 'frontend/express/public/javascripts/utils/initialAvatar.js', - 'frontend/express/public/javascripts/utils/jquery.amaran.min.js', - 'frontend/express/public/javascripts/utils/jquery.titlealert.js', - 'frontend/express/public/javascripts/utils/jquery.hoverIntent.minified.js', - 'frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.js', 'frontend/express/public/javascripts/utils/highlight/highlight.pack.js', - 'frontend/express/public/javascripts/utils/dropzone.js', 'frontend/express/public/javascripts/utils/webfont.js', - 'frontend/express/public/javascripts/utils/selectize.min.js', 'frontend/express/public/javascripts/utils/leaflet.js', 'frontend/express/public/javascripts/utils/js-deep-equals.unsorted.min.js', 'frontend/express/public/javascripts/utils/polyfill/es6-promise.auto.min.js', @@ -77,16 +55,8 @@ module.exports = function(grunt) { 'frontend/express/public/javascripts/utils/vue/vue-json-pretty.min.js', 'frontend/express/public/javascripts/utils/jquery.xss.js', 'frontend/express/public/javascripts/countly/countly.common.js', - 'frontend/express/public/javascripts/utils/simpleUpload.min.js', - 'frontend/express/public/javascripts/utils/jsoneditor/codemirror.js', - 'frontend/express/public/javascripts/utils/jsoneditor/javascript.min.js', - 'frontend/express/public/javascripts/utils/jsoneditor/json2.js', - 'frontend/express/public/javascripts/utils/jsoneditor/jsonlint.js', - 'frontend/express/public/javascripts/utils/jsoneditor/minify.json.js', - 'frontend/express/public/javascripts/utils/jsoneditor/jsoneditor.js', 'frontend/express/public/javascripts/utils/Sortable.min.js', 'frontend/express/public/javascripts/utils/vue/vuedraggable.umd.min.js', - 'frontend/express/public/javascripts/utils/countly.checkbox.js', 'frontend/express/public/javascripts/utils/lodash.mergeWith.js', 'frontend/express/public/javascripts/utils/element-tiptap.umd.min.js' ], @@ -94,21 +64,6 @@ module.exports = function(grunt) { }, visualization: { src: [ - 'frontend/express/public/javascripts/visualization/jquery.peity.min.js', - 'frontend/express/public/javascripts/visualization/jquery.sparkline.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.spline.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.crosshair.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.orderBars.js', - 'frontend/express/public/javascripts/visualization/flot/jquery.flot.navigate.js', - 'frontend/express/public/javascripts/visualization/gauge.min.js', - 'frontend/express/public/javascripts/visualization/d3/d3.min.js', - 'frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js', - 'frontend/express/public/javascripts/visualization/rickshaw/rickshaw.x.axis.js' ], dest: 'frontend/express/public/javascripts/min/countly.visualization.concat.js' }, @@ -159,7 +114,6 @@ module.exports = function(grunt) { 'frontend/express/public/javascripts/countly/vue/components/progress.js', 'frontend/express/public/javascripts/countly/vue/directives/scroll-shadow.js', 'frontend/express/public/javascripts/countly/vue/legacy.js', - 'frontend/express/public/javascripts/countly/countly.vue.legacy.js', 'frontend/express/public/javascripts/countly/countly.token.manager.js', 'frontend/express/public/javascripts/countly/countly.version.history.js', 'frontend/express/public/javascripts/countly/countly.analytics.js', @@ -229,18 +183,10 @@ module.exports = function(grunt) { 'frontend/express/public/stylesheets/main.min.css': [ 'frontend/express/public/stylesheets/main.css', 'frontend/express/public/stylesheets/vue/clyvue.css', - 'frontend/express/public/stylesheets/vue/vue-json-pretty.css', - 'frontend/express/public/stylesheets/amaranjs/amaran.min.css', - 'frontend/express/public/stylesheets/selectize/selectize.css', 'frontend/express/public/stylesheets/leaflet/leaflet.css', - 'frontend/express/public/stylesheets/jsoneditor/codemirror.css', - 'frontend/express/public/stylesheets/countly-checkbox/countly.checkbox.css', - 'frontend/express/public/javascripts/dom/tipsy/tipsy.css', + 'frontend/express/public/stylesheets/vue/vue-json-pretty.css', 'frontend/express/public/javascripts/dom/gridstack/gridstack.css', - 'frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.css', 'frontend/express/public/javascripts/dom/pace/pace-theme-flash.css', - 'frontend/express/public/javascripts/dom/drop/drop-theme-countly.min.css', - 'frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.css', 'frontend/express/public/stylesheets/bulma/bulma-custom.css', 'frontend/express/public/stylesheets/styles/manifest2.css', 'frontend/express/public/stylesheets/vue/element-tiptap.css', diff --git a/api/jobs/topEvents.js b/api/jobs/topEvents.js index d5043b2235e..ad394794600 100644 --- a/api/jobs/topEvents.js +++ b/api/jobs/topEvents.js @@ -44,29 +44,49 @@ class TopEventsJob extends job.Job { } /** - * async - * Get events count. - * @param {Object} params - getEventsCount object - * @param {String} params.collectionNameEvents - event collection name - * @param {Object} params.ob - it contains all necessary info - * @param {string} params.event - event name - * @param {Object} params.data - dummy event data - * @returns {Promise.} true. + * + * @param {object} params - params object + * @param {object} data - object where to collect data + * @param {boolean} previous - if fetching for previous period + * @returns {Promise} promise */ - async getEventsCount(params) { - const { collectionNameEvents, ob, data, event } = params; + async fetchEventTotalCounts(params, data, previous) { + let collectionName = "all"; + params.qstring.segmentation = "key"; return await new Promise((resolve) => { - countlyApi.data.fetch.getTimeObjForEvents(collectionNameEvents, ob, (doc) => { + countlyApi.data.fetch.getTimeObjForEvents("events_data", params, {'id_prefix': params.app_id + "_" + collectionName + '_'}, function(doc) { countlyEvents.setDb(doc || {}); - const countProp = countlyEvents.getNumber("c", true); - const sumProp = countlyEvents.getNumber("s", true); - const durationProp = countlyEvents.getNumber("dur", true); - data[event] = {}; - data[event].data = { - count: countProp, - sum: sumProp, - duration: durationProp - }; + + var dd = countlyEvents.getSegmentedData(params.qstring.segmentation); + for (var z = 0; z < dd.length;z++) { + var key = dd[z]._id; + data[key] = data[key] || {}; + data[key].data = data[key].data || {}; + data[key].data.count = data[key].data.count || {"total": 0, "prev-total": 0, "change": "NA", "trend": "u"}; + if (previous) { + data[key].data.count["prev-total"] = dd[z].c; + } + else { + data[key].data.count.total = dd[z].c; + } + + data[key].data.sum = data[key].data.sum || {"total": 0, "prev-total": 0, "change": "NA", "trend": "u"}; + if (previous) { + data[key].data.sum["prev-total"] = dd[z].s; + } + else { + data[key].data.sum.total = dd[z].s; + } + + data[key].data.duration = data[key].data.duration || {"total": 0, "prev-total": 0, "change": "NA", "trend": "u"}; + if (previous) { + data[key].data.duration["prev-total"] = dd[z].dur; + } + else { + data[key].data.duration.total = dd[z].dur; + } + } + //data.all = countlyEvents.getSegmentedData(params.qstring.segmentation); resolve(true); }); }); @@ -204,10 +224,20 @@ class TopEventsJob extends job.Job { let prevTotalSum = 0; let totalDuration = 0; let prevTotalDuration = 0; - for (const event of eventMap) { - log.d(" getting event data for event: " + event + " (" + period + ")"); - const collectionNameEvents = this.eventsCollentions({ event, id: app._id }); - await this.getEventsCount({ collectionNameEvents, ob, data, event }); + + //Fetching totals for this period + await this.fetchEventTotalCounts({ app_id: app._id, appTimezone: app.timezone, qstring: { period: period } }, data, false); + var period2 = countlyCommon.getPeriodObj({appTimezone: app.timezone, qstring: {}}, period); + var newPeriod = [period2.start - (period2.end - period2.start), period2.start]; + //Fetching totals for previous period + await this.fetchEventTotalCounts({ app_id: app._id, appTimezone: app.timezone, qstring: { period: newPeriod } }, data, true); + + + for (var event in data) { + //Calculating trend + var trend = countlyCommon.getPercentChange(data[event].data.count["prev-total"], data[event].data.count.total); + data[event].data.count.change = trend.percent; + data[event].data.count.trend = trend.trend; totalCount += data[event].data.count.total; prevTotalCount += data[event].data.count["prev-total"]; totalSum += data[event].data.sum.total; diff --git a/api/utils/countly-request/package-lock.json b/api/utils/countly-request/package-lock.json index 57af8f88f04..d69a3c91495 100644 --- a/api/utils/countly-request/package-lock.json +++ b/api/utils/countly-request/package-lock.json @@ -13,10 +13,39 @@ "hpagent": "^1.2.0" }, "devDependencies": { - "mocha": "^10.8.2", + "mocha": "^11.1.0", "should": "^13.2.3" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -76,23 +105,17 @@ "@types/node": "*" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -110,19 +133,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -136,15 +146,6 @@ "dev": true, "license": "MIT" }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -155,18 +156,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -239,41 +228,97 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/clone-response": { @@ -305,6 +350,21 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", @@ -378,11 +438,19 @@ "node": ">=0.3.1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" }, "node_modules/end-of-stream": { "version": "1.4.4", @@ -393,10 +461,11 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -413,18 +482,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -450,25 +507,21 @@ "flat": "cli.js" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/get-caller-file": { @@ -476,6 +529,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -495,36 +549,40 @@ } }, "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=12" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 6" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/got": { @@ -594,76 +652,16 @@ "node": ">=10.19.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -685,6 +683,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -749,6 +770,13 @@ "node": ">=8" } }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -770,32 +798,42 @@ "node": ">=10" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mocha": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.2.2.tgz", + "integrity": "sha512-VlSBxrPYHK4YNOEbFdkCxHQbZMoNzBkoPprqtZRW6311EUF/DlSxoycE2e/2NtRk4WKkIXzyrXDTrlikJMWgbw==", "dev": true, "license": "MIT", "dependencies": { - "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", + "chokidar": "^4.0.1", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", - "glob": "^8.1.0", + "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", + "picocolors": "^1.1.1", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" }, "bin": { @@ -803,7 +841,7 @@ "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/ms": { @@ -812,15 +850,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", @@ -878,6 +907,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -887,18 +923,40 @@ "node": ">=8" } }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -930,15 +988,17 @@ } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": ">=8.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/require-directory": { @@ -946,6 +1006,7 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -997,6 +1058,29 @@ "randombytes": "^2.1.0" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/should": { "version": "13.2.3", "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", @@ -1051,11 +1135,44 @@ "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", "dev": true }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1065,11 +1182,59 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1077,6 +1242,16 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1104,16 +1279,20 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { - "is-number": "^7.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=8.0" + "node": ">= 8" } }, "node_modules/workerpool": { @@ -1124,10 +1303,30 @@ "license": "Apache-2.0" }, "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1140,6 +1339,64 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1150,36 +1407,38 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { @@ -1197,6 +1456,51 @@ "node": ">=10" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/api/utils/countly-request/package.json b/api/utils/countly-request/package.json index 3c5080bdb45..df7ab76f5a2 100644 --- a/api/utils/countly-request/package.json +++ b/api/utils/countly-request/package.json @@ -18,7 +18,7 @@ "hpagent": "^1.2.0" }, "devDependencies": { - "mocha": "^10.8.2", + "mocha": "^11.1.0", "should": "^13.2.3" } } diff --git a/bin/scripts/license_installer.js b/bin/scripts/license_installer.js index f12451914a8..be005f0cf87 100755 --- a/bin/scripts/license_installer.js +++ b/bin/scripts/license_installer.js @@ -58,7 +58,10 @@ pluginManager.dbConnection(DB).then(async(countlyDb) => { try { let apiDomain = (await countlyDb.collection('plugins').findOne({ _id: 'plugins' }, { _id: 0, 'api.domain': 1 })).api.domain.split('//')[1]; apiDomain = apiDomain.replace(/(^\w+:|^)\/\//, '').replace(/\/$/, ''); - let { body } = await httpRequest(`https://stats.count.ly/o/license-generator/list?app_id=633b1796ff6957bdc9360aef&iDisplayStart=0&iDisplayLength=1&iSortCol_0=3&sSortDir_0=desc&query={"domain":{"$regex":"${apiDomain}"}}`, { method: 'POST' }, { auth_token: auth_token }); + if (apiDomain.indexOf("www.") === 0) { + apiDomain = apiDomain.substring(4); + } + let { body } = await httpRequest(`https://stats.count.ly/o/license-generator/list?app_id=633b1796ff6957bdc9360aef&iDisplayStart=0&iDisplayLength=1&iSortCol_0=3&sSortDir_0=desc&query={"domain":{"$regex":"^${apiDomain}"}}`, { method: 'POST' }, { auth_token: auth_token }); body = JSON.parse(body); let licenseId = ''; if (body?.aaData?.length) { diff --git a/bin/scripts/localization/clean-all-plugins.sh b/bin/scripts/localization/clean-all-plugins.sh new file mode 100755 index 00000000000..128e4066412 --- /dev/null +++ b/bin/scripts/localization/clean-all-plugins.sh @@ -0,0 +1,236 @@ +#!/bin/bash + +# Script to clean unused localization keys from all Countly plugins +# This script iterates through each plugin in the plugins directory +# and runs the clean-localization.sh script on each one + +# Don't exit on error, we want to process all plugins even if some fail +set +e + +# Correct path detection +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +COUNTLY_ROOT="$(cd "$SCRIPT_DIR/../../.." &> /dev/null && pwd )" # Go up three levels from bin/scripts/localization to countly root +PLUGINS_DIR="$COUNTLY_ROOT/plugins" +CLEAN_SCRIPT="$SCRIPT_DIR/clean-localization.sh" + +# Print paths for debugging +echo "COUNTLY_ROOT: $COUNTLY_ROOT" +echo "PLUGINS_DIR: $PLUGINS_DIR" + +# Default values +APPLY_CHANGES=false +SKIP_CONFIRMATION=false +VERBOSE=false +INCLUDE_PATTERN="" +EXCLUDE_PATTERN="" +DEBUG=false + +# Print usage +function print_usage { + echo "Usage: $0 [options]" + echo + echo "Options:" + echo " --apply Automatically apply changes to the original properties files" + echo " --force Skip confirmation when applying changes" + echo " --verbose Show more detailed output" + echo " --debug Show debug information about the script execution" + echo " --include=PATTERN Only process plugins matching the pattern (grep -E format)" + echo " --exclude=PATTERN Skip plugins matching the pattern (grep -E format)" + echo " --help, -h Show this help message" + echo + echo "Examples:" + echo " $0 # Check all plugins" + echo " $0 --apply # Check and apply changes to all plugins" + echo " $0 --apply --force # Check and apply changes without confirmation" + echo " $0 --include='^(alerts|surveys)$' # Only process alerts and surveys plugins" + echo " $0 --exclude='^empty$' # Process all plugins except 'empty'" + echo " $0 --debug # Show debug information" +} + +# Parse arguments +for arg in "$@"; do + case $arg in + --apply) + APPLY_CHANGES=true + ;; + --force) + SKIP_CONFIRMATION=true + ;; + --verbose) + VERBOSE=true + ;; + --debug) + DEBUG=true + ;; + --include=*) + INCLUDE_PATTERN="${arg#*=}" + ;; + --exclude=*) + EXCLUDE_PATTERN="${arg#*=}" + ;; + --help|-h) + print_usage + exit 0 + ;; + -*) + echo "Unknown option: $arg" + print_usage + exit 1 + ;; + esac +done + +# Debug check +if [ "$DEBUG" = true ]; then + echo "DEBUG: Script location: $SCRIPT_DIR" + echo "DEBUG: Clean script path: $CLEAN_SCRIPT" + echo "DEBUG: Script options:" + echo " APPLY_CHANGES: $APPLY_CHANGES" + echo " SKIP_CONFIRMATION: $SKIP_CONFIRMATION" + echo " VERBOSE: $VERBOSE" + echo " DEBUG: $DEBUG" + echo " INCLUDE_PATTERN: $INCLUDE_PATTERN" + echo " EXCLUDE_PATTERN: $EXCLUDE_PATTERN" + # Check if the Node.js script exists + if [ -f "$CLEAN_SCRIPT" ]; then + echo "DEBUG: Clean localization script found at $CLEAN_SCRIPT" + else + echo "ERROR: Clean localization script NOT found at $CLEAN_SCRIPT" + exit 1 + fi + # Check Node.js version + echo "DEBUG: Node.js version: $(node --version)" + echo +fi + +# Prepare arguments for the clean-localization.sh script +CLEAN_ARGS=() +if [ "$APPLY_CHANGES" = true ]; then + CLEAN_ARGS+=("--apply") +fi +if [ "$SKIP_CONFIRMATION" = true ]; then + CLEAN_ARGS+=("--force") +fi + +# Check if plugins directory exists +if [ ! -d "$PLUGINS_DIR" ]; then + echo "Error: Plugins directory not found at $PLUGINS_DIR" + exit 1 +fi + +# Collect all plugin directories +echo "Scanning for plugins in $PLUGINS_DIR..." +PLUGINS=() +for plugin_dir in "$PLUGINS_DIR"/*; do + if [ -d "$plugin_dir" ]; then + plugin_name=$(basename "$plugin_dir") + + # Apply include pattern if specified + if [ -n "$INCLUDE_PATTERN" ]; then + if ! echo "$plugin_name" | grep -Eq "$INCLUDE_PATTERN"; then + [ "$VERBOSE" = true ] && echo "Skipping plugin '$plugin_name' (not matching include pattern)" + continue + fi + fi + + # Apply exclude pattern if specified + if [ -n "$EXCLUDE_PATTERN" ]; then + if echo "$plugin_name" | grep -Eq "$EXCLUDE_PATTERN"; then + [ "$VERBOSE" = true ] && echo "Skipping plugin '$plugin_name' (matching exclude pattern)" + continue + fi + fi + + PLUGINS+=("$plugin_name") + fi +done + +echo "Found ${#PLUGINS[@]} plugins to process" +echo + +# Process each plugin +PROCESSED=0 +SUCCESS=0 +FAILED=0 +WITH_UNUSED_KEYS=0 +FAILED_PLUGINS=() + +for plugin in "${PLUGINS[@]}"; do + echo "================================================================================" + echo "Processing plugin: $plugin ($(( PROCESSED + 1 ))/${#PLUGINS[@]})" + echo "================================================================================" + + # Check if the plugin has a localization directory + LOCALIZATION_DIR="$PLUGINS_DIR/$plugin/frontend/public/localization" + if [ ! -d "$LOCALIZATION_DIR" ]; then + echo "Plugin '$plugin' does not have a localization directory. Skipping." + echo + ((PROCESSED++)) + continue + fi + + # Check if the plugin has a properties file + PROPERTIES_FILE="$LOCALIZATION_DIR/$plugin.properties" + if [ ! -f "$PROPERTIES_FILE" ]; then + echo "Plugin '$plugin' does not have a main properties file ($plugin.properties). Skipping." + echo + ((PROCESSED++)) + continue + fi + + # Run the cleanup script on this plugin + if [ "$DEBUG" = true ]; then + # shellcheck disable=SC2145 + echo "DEBUG: Running command: $CLEAN_SCRIPT $plugin ${CLEAN_ARGS[@]}" + fi + + if [ "$VERBOSE" = true ]; then + # In verbose mode, run directly to show real-time output + "$CLEAN_SCRIPT" "$plugin" "${CLEAN_ARGS[@]}" + RESULT=$? + else + # In non-verbose mode, capture output to check for unused keys + OUTPUT_FILE=$(mktemp) + "$CLEAN_SCRIPT" "$plugin" "${CLEAN_ARGS[@]}" > "$OUTPUT_FILE" 2>&1 + RESULT=$? + cat "$OUTPUT_FILE" + + # Check if unused keys were found + if grep -q "Found [1-9][0-9]* unused keys" "$OUTPUT_FILE"; then + ((WITH_UNUSED_KEYS++)) + fi + rm "$OUTPUT_FILE" + fi + + # Check result + if [ $RESULT -eq 0 ]; then + ((SUCCESS++)) + else + echo "ERROR: Failed to process plugin $plugin (exit code $RESULT)" + FAILED_PLUGINS+=("$plugin ($RESULT)") + ((FAILED++)) + fi + + ((PROCESSED++)) + echo +done + +echo "================================================================================" +echo "Summary:" +echo "================================================================================" +echo "Total plugins processed: $PROCESSED" +echo "Successful: $SUCCESS" +echo "Failed: $FAILED" +echo "Plugins with unused keys: $WITH_UNUSED_KEYS" +echo + +if [ $FAILED -gt 0 ]; then + echo "Failed plugins:" + for plugin in "${FAILED_PLUGINS[@]}"; do + echo " - $plugin" + done + echo +fi + +echo "All done!" +exit 0 \ No newline at end of file diff --git a/bin/scripts/localization/clean-localization-keys.js b/bin/scripts/localization/clean-localization-keys.js new file mode 100644 index 00000000000..58c1880d9a5 --- /dev/null +++ b/bin/scripts/localization/clean-localization-keys.js @@ -0,0 +1,249 @@ +/** + * Script to clean unused localization keys from Countly plugin properties files + * + * This script: + * 1. Reads all keys from a plugin's localization properties file + * 2. Scans the entire project to find localization key usage + * 3. Identifies unused keys and creates a new properties file without them + * + * Usage: node clean-localization-keys.js [] + * Example: node clean-localization-keys.js alerts + * node clean-localization-keys.js surveys surveys + */ + +const fs = require('fs'); +const path = require('path'); +const util = require('util'); + +const readFile = util.promisify(fs.readFile); +const writeFile = util.promisify(fs.writeFile); +const readdir = util.promisify(fs.readdir); +const access = util.promisify(fs.access); + +// Get plugin name from command line arguments +const pluginName = process.argv[2]; +// Get properties file name (defaults to plugin name if not provided) +const propertiesFileName = process.argv[3] || pluginName; + +// Check if plugin name was provided +if (!pluginName) { + console.error('Error: No plugin name provided'); + console.error('Usage: node clean-localization-keys.js []'); + console.error('Example: node clean-localization-keys.js alerts'); + console.error(' node clean-localization-keys.js surveys surveys'); + process.exit(1); +} + +// Define paths - fixed to correctly reference the root directory +const scriptDir = __dirname; +const countlyRoot = path.resolve(scriptDir, '../../..'); // Go up three levels from bin/scripts/localization +const pluginPath = path.join(countlyRoot, 'plugins', pluginName); +const localizationPath = path.join(pluginPath, 'frontend', 'public', 'localization', `${propertiesFileName}.properties`); + +// Check if plugin directory exists +(async function() { + try { + await access(pluginPath, fs.constants.F_OK); + } + catch (err) { + console.error(`Error: Plugin '${pluginName}' not found at ${pluginPath}`); + process.exit(1); + } + + // Check if properties file exists + try { + await access(localizationPath, fs.constants.F_OK); + } + catch (err) { + console.error(`Error: Properties file not found at ${localizationPath}`); + console.error(`Make sure the plugin has a localization file at: frontend/public/localization/${propertiesFileName}.properties`); + process.exit(1); + } + + await cleanUnusedKeys(); +})(); + +/** + * Recursively get all JavaScript and HTML files in a directory and its subdirectories + * @param {string} dir - Directory path + * @param {Array} extensions - Array of file extensions to include (e.g., ['.js', '.html']) + * @param {Array} excludeDirs - Array of directory names to exclude + * @returns {Promise} - Array of file paths + */ +async function getFilesWithExtensions(dir, extensions, excludeDirs = ['node_modules', '.git']) { + try { + const entries = await readdir(dir, { withFileTypes: true }); + const files = await Promise.all(entries.map(async(entry) => { + const fullPath = path.resolve(dir, entry.name); + + try { + if (entry.isDirectory()) { + if (excludeDirs.includes(entry.name)) { + return []; + } + return getFilesWithExtensions(fullPath, extensions, excludeDirs); + } + + if (extensions.some(ext => entry.name.endsWith(ext))) { + return [fullPath]; + } + return []; + } + catch (err) { + console.warn(`Warning: Could not process ${fullPath}: ${err.message}`); + return []; + } + })); + return files.flat(); + } + catch (err) { + console.warn(`Warning: Could not read directory ${dir}: ${err.message}`); + return []; + } +} + +/** + * Extract keys from properties file + * @param {string} filePath - Path to properties file + * @returns {Promise} - Map of key to value and line number + */ +async function extractKeysFromProperties(filePath) { + const content = await readFile(filePath, 'utf8'); + const lines = content.split('\n'); + + const keys = {}; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (line.trim() === '' || line.trim().startsWith('#')) { + continue; // Skip empty lines and comments + } + + const equalPos = line.indexOf('='); + if (equalPos > 0) { + const key = line.substring(0, equalPos).trim(); + const value = line.substring(equalPos + 1).trim(); + keys[key] = { value, lineNumber: i }; + } + } + + return keys; +} + +/** + * Check if a key is used anywhere in the project + * @param {string} key - The localization key + * @param {string[]} files - List of files to check + * @returns {Promise} - Whether the key is used + */ +async function isKeyUsed(key, files) { + // Different patterns for how keys might be used in the code + const patterns = [ + `["${key}"]`, // jQuery.i18n.map["key"] + `['${key}']`, // jQuery.i18n.map['key'] + `"${key}"`, // In various contexts + `'${key}'`, // In various contexts + `\`${key}\``, // Template literals + `data-localize="${key}"`, // HTML data-localize attribute + `data-localize='${key}'` // HTML data-localize attribute with single quotes + ]; + + for (const file of files) { + try { + const content = await readFile(file, 'utf8'); + + for (const pattern of patterns) { + if (content.includes(pattern)) { + // Found usage, return true immediately + return true; + } + } + } + catch (err) { + console.warn(`Warning: Could not read file ${file}: ${err.message}`); + } + } + + return false; +} + +/** + * Create a new properties file without unused keys + * @param {Object} keys - Map of all keys + * @param {string[]} unusedKeys - List of unused keys + * @param {string} filePath - Path to original properties file + */ +async function createCleanedProperties(keys, unusedKeys, filePath) { + const content = await readFile(filePath, 'utf8'); + const lines = content.split('\n'); + + // Mark lines that contain unused keys for removal + const linesToRemove = new Set(); + for (const key of unusedKeys) { + if (keys[key]) { + linesToRemove.add(keys[key].lineNumber); + } + } + + // Create new content without the unused keys + const newLines = lines.filter((_, i) => !linesToRemove.has(i)); + + // Write the new content back to the file + const newPath = path.join(path.dirname(filePath), `${path.basename(filePath)}.clean`); + await writeFile(newPath, newLines.join('\n')); + return newPath; +} + +/** + * Main function that runs the cleanup + */ +async function cleanUnusedKeys() { + try { + console.log(`Scanning files for unused localization keys in plugin: ${pluginName}...`); + + // Get relevant files across the entire project (JS, HTML files) + const projectFiles = await getFilesWithExtensions(countlyRoot, ['.js', '.html', '.hbs', '.ejs', '.vue'], ['node_modules', '.git', 'dump', 'log']); + console.log(`Found ${projectFiles.length} relevant files to scan across the project.`); + + // Extract keys from properties file + const keys = await extractKeysFromProperties(localizationPath); + console.log(`Found ${Object.keys(keys).length} localization keys in ${propertiesFileName}.properties.`); + + // Find unused keys + const unusedKeys = []; + let checkedCount = 0; + + for (const key of Object.keys(keys)) { + const isUsed = await isKeyUsed(key, projectFiles); + if (!isUsed) { + unusedKeys.push(key); + } + + // Show progress + checkedCount++; + if (checkedCount % 10 === 0 || checkedCount === Object.keys(keys).length) { + process.stdout.write(`\rChecked ${checkedCount}/${Object.keys(keys).length} keys...`); + } + } + console.log(); // New line after progress + + console.log(`Found ${unusedKeys.length} unused keys.`); + + if (unusedKeys.length > 0) { + console.log('Unused keys:'); + unusedKeys.forEach(key => { + console.log(`- ${key}`); + }); + + // Create a new properties file without the unused keys + const newPath = await createCleanedProperties(keys, unusedKeys, localizationPath); + console.log(`\nCleaned properties file created at: ${newPath}`); + } + else { + console.log('No unused keys found. Great job!'); + } + + } + catch (err) { + console.error('Error:', err); + } +} \ No newline at end of file diff --git a/bin/scripts/localization/clean-localization.sh b/bin/scripts/localization/clean-localization.sh new file mode 100755 index 00000000000..f7fd58af742 --- /dev/null +++ b/bin/scripts/localization/clean-localization.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +# Script to clean unused localization keys from a Countly plugin's properties file +# and automatically apply the changes + +set -e # Exit on error + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +COUNTLY_ROOT="$(cd "$SCRIPT_DIR/../../.." &> /dev/null && pwd )" # Fix: Go up three levels from bin/scripts/localization +PLUGINS_DIR="$COUNTLY_ROOT/plugins" # Fix: Use the plugins directory at the root level + +# Default values +APPLY_CHANGES=false +SKIP_CONFIRMATION=false + +# Print usage +function print_usage { + echo "Usage: $0 [] [--apply] [--force]" + echo + echo "Arguments:" + echo " plugin-name Name of the plugin to scan (required)" + echo " properties-file Name of the properties file without .properties extension" + echo " (defaults to plugin name if not provided)" + echo + echo "Options:" + echo " --apply Automatically apply changes to the original properties file" + echo " --force Skip confirmation when applying changes" + echo + echo "Examples:" + echo " $0 alerts # Check alerts plugin with alerts.properties" + echo " $0 surveys surveys # Check surveys plugin with surveys.properties" + echo " $0 alerts --apply # Check and apply changes to alerts.properties" + echo " $0 alerts --apply --force # Check and apply changes without confirmation" +} + +# Parse arguments +PLUGIN_NAME="" +PROPERTIES_FILE="" +REMAINING_ARGS=() + +for arg in "$@"; do + case $arg in + --apply) + APPLY_CHANGES=true + ;; + --force) + SKIP_CONFIRMATION=true + ;; + --help|-h) + print_usage + exit 0 + ;; + -*) + echo "Unknown option: $arg" + print_usage + exit 1 + ;; + *) + if [ -z "$PLUGIN_NAME" ]; then + PLUGIN_NAME="$arg" + elif [ -z "$PROPERTIES_FILE" ]; then + PROPERTIES_FILE="$arg" + else + REMAINING_ARGS+=("$arg") + fi + ;; + esac +done + +# Check if plugin name was provided +if [ -z "$PLUGIN_NAME" ]; then + echo "Error: No plugin name provided" + print_usage + exit 1 +fi + +# Use plugin name as properties file name if not provided +if [ -z "$PROPERTIES_FILE" ]; then + PROPERTIES_FILE="$PLUGIN_NAME" +fi + +# Define paths +PLUGIN_DIR="$PLUGINS_DIR/$PLUGIN_NAME" +PROPERTIES_PATH="$PLUGIN_DIR/frontend/public/localization/$PROPERTIES_FILE.properties" +BACKUP_PATH="$PROPERTIES_PATH.backup" +CLEAN_PATH="$PROPERTIES_PATH.clean" +NODE_SCRIPT="$SCRIPT_DIR/clean-localization-keys.js" + +# Check if the plugin directory exists +if [ ! -d "$PLUGIN_DIR" ]; then + echo "Error: Plugin directory not found at $PLUGIN_DIR" + exit 1 +fi + +# Check if the properties file exists +if [ ! -f "$PROPERTIES_PATH" ]; then + echo "Error: Properties file not found at $PROPERTIES_PATH" + echo "Make sure the plugin has a localization file at: frontend/public/localization/$PROPERTIES_FILE.properties" + exit 1 +fi + +# Main execution +echo "===== Cleaning unused localization keys from $PROPERTIES_FILE.properties =====" +echo + +# Create a backup of the original file, unless running with --apply --force +if [ "$APPLY_CHANGES" = true ] && [ "$SKIP_CONFIRMATION" = true ]; then + # Skip backup when running with both --apply and --force + echo "Skipping backup creation (running with --apply --force)" +else + echo "Creating backup of original file at $BACKUP_PATH" + cp "$PROPERTIES_PATH" "$BACKUP_PATH" + echo "Backup created successfully." +fi +echo + +# Run the Node.js cleanup script +echo "Running cleanup script..." +node "$NODE_SCRIPT" "$PLUGIN_NAME" "$PROPERTIES_FILE" +echo + +# Check if the cleaned file exists +if [ ! -f "$CLEAN_PATH" ]; then + echo "No changes were applied. The script did not produce a cleaned file." + exit 0 +fi + +# Check if there are any differences +if cmp -s "$PROPERTIES_PATH" "$CLEAN_PATH"; then + echo "No changes detected. The original and cleaned files are identical." + # Remove the clean file since it's the same as the original + rm "$CLEAN_PATH" + exit 0 +fi + +# Apply changes if requested +if [ "$APPLY_CHANGES" = true ]; then + if [ "$SKIP_CONFIRMATION" = false ]; then + echo "Do you want to apply these changes to the original properties file? [y/N]" + read -r response + if [[ ! "$response" =~ ^[Yy]$ ]]; then + echo "Changes not applied. You can find the cleaned file at: $CLEAN_PATH" + exit 0 + fi + fi + + echo "Applying changes to original properties file..." + cp "$CLEAN_PATH" "$PROPERTIES_PATH" + rm "$CLEAN_PATH" + echo "Changes applied successfully." + + # Only mention the backup if we created one + if [ "$SKIP_CONFIRMATION" = false ] || [ "$APPLY_CHANGES" = false ]; then + echo "Original file backed up at: $BACKUP_PATH" + echo "If you need to restore the original file, run: cp $BACKUP_PATH $PROPERTIES_PATH" + fi +else + echo "To apply the changes, use the --apply option or manually copy the cleaned file:" + echo "cp $CLEAN_PATH $PROPERTIES_PATH" +fi + +echo +echo "===== Cleanup process complete! =====" \ No newline at end of file diff --git a/bin/scripts/modify-data/omit_events.js b/bin/scripts/modify-data/omit_events.js index a2d5fd5232c..4a4aac5f4bf 100644 --- a/bin/scripts/modify-data/omit_events.js +++ b/bin/scripts/modify-data/omit_events.js @@ -1,36 +1,30 @@ /** * Checks aggregated data for all events of all apps and outputs the ones that should need omitting segments. + * For deletion to work SERVER_URL and API_KEY should be set. * If DRY_RUN is false, will also omit those segmentes * Server: countly * Path: $(countly dir)/bin/scripts/modify-data * Command: nodejs omit_events.js */ -//API key here with permission to delete events -var API_KEY = "0d87fb49bd48ddc510306b7b4faf209a"; - +//API key with global admin rights +var API_KEY = ""; //dry run without deleting events var DRY_RUN = true; var SERVER_URL = "https://yourserver.count.ly"; var requestsToRun = []; - +var omitLimit = 100; //Segment value limit +var failedReqs = 0; var plugins = require("../../../plugins/pluginManager"); var crypto = require('crypto'); -var request = require('request'); -var requestOptions = { - uri: (process.env.COUNTLY_CONFIG_PROTOCOL || "http") + "://" + (process.env.COUNTLY_CONFIG_HOSTNAME || "localhost") + "/i/events/edit_map", - method: 'POST' -}; +var request = require('countly-request')(plugins.getConfig("security")); + if (!SERVER_URL) { SERVER_URL = (process.env.COUNTLY_CONFIG_PROTOCOL || "http") + "://" + (process.env.COUNTLY_CONFIG_HOSTNAME || "localhost"); } plugins.dbConnection().then(async function(db) { - - var date = new Date(); - var yy = date.getFullYear(); - var apps = await db.collection("apps").find().toArray(); var appCheck = {}; for (var l = 0; l < apps.length; l++) { @@ -42,48 +36,78 @@ plugins.dbConnection().then(async function(db) { var omitted_segments = {}; var event_map = {}; if (events[i] && events[i].list && events[i].list.length) { + console.log("Checking app:", events[i]._id); for (var j = 0; j < events[i].list.length; j++) { if (events[i].list[j]) { + console.log(" Checking event:", events[i].list[j]); var eventSegmentCounts = {}; - var eventMeta = await db.collection("events" + crypto.createHash('sha1').update(events[i].list[j] + events[i]._id).digest('hex')).find({"m": yy + ":0"}).toArray(); - for (var k = 0; k < eventMeta.length; k++) { - if (eventMeta[k] && eventMeta[k].meta_v2 && eventMeta[k].meta_v2.segments) { - for (let segment in eventMeta[k].meta_v2.segments) { - if (eventMeta[k].meta_v2[segment]) { - if (typeof eventSegmentCounts[segment] === "undefined") { - eventSegmentCounts[segment] = 0; + var hash = crypto.createHash('sha1').update(events[i].list[j] + events[i]._id).digest('hex'); + var pipeline = [ + {"$match": {"_id": {"$regex": "^" + events[i]._id + "_" + hash + "_no-segment_.*"}, "meta_v2": {"$exists": true}}}, + { + "$project": { + "m": "$m", + "meta_v2": { + "$map": { + "input": {"$objectToArray": "$meta_v2"}, + "as": "seg", + "in": {"k": "$$seg.k", "v": {"$size": {"$objectToArray": "$$seg.v"}}} } - eventSegmentCounts[segment] += Object.keys(eventMeta[k].meta_v2[segment]).length; } } + }, + {"$unwind": "$meta_v2"}, + { + "$group": { + "_id": {"key": "$meta_v2.k", "m": "$m"}, + "count": {"$sum": "$meta_v2.v"} + } + } + ]; + var eventMeta = await db.collection("events_data").aggregate(pipeline).toArray(); + for (var k = 0; k < eventMeta.length; k++) { + if (eventMeta[k]._id.key !== "segments") { + eventSegmentCounts[eventMeta[k]._id.key] = eventSegmentCounts[eventMeta[k]._id.key] || 0; + eventSegmentCounts[eventMeta[k]._id.key] = Math.max(eventMeta[k].count, eventSegmentCounts[eventMeta[k]._id.key]); } + } var first = true; //console.log("Event:", events[i].list[j], "for app:", events[i]._id); for (let segment in eventSegmentCounts) { - if (eventSegmentCounts[segment] >= 1000) { + if (eventSegmentCounts[segment] >= omitLimit) { if (first) { if (firstApp) { - console.log("For app:", appCheck[events[i]._id] || events[i]._id); firstApp = false; } - console.log("", "Event:", events[i].list[j]); first = false; } - console.log("", "", segment, ":", eventSegmentCounts[segment]); + if (events[i] && events[i].omitted_segments && events[i].omitted_segments[events[i].list[j]] && Array.isArray(events[i].omitted_segments[events[i].list[j]])) { + omitted_segments[events[i].list[j]] = events[i].omitted_segments[events[i].list[j]]; + } if (!omitted_segments[events[i].list[j]]) { omitted_segments[events[i].list[j]] = []; } - omitted_segments[events[i].list[j]].push(segment); + if (omitted_segments[events[i].list[j]].indexOf(segment) === -1) { + omitted_segments[events[i].list[j]].push(segment); + } + + if (events[i] && events[i].map && events[i].map[events[i].list[j]]) { + event_map[events[i].list[j]] = events[i].map[events[i].list[j]]; + event_map[events[i].list[j]].omit_list = events[i].map[events[i].list[j]].omit_list || []; + } if (!event_map[events[i].list[j]]) { event_map[events[i].list[j]] = {key: events[i].list[j], is_visible: true, omit_list: []}; } - event_map[events[i].list[j]].omit_list.push(segment); + if (event_map[events[i].list[j]] && event_map[events[i].list[j]].omit_list && event_map[events[i].list[j]].omit_list.indexOf(segment) === -1) { + event_map[events[i].list[j]].omit_list.push(segment); + } } } } } } + console.log(" Current event map:", JSON.stringify(event_map)); if (Object.keys(omitted_segments).length) { if (DRY_RUN) { //as it is dry run - output request @@ -96,25 +120,41 @@ plugins.dbConnection().then(async function(db) { requestsToRun.push(SERVER_URL + "/i/events/edit_map?" + props.join("&")); } else { - requestOptions.json = { - omitted_segments: JSON.stringify(omitted_segments), - event_map: JSON.stringify(event_map), - app_id: events[i]._id, - api_key: API_KEY + console.log("Omitting segments for app:", events[i]._id, "for events:", JSON.stringify(omitted_segments)); + const options = { + url: SERVER_URL + "/i/events/edit_map", + uri: SERVER_URL + "/i/events/edit_map", + method: "POST", + json: { + omitted_segments: JSON.stringify(omitted_segments), + event_map: JSON.stringify(event_map), + app_id: events[i]._id + "", + api_key: API_KEY + }, + strictSSL: false }; await new Promise(function(resolve) { - request(requestOptions, function(error, response, body) { - console.log("request finished", body); + request(SERVER_URL + "/i/events/edit_map", options, function(error) { + if ((error && error.name)) { + failedReqs++; + console.log(JSON.stringify(error.message)); + console.log({err: 'There was an error while sending a request.'}); + } + resolve(); }); }); } } } + if (failedReqs) { + console.log("There were " + failedReqs + " failed requests. Please check your API KEY and url for server"); + } if (requestsToRun.length) { for (var z = 0; z < requestsToRun.length; z++) { console.log(requestsToRun[z]); } } + console.log("Done"); db.close(); }); \ No newline at end of file diff --git a/bin/scripts/timezones/package-lock.json b/bin/scripts/timezones/package-lock.json index 8e919c0ad20..2c69b28afbd 100644 --- a/bin/scripts/timezones/package-lock.json +++ b/bin/scripts/timezones/package-lock.json @@ -1,47 +1,126 @@ { "name": "timezones", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "moment": { + "packages": { + "": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "moment-timezone": "0.5.48", + "node-fetch": "3.3.2" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" - }, - "moment-timezone": { - "version": "0.5.35", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.35.tgz", - "integrity": "sha512-cY/pBOEXepQvlgli06ttCTKcIf8cD1nmNwOKQQAdHBqYApQSpAqotBMX0RJZNgMp6i0PlZuf1mFtnlyEkwyvFw==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" } } } diff --git a/bin/scripts/timezones/package.json b/bin/scripts/timezones/package.json index cfdcb1bc2ce..0ba29f8a4cf 100644 --- a/bin/scripts/timezones/package.json +++ b/bin/scripts/timezones/package.json @@ -22,7 +22,7 @@ }, "homepage": "https://count.ly/", "dependencies": { - "moment-timezone": "0.5.35", - "node-fetch": "2.6.7" + "moment-timezone": "0.5.48", + "node-fetch": "3.3.2" } } diff --git a/bin/upgrade/DEV/upgrade.sh b/bin/upgrade/DEV/upgrade.sh new file mode 100644 index 00000000000..54565dd038e --- /dev/null +++ b/bin/upgrade/DEV/upgrade.sh @@ -0,0 +1,13 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +DATE=$(date +%Y-%m-%d:%H:%M:%S) +VERSION="$(basename "${DIR}")" + +countly stop +if [ -f "$DIR/upgrade_fs.sh" ]; then + bash "$DIR/upgrade_fs.sh" combined 2>&1 | tee -a "$DIR/../../../log/countly-upgrade-fs-$VERSION-$DATE.log" +fi +if [ -f "$DIR/upgrade_db.sh" ]; then + bash "$DIR/upgrade_db.sh" combined 2>&1 | tee -a "$DIR/../../../log/countly-upgrade-db-$VERSION-$DATE.log" +fi +countly upgrade diff --git a/bin/upgrade/DEV/upgrade_db.sh b/bin/upgrade/DEV/upgrade_db.sh new file mode 100644 index 00000000000..0c7d233ff3f --- /dev/null +++ b/bin/upgrade/DEV/upgrade_db.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +VER="25.06" + +CONTINUE="$(countly check before upgrade db "$VER")" + +if [ "$CONTINUE" != "1" ] && [ "$1" != "combined" ] +then + echo "Database is already up to date with $VER" + read -r -p "Are you sure you want to run this script? [y/N] " response + if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]] + then + CONTINUE=1 + fi +fi + +if [ "$CONTINUE" == "1" ] +then + echo "Running database modifications" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" + SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + if [ "$1" != "combined" ]; then + #upgrade plugins + countly plugin enable content; + countly plugin enable journey_engine; + nodejs "$DIR/scripts/install_plugins.js" + fi + + #add indexes + nodejs "$DIR/scripts/add_indexes.js" + + #run upgrade scripts + nodejs "$SCRIPTS/scripts/merge_events_collections.js" + + + if [ "$1" != "combined" ]; then + countly upgrade; + fi + + #call after check + countly check after upgrade db "$VER" +elif [ "$CONTINUE" == "0" ] +then + echo "Database is already upgraded to $VER" +elif [ "$CONTINUE" == "-1" ] +then + echo "Database is upgraded to higher version" +else + echo "Unknown upgrade state: $CONTINUE" +fi diff --git a/bin/upgrade/DEV/upgrade_fs.sh b/bin/upgrade/DEV/upgrade_fs.sh new file mode 100644 index 00000000000..20455907020 --- /dev/null +++ b/bin/upgrade/DEV/upgrade_fs.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +echo "Running filesystem modifications" + +VER="25.06" + +CONTINUE="$(countly check before upgrade fs "$VER")" + +if [ "$CONTINUE" != "1" ] && [ "$1" != "combined" ] +then + echo "Filesystem is already up to date with $VER" + read -r -p "Are you sure you want to run this script? [y/N] " response + if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]] + then + CONTINUE=1 + fi +fi + +if [ "$CONTINUE" == "1" ] +then + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" + + #enable command line + bash "$DIR/scripts/detect.init.sh" + rm -rf "$DIR/../plugins/old-ui-compatibility" + + countly plugin enable content; + countly plugin enable journey_engine; + + #upgrade plugins + nodejs "$DIR/scripts/install_plugins.js" + + #get web sdk + countly update sdk-web + + + if [ "$1" != "combined" ]; then + countly upgrade; + else + countly task dist-all; + fi + + #call after check + countly check after upgrade fs "$VER" +elif [ "$CONTINUE" == "0" ] +then + echo "Filesystem is already upgraded to $VER" +elif [ "$CONTINUE" == "-1" ] +then + echo "Filesystem is upgraded to higher version" +else + echo "Unknown upgrade state: $CONTINUE" +fi diff --git a/frontend/express/public/javascripts/countly/countly.auth.js b/frontend/express/public/javascripts/countly/countly.auth.js index 725c9aa2163..14ea476dca2 100644 --- a/frontend/express/public/javascripts/countly/countly.auth.js +++ b/frontend/express/public/javascripts/countly/countly.auth.js @@ -298,62 +298,6 @@ return permission_object; }; - countlyAuth.permissionParser = function(parent_el, permission_object, permission_sets) { - var admin_apps = permission_object._.a; - var user_apps = permission_object._.u; - var checked_admin_apps = []; - var checked_user_apps = []; - - for (var i = 0; i < admin_apps.length; i++) { - if (countlyGlobal.apps[admin_apps[i]]) { - checked_admin_apps.push(admin_apps[i]); - } - } - - $('#manage-users-admin-app-selector')[0].selectize.setValue(checked_admin_apps); - - for (var i0 = 0; i0 < user_apps.length; i0++) { - checked_user_apps = []; - for (var j0 = 0; j0 < user_apps[i0].length; j0++) { - if (countlyGlobal.apps[user_apps[i0][j0]]) { - checked_user_apps.push(user_apps[i0][j0]); - } - } - - $(parent_el + ' #user-app-selector-' + i0)[0].selectize.setValue(checked_user_apps); - - for (var j1 = 0; j1 < countlyAuth.types.length; j1++) { - if (user_apps[i0].length > 0) { - if (permission_object[countlyAuth.types[j1]][user_apps[i0][0]].all) { - - $(parent_el + ' #mark-all-' + countlyAuth.typeNames[j1] + '-' + i0).countlyCheckbox().set(true); - - for (var k = 0; k < countlyAuth.features.length; k++) { - $(parent_el + ' #' + countlyAuth.types[j1] + '-' + countlyAuth.features[k] + '-' + i0).countlyCheckbox().set(true); - if (countlyAuth.types[j1] === "r" && countlyAuth.features[k] === 'core') { - $(parent_el + ' #' + countlyAuth.types[j1] + '-' + countlyAuth.features[k] + '-' + i0).countlyCheckbox().setDisabled(); - } - } - - permission_sets[i0][countlyAuth.types[j1]].all = true; - permission_sets[i0][countlyAuth.types[j1]].allowed = permission_object[countlyAuth.types[j1]][user_apps[i0][0]].allowed; - } - else { - for (var feature in permission_object[countlyAuth.types[j1]][user_apps[i0][0]].allowed) { - permission_sets[i0] = countlyAuth.giveFeaturePermission(countlyAuth.types[j1], feature, permission_sets[i0]); - $(parent_el + ' #' + countlyAuth.types[j1] + '-' + feature + '-' + i0).countlyCheckbox().set(true); - if (countlyAuth.types[j1] === "r" && feature === 'core') { - $(parent_el + ' #' + countlyAuth.types[j1] + '-' + feature + '-' + i0).countlyCheckbox().setDisabled(); - } - } - } - } - } - } - - return permission_sets; - }; - countlyAuth.getUserApps = function() { var member = countlyGlobal.member; var userApps = []; diff --git a/frontend/express/public/javascripts/countly/countly.common.js b/frontend/express/public/javascripts/countly/countly.common.js index 2b6cd25283f..209dec36f81 100644 --- a/frontend/express/public/javascripts/countly/countly.common.js +++ b/frontend/express/public/javascripts/countly/countly.common.js @@ -1,4 +1,4 @@ -/*global store, Handlebars, CountlyHelpers, countlyGlobal, _, Gauge, d3, moment, countlyTotalUsers, jQuery, filterXSS, mergeWith*/ +/*global store, CountlyHelpers, countlyGlobal, _, moment, countlyTotalUsers, jQuery, filterXSS, mergeWith*/ (function(window, $) { /** * Object with common functions to be used for multiple purposes @@ -450,1081 +450,232 @@ }; /** - * Checks if current graph type matches the one being drawn - * @memberof countlyCommon - * @param {string} type - graph type - * @param {object} settings - graph settings - * @returns {boolean} Return true if type is the same - */ - countlyCommon.checkGraphType = function(type, settings) { - var eType = "line"; - if (settings && settings.series && settings.series.bars && settings.series.bars.show === true) { - if (settings.series.stack === true) { - eType = "bar"; - } - else { - eType = "seperate-bar"; - } - } - else if (settings && settings.series && settings.series.pie && settings.series.pie.show === true) { - eType = "pie"; - } - - if (type === eType) { - return true; - } - else { - return false; - } - }; - /** - * Draws a graph with the given dataPoints to container. Used for drawing bar and pie charts. + * Get Date graph ticks * @memberof countlyCommon - * @param {object} dataPoints - data poitns to draw on graph - * @param {string|object} container - selector for container or container object itself where to create graph - * @param {string} graphType - type of the graph, accepted values are bar, line, pie, separate-bar - * @param {object} inGraphProperties - object with properties to extend and use on graph library directly - * @returns {boolean} false if container element not found, otherwise true - * @example Drawing Pie chart - * countlyCommon.drawGraph({"dp":[ - * {"data":[[0,20]],"label":"Test1","color":"#52A3EF"}, - * {"data":[[0,30]],"label":"Test2","color":"#FF8700"}, - * {"data":[[0,50]],"label":"Test3","color":"#0EC1B9"} - * ]}, "#dashboard-graph", "pie"); - * @example Drawing bar chart, to comapre values with different color bars - * //[-1,null] and [3,null] are used for offsets from left and right - * countlyCommon.drawGraph({"dp":[ - * {"data":[[-1,null],[0,20],[1,30],[2,50],[3,null]],"color":"#52A3EF"}, //first bar set - * {"data":[[-1,null],[0,50],[1,30],[2,20],[3,null]],"color":"#0EC1B9"} //second bar set - *], - * "ticks":[[-1,""],[0,"Test1"],[1,"Test2"],[2,"Test3"],[3,""]] - *}, "#dashboard-graph", "separate-bar", {"series":{"stack":null}}); - * @example Drawing Separate bars chart, to comapre values with different color bars - * //[-1,null] and [3,null] are used for offsets from left and right - * countlyCommon.drawGraph({"dp":[ - * {"data":[[-1,null],[0,20],[1,null],[2,null],[3,null]],"label":"Test1","color":"#52A3EF"}, - * {"data":[[-1,null],[0,null],[1,30],[2,null],[3,null]],"label":"Test2","color":"#FF8700"}, - * {"data":[[-1,null],[0,null],[1,null],[2,50],[3,null]],"label":"Test3","color":"#0EC1B9"} - *], - * "ticks":[[-1,""],[0,"Test1"],[1,"Test2"],[2,"Test3"],[3,""] - *]}, "#dashboard-graph", "separate-bar"); + * @param {string} bucket - time bucket, accepted values, hourly, weekly, monthly + * @param {boolean} overrideBucket - override existing bucket logic and simply use current date for generating ticks + * @param {boolean} newChart - new chart implementation + * @returns {object} object containing tick texts and ticks to use on time graphs + * @example Example output + *{ + * "min":0, + * "max":29, + * "tickTexts":["22 Dec, Thursday","23 Dec, Friday","24 Dec, Saturday","25 Dec, Sunday","26 Dec, Monday","27 Dec, Tuesday","28 Dec, Wednesday", + * "29 Dec, Thursday","30 Dec, Friday","31 Dec, Saturday","1 Jan, Sunday","2 Jan, Monday","3 Jan, Tuesday","4 Jan, Wednesday","5 Jan, Thursday", + * "6 Jan, Friday","7 Jan, Saturday","8 Jan, Sunday","9 Jan, Monday","10 Jan, Tuesday","11 Jan, Wednesday","12 Jan, Thursday","13 Jan, Friday", + * "14 Jan, Saturday","15 Jan, Sunday","16 Jan, Monday","17 Jan, Tuesday","18 Jan, Wednesday","19 Jan, Thursday","20 Jan, Friday"], + * "ticks":[[1,"23 Dec"],[4,"26 Dec"],[7,"29 Dec"],[10,"1 Jan"],[13,"4 Jan"],[16,"7 Jan"],[19,"10 Jan"],[22,"13 Jan"],[25,"16 Jan"],[28,"19 Jan"]] + *} */ - countlyCommon.drawGraph = function(dataPoints, container, graphType, inGraphProperties) { - var p = 0; - - if ($(container).length <= 0) { - return false; - } - - if (graphType === "pie") { - var min_treshold = 0.05; //minimum treshold for graph - var break_other = 0.3; //try breaking other in smaller if at least given % from all - var sum = 0; + countlyCommon.getTickObj = function(bucket, overrideBucket, newChart) { + var days = parseInt(countlyCommon.periodObj.numberOfDays, 10), + ticks = [], + tickTexts = [], + skipReduction = false, + limitAdjustment = 0; - var i = 0; - var useMerging = true; - for (i = 0; i < dataPoints.dp.length; i++) { - sum = sum + dataPoints.dp[i].data[0][1]; - if (dataPoints.dp[i].moreInfo) { - useMerging = false; - } - else { - dataPoints.dp[i].moreInfo = ""; - } + if (overrideBucket) { + var thisDay; + if (countlyCommon.periodObj.activePeriod) { + thisDay = moment(countlyCommon.periodObj.activePeriod, "YYYY.M.D"); } - - if (useMerging) { - var dpLength = dataPoints.dp.length; - var treshold_value = Math.round(min_treshold * sum); - var max_other = Math.round(min_treshold * sum); - var under_treshold = [];//array of values under treshold - var left_for_other = sum; - for (i = 0; i < dataPoints.dp.length; i++) { - if (dataPoints.dp[i].data[0][1] >= treshold_value) { - left_for_other = left_for_other - dataPoints.dp[i].data[0][1]; - } - else { - under_treshold.push(dataPoints.dp[i].data[0][1]); - } - } - var stop_breaking = Math.round(sum * break_other); - if (left_for_other >= stop_breaking) { //fix values if other takes more than set % of data - under_treshold = under_treshold.sort(function(a, b) { - return a - b; - }); - - var tresholdMap = []; - treshold_value = treshold_value - 1; //to don't group exactly 5% values later in code - tresholdMap.push({value: treshold_value, text: 5}); - var in_this_one = 0; - var count_in_this = 0; - - for (p = under_treshold.length - 1; p >= 0 && under_treshold[p] > 0 && left_for_other >= stop_breaking; p--) { - if (under_treshold[p] <= treshold_value) { - if (in_this_one + under_treshold[p] <= max_other || count_in_this < 5) { - count_in_this++; - in_this_one += under_treshold[p]; - left_for_other -= under_treshold[p]; - } - else { - if (tresholdMap[tresholdMap.length - 1].value === under_treshold[p]) { - in_this_one = 0; - count_in_this = 0; - treshold_value = under_treshold[p] - 1; - } - else { - in_this_one = under_treshold[p]; - count_in_this = 1; - treshold_value = under_treshold[p]; - left_for_other -= under_treshold[p]; - } - tresholdMap.push({value: treshold_value, text: Math.max(0.009, Math.round(treshold_value * 10000 / sum) / 100)}); - } - } - } - treshold_value = Math.max(treshold_value - 1, 0); - tresholdMap.push({value: treshold_value, text: Math.round(treshold_value * 10000 / sum) / 100}); - var tresholdPointer = 0; - - while (tresholdPointer < tresholdMap.length - 1) { - dataPoints.dp.push({"label": tresholdMap[tresholdPointer + 1].text + "-" + tresholdMap[tresholdPointer].text + "%", "data": [[0, 0]], "moreInfo": []}); - var tresholdPlace = dataPoints.dp.length - 1; - for (i = 0; i < dpLength; i++) { - if (dataPoints.dp[i].data[0][1] <= tresholdMap[tresholdPointer].value && dataPoints.dp[i].data[0][1] > tresholdMap[tresholdPointer + 1].value) { - dataPoints.dp[tresholdPlace].moreInfo.push({"label": dataPoints.dp[i].label, "value": Math.round(dataPoints.dp[i].data[0][1] * 10000 / sum) / 100}); - dataPoints.dp[tresholdPlace].data[0][1] = dataPoints.dp[tresholdPlace].data[0][1] + dataPoints.dp[i].data[0][1]; - dataPoints.dp.splice(i, 1); - dpLength = dataPoints.dp.length; - i--; - tresholdPlace--; - } - } - tresholdPointer = tresholdPointer + 1; - } - } + else { + thisDay = moment(countlyCommon.periodObj.currentPeriodArr[0], "YYYY.M.D"); } + ticks.push([0, countlyCommon.formatDate(thisDay, "D MMM")]); + tickTexts[0] = countlyCommon.formatDate(thisDay, "D MMM, dddd"); } - - _.defer(function() { - if ((!dataPoints.dp || !dataPoints.dp.length) || (graphType === "bar" && (!dataPoints.dp[0].data[0] || (typeof dataPoints.dp[0].data[0][1] === 'undefined' && typeof dataPoints.dp[0].data[1][1] === 'undefined') || (dataPoints.dp[0].data[0][1] === null && dataPoints.dp[0].data[1][1] === null)))) { - $(container).hide(); - $(container).siblings(".graph-no-data").show(); - return true; - } - else { - $(container).show(); - $(container).siblings(".graph-no-data").hide(); - } - - var graphProperties = { - series: { - lines: { show: true, fill: true }, - points: { show: true } - }, - grid: { hoverable: true, borderColor: "null", color: "#999", borderWidth: 0, minBorderMargin: 10 }, - xaxis: { minTickSize: 1, tickDecimals: "number", tickLength: 0 }, - yaxis: { min: 0, minTickSize: 1, tickDecimals: "number", position: "right" }, - legend: { backgroundOpacity: 0, margin: [20, -19] }, - colors: countlyCommon.GRAPH_COLORS - }; - - switch (graphType) { - case "line": - graphProperties.series = { lines: { show: true, fill: true }, points: { show: true } }; - break; - case "bar": - if (dataPoints.ticks.length > 20) { - graphProperties.xaxis.rotateTicks = 45; - } - - var barWidth = 0.6; - - switch (dataPoints.dp.length) { - case 2: - barWidth = 0.3; - break; - case 3: - barWidth = 0.2; - break; - } - - for (i = 0; i < dataPoints.dp.length; i++) { - dataPoints.dp[i].bars = { - order: i, - barWidth: barWidth - }; - } - - graphProperties.series = { stack: true, bars: { show: true, barWidth: 0.6, tickLength: 0, fill: 1 } }; - graphProperties.xaxis.ticks = dataPoints.ticks; - break; - case "separate-bar": - if (dataPoints.ticks.length > 20) { - graphProperties.xaxis.rotateTicks = 45; - } - graphProperties.series = { bars: { show: true, align: "center", barWidth: 0.6, tickLength: 0, fill: 1 } }; - graphProperties.xaxis.ticks = dataPoints.ticks; - break; - case "pie": - graphProperties.series = { - pie: { - show: true, - lineWidth: 0, - radius: 115, - innerRadius: 0.45, - combine: { - color: '#CCC', - threshold: 0.05 - }, - label: { - show: true, - radius: 160 - } - } - }; - graphProperties.legend.show = false; - break; - default: - break; + else if ((days === 1 && _period !== "month" && _period !== "day") || (days === 1 && bucket === "hourly")) { + //When period is an array or string like Xdays, Xweeks + for (var z = 0; z < 24; z++) { + ticks.push([z, (z + ":00")]); + tickTexts.push((z + ":00")); } - - if (inGraphProperties) { - $.extend(true, graphProperties, inGraphProperties); + skipReduction = true; + } + else { + var start = moment().subtract(days, 'days'); + if (Object.prototype.toString.call(countlyCommon.getPeriod()) === '[object Array]') { + start = moment(countlyCommon.periodObj.currentPeriodArr[countlyCommon.periodObj.currentPeriodArr.length - 1], "YYYY.MM.DD").subtract(days, 'days'); } + var i = 0; + if (bucket === "monthly") { + var allMonths = []; - $.plot($(container), dataPoints.dp, graphProperties); - - if (graphType === "bar" || graphType === "separate-bar") { - $(container).unbind("plothover"); - $(container).bind("plothover", function(event, pos, item) { - $("#graph-tooltip").remove(); - - if (item && item.datapoint && item.datapoint[1]) { - // For stacked bar chart calculate the diff - var yAxisValue = item.datapoint[1].toFixed(1).replace(".0", "") - item.datapoint[2].toFixed(1).replace(".0", ""); - if (inGraphProperties && inGraphProperties.tooltipType === "duration") { - yAxisValue = countlyCommon.formatSecond(yAxisValue); - } + //so we would not start from previous year + start.add(1, 'day'); - showTooltip({ - x: pos.pageX, - y: item.pageY, - contents: yAxisValue || 0 - }); - } - }); - } - else if (graphType === 'pie') { - $(container).unbind("plothover"); - $(container).bind("plothover", function(event, pos, item) { - $("#graph-tooltip").remove(); - if (item && item.series && item.series.moreInfo) { - var tooltipcontent; - if (Array.isArray(item.series.moreInfo)) { - tooltipcontent = ""; - if (item.series.moreInfo.length <= 5) { - for (p = 0; p < item.series.moreInfo.length; p++) { - tooltipcontent = tooltipcontent + ""; - } - } - else { - for (p = 0; p < 5; p = p + 1) { - tooltipcontent += ""; - } - tooltipcontent += ""; - } - tooltipcontent += "
" + item.series.moreInfo[p].label + ":" + item.series.moreInfo[p].value + "%
" + item.series.moreInfo[p].label + " :" + item.series.moreInfo[p].value + "%
...
(and " + (item.series.moreInfo.length - 5) + " other)
"; - } - else { - tooltipcontent = item.series.moreInfo; - } - showTooltip({ - x: pos.pageX, - y: pos.pageY, - contents: tooltipcontent - }); - } - }); - } - else { - $(container).unbind("plothover"); - } - }, dataPoints, container, graphType, inGraphProperties); + var monthCount = 12; - return true; - }; + for (i = 0; i < monthCount; i++) { + allMonths.push(start.format(countlyCommon.getDateFormat("MMM YYYY"))); + start.add(1, 'months'); + } - /** - * Draws a time line graph with the given dataPoints to container. - * @memberof countlyCommon - * @param {object} dataPoints - data points to draw on graph - * @param {string|object} container - selector for container or container object itself where to create graph - * @param {string=} bucket - time bucket to display on graph. See {@link countlyCommon.getTickObj} - * @param {string=} overrideBucket - time bucket to display on graph. See {@link countlyCommon.getTickObj} - * @param {boolean=} small - if graph won't be full width graph - * @param {array=} appIdsForNotes - display notes from provided apps ids on graph, will not show notes when empty - * @param {object=} options - extra graph options, see flot documentation - * @example - * countlyCommon.drawTimeGraph([{ - * "data":[[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,12],[8,9],[9,10],[10,5],[11,8],[12,7],[13,9],[14,4],[15,6]], - * "label":"Total Sessions", - * "color":"#DDDDDD", - * "mode":"ghost" - *},{ - * "data":[[1,74],[2,69],[3,60],[4,17],[5,6],[6,3],[7,13],[8,25],[9,62],[10,34],[11,34],[12,33],[13,34],[14,30],[15,1]], - * "label":"Total Sessions", - * "color":"#333933" - *}], "#dashboard-graph"); - */ - countlyCommon.drawTimeGraph = function(dataPoints, container, bucket, overrideBucket, small, appIdsForNotes, options) { - _.defer(function() { - if (!dataPoints || !dataPoints.length) { - $(container).hide(); - $(container).siblings(".graph-no-data").show(); - return true; - } - else { - $(container).show(); - $(container).siblings(".graph-no-data").hide(); - } + allMonths = _.uniq(allMonths); - var i = 0; - var j = 0; - // Some data points start with [1, XXX] (should be [0, XXX]) and brakes the new tick logic - // Below loops converts the old structures to the new one - if (dataPoints[0].data[0][0] === 1) { - for (i = 0; i < dataPoints.length; i++) { - for (j = 0; j < dataPoints[i].data.length; j++) { - dataPoints[i].data[j][0] -= 1; - } + for (i = 0; i < allMonths.length; i++) { + ticks.push([i, allMonths[i]]); + tickTexts[i] = allMonths[i]; } } - var minValue = dataPoints[0].data[0][1]; - var maxValue = dataPoints[0].data[0][1]; - for (i = 0; i < dataPoints.length; i++) { - for (j = 0; j < dataPoints[i].data.length; j++) { - dataPoints[i].data[j][1] = Math.round(dataPoints[i].data[j][1] * 1000) / 1000; // 3 decimal places max - if (dataPoints[i].data[j][1] < minValue) { - minValue = dataPoints[i].data[j][1]; - } - if (dataPoints[i].data[j][1] > maxValue) { - maxValue = dataPoints[i].data[j][1]; + else if (bucket === "weekly") { + var allWeeks = []; + for (i = 0; i < days; i++) { + start.add(1, 'days'); + if (i === 0 && start.isoWeekday() === 7) { + continue; } + allWeeks.push(start.isoWeek() + " " + start.isoWeekYear()); } - } - var myTickDecimals = 0; - var myMinTickSize = 1; - if (maxValue < 1 && maxValue > 0) { - myTickDecimals = maxValue.toString().length - 2; - myMinTickSize = 0.001; - } - - var graphProperties = { - series: { - lines: { - stack: false, - show: false, - fill: true, - lineWidth: 2.5, - fillColor: { - colors: [ - { opacity: 0 }, - { opacity: 0 } - ] - }, - shadowSize: 0 - }, - splines: { - show: true, - lineWidth: 2.5 - }, - points: { show: true, radius: 0, shadowSize: 0, lineWidth: 2 }, - shadowSize: 0 - }, - crosshair: { mode: "x", color: "rgba(78,78,78,0.4)" }, - grid: { hoverable: true, borderColor: "null", color: "#666", borderWidth: 0, minBorderMargin: 10, labelMargin: 10 }, - xaxis: { tickDecimals: "number", tickSize: 0, tickLength: 0 }, - yaxis: { min: 0, minTickSize: 1, tickDecimals: "number", ticks: 3, position: "right"}, - legend: { show: false, margin: [-25, -44], noColumns: 3, backgroundOpacity: 0 }, - colors: countlyCommon.GRAPH_COLORS, - }; - //overriding values - graphProperties.yaxis.minTickSize = myMinTickSize; - graphProperties.yaxis.tickDecimals = myTickDecimals; - if (myMinTickSize < 1) { - graphProperties.yaxis.tickFormatter = function(number) { - return (Math.round(number * 1000) / 1000).toString(); - }; - } - graphProperties.series.points.show = (dataPoints[0].data.length <= 90); - - if (overrideBucket) { - graphProperties.series.points.radius = 4; - } - - var graphTicks = [], - tickObj = {}; + allWeeks = _.uniq(allWeeks); - if (_period === "month" && !bucket) { - tickObj = countlyCommon.getTickObj("monthly"); - if (tickObj.labelCn === 1) { - for (var kk = 0; kk < dataPoints.length; kk++) { - dataPoints[kk].data = dataPoints[kk].data.slice(0, 1); - } - graphProperties.series.points.radius = 4; - overrideBucket = true;//to get the dots added - } - else if (tickObj.labelCn === 2) { - for (var kkk = 0; kkk < dataPoints.length; kkk++) { - dataPoints[kkk].data = dataPoints[kkk].data.slice(0, 2); - } - } - } - else { - tickObj = countlyCommon.getTickObj(bucket, overrideBucket); - } - if (small) { - for (i = 0; i < tickObj.ticks.length; i = i + 2) { - tickObj.ticks[i][1] = ""; - } - graphProperties.xaxis.font = { - size: 11, - color: "#a2a2a2" - }; - } - - graphProperties.xaxis.max = tickObj.max; - graphProperties.xaxis.min = tickObj.min; - graphProperties.xaxis.ticks = tickObj.ticks; - - graphTicks = tickObj.tickTexts; - //set dashed line for not finished yet - - if (countlyCommon.periodObj.periodContainsToday === true) { - var settings = countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID]; - var tzDate = new Date(new Date().toLocaleString('en-US', { timeZone: settings.timezone })); - for (var z = 0; z < dataPoints.length; z++) { - if (dataPoints[z].mode !== "ghost" && dataPoints[z].mode !== "previous") { - var bDate = new Date(); - if (_period === "hour") { - if (bDate.getDate() === tzDate.getDate()) { - dataPoints[z].dashAfter = tzDate.getHours() - 1; - } - else if (bDate.getDate() > tzDate.getDate()) { - dataPoints[z].dashed = true; //all dashed because app lives still in yesterday - } - //for last - none dashed - because app lives in tomorrow(so don't do anything for this case) - } - else if (_period === "day") { //days in this month - var c = countlyCommon.periodObj.currentPeriodArr.length; - dataPoints[z].dashAfter = c - 2; - } - else if (_period === "month" && bDate.getMonth() <= 2 && (!bucket || bucket === "monthly")) { - dataPoints[z].dashed = true; - } - else { - if (bucket === "hourly") { - dataPoints[z].dashAfter = graphTicks.length - (24 - tzDate.getHours() + 1); - } - else { - dataPoints[z].dashAfter = graphTicks.length - 2; - } - } + for (i = 0; i < allWeeks.length; i++) { + var parts = allWeeks[i].split(" "); + //iso week falls in the year which has thursday of the week + if (parseInt(parts[1]) === moment().isoWeekYear(parseInt(parts[1])).isoWeek(parseInt(parts[0])).isoWeekday(4).year()) { + ticks.push([i, "W" + allWeeks[i]]); - if (typeof dataPoints[z].dashAfter !== 'undefined' && dataPoints[z].dashAfter <= 0) { - delete dataPoints[z].dashAfter; - dataPoints[z].dashed = true; //dash whole line - } + var weekText = countlyCommon.formatDate(moment().isoWeekYear(parseInt(parts[1])).isoWeek(parseInt(parts[0])).isoWeekday(1), ", D MMM YYYY"); + tickTexts[i] = "W" + parts[0] + weekText; } } } + else if (bucket === "hourly") { + for (i = 0; i < days; i++) { + start.add(1, 'days'); - var graphObj = $(container).data("plot"), - keyEventCounter = "A", - keyEvents = []; - //keyEventsIndex = 0; - - - if (!(options && _.isObject(options) && $(container).parents("#dashboard-data").length > 0)) { - countlyCommon.deepObjectExtend(graphProperties, { - series: {lines: {show: true}, splines: {show: false}}, - zoom: {active: true}, - pan: {interactive: true, active: true, mode: "smartLock", frameRate: 120}, - xaxis: {zoomRange: false, panRange: false}, - yaxis: {showZeroTick: true, ticks: 5} - }); - } - - if (options && _.isObject(options)) { - countlyCommon.deepObjectExtend(graphProperties, options); - } + for (var j = 0; j < 24; j++) { + //if (j === 0) { + ticks.push([((24 * i) + j), countlyCommon.formatDate(start, "D MMM") + " 0:00"]); + //} - if (graphObj && countlyCommon.checkGraphType("line", graphObj.getOptions()) && graphObj.getOptions().series && graphObj.getOptions().grid.show && graphObj.getOptions().series.splines && graphObj.getOptions().yaxis.minTickSize === graphProperties.yaxis.minTickSize) { - graphObj = $(container).data("plot"); - if (overrideBucket) { - graphObj.getOptions().series.points.radius = 4; - } - else { - graphObj.getOptions().series.points.radius = 0; + tickTexts.push(countlyCommon.formatDate(start, "D MMM, ") + j + ":00"); + } } - - graphObj.getOptions().xaxes[0].max = tickObj.max; - graphObj.getOptions().xaxes[0].min = tickObj.min; - graphObj.getOptions().xaxes[0].ticks = tickObj.ticks; - - graphObj.setData(dataPoints); - graphObj.setupGrid(); - graphObj.draw(); - } else { - graphObj = $.plot($(container), dataPoints, graphProperties); - } - - /** function calculates min and max - * @param {number} index - index - * @param {object} el - element - * @returns {boolean} true(if not set), else return nothing - */ - var findMinMax = function(index, el) { - // data point is null, this workaround is used to start drawing graph with a certain padding - if (!el[1] && parseInt(el[1]) !== 0) { - return true; - } - - el[1] = parseFloat(el[1]); - - if (el[1] >= tmpMax) { - tmpMax = el[1]; - tmpMaxIndex = el[0]; - } - - if (el[1] <= tmpMin) { - tmpMin = el[1]; - tmpMinIndex = el[0]; - } - }; - var k = 0; - for (k = 0; k < graphObj.getData().length; k++) { - - var tmpMax = 0, - tmpMaxIndex = 0, - tmpMin = 999999999999, - tmpMinIndex = 0, - label = (graphObj.getData()[k].label + "").toLowerCase(); - - if (graphObj.getData()[k].mode === "ghost") { - //keyEventsIndex += graphObj.getData()[k].data.length; - continue; - } - - $.each(graphObj.getData()[k].data, findMinMax); - - if (tmpMax === tmpMin) { - continue; - } - - keyEvents[k] = []; - - keyEvents[k][keyEvents[k].length] = { - data: [tmpMinIndex, tmpMin], - code: keyEventCounter, - color: graphObj.getData()[k].color, - event: "min", - desc: jQuery.i18n.prop('common.graph-min', tmpMin, label, graphTicks[tmpMinIndex]) - }; - - keyEventCounter = String.fromCharCode(keyEventCounter.charCodeAt() + 1); - - keyEvents[k][keyEvents[k].length] = { - data: [tmpMaxIndex, tmpMax], - code: keyEventCounter, - color: graphObj.getData()[k].color, - event: "max", - desc: jQuery.i18n.prop('common.graph-max', tmpMax, label, graphTicks[tmpMaxIndex]) - }; - - keyEventCounter = String.fromCharCode(keyEventCounter.charCodeAt() + 1); - } - - var drawLabels = function() { - var graphWidth = graphObj.width(), - graphHeight = graphObj.height(); - - $(container).find(".graph-key-event-label").remove(); - $(container).find(".graph-note-label").remove(); - - for (k = 0; k < keyEvents.length; k++) { - var bgColor = graphObj.getData()[k].color; - - if (!keyEvents[k]) { - continue; - } - - for (var l = 0; l < keyEvents[k].length; l++) { - var o = graphObj.pointOffset({ x: keyEvents[k][l].data[0], y: keyEvents[k][l].data[1] }); - - if (o.top <= 40) { - o.top = 40; - } - else if (o.top >= (graphHeight + 30)) { - o.top = graphHeight + 30; - } - - if (o.left <= 15) { - o.left = 15; - } - else if (o.left >= (graphWidth - 15)) { - o.left = (graphWidth - 15); - } - - var keyEventLabel = $('
').text(keyEvents[k][l].code); - - keyEventLabel.attr({ - "title": keyEvents[k][l].desc, - "data-points": "[" + keyEvents[k][l].data + "]" - }).css({ - "position": 'absolute', - "left": o.left, - "top": o.top - 33, - "display": 'none', - "background-color": bgColor - }).appendTo(graphObj.getPlaceholder()).show(); - - $(".tipsy").remove(); - keyEventLabel.tipsy({ gravity: $.fn.tipsy.autoWE, offset: 3, html: true }); + if (_period === "day") { + start.add(1, 'days'); + var now = new Date(); + // it will add the count of days of the current month to the x-axis label + var currentMonthCount = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate(); + for (i = 0; i < currentMonthCount; i++) { + ticks.push([i, countlyCommon.formatDate(start, "D MMM")]); + tickTexts[i] = countlyCommon.formatDate(start, "D MMM, dddd"); + start.add(1, 'days'); } } - - // Add note labels to the graph - if (appIdsForNotes && !(countlyGlobal && countlyGlobal.ssr) && !(bucket === "hourly" && dataPoints[0].data.length > 24) && bucket !== "weekly") { - var noteDateIds = countlyCommon.getNoteDateIds(bucket), - frontData = graphObj.getData()[graphObj.getData().length - 1], - startIndex = (!frontData.data[1] && frontData.data[1] !== 0) ? 1 : 0; - for (k = 0, l = startIndex; k < frontData.data.length; k++, l++) { - if (frontData.data[l]) { - var graphPoint = graphObj.pointOffset({ x: frontData.data[l][0], y: frontData.data[l][1] }); - var notes = countlyCommon.getNotesForDateId(noteDateIds[k], appIdsForNotes); - var colors = ["#79a3e9", "#70bbb8", "#e2bc33", "#a786cd", "#dd6b67", "#ece176"]; - - if (notes.length) { - var labelColor = colors[notes[0].color - 1]; - var titleDom = ''; - if (notes.length === 1) { - var noteTime = moment(notes[0].ts).format("D MMM, HH:mm"); - var noteId = notes[0].app_id; - var app = countlyGlobal.apps[noteId] || {}; - titleDom = "
" + noteTime + "
" + app.name + "
" + - "
" + notes[0].note + "
" + - "" + - "
"; - } - else { - var noteDateFormat = "D MMM, YYYY"; - if (countlyCommon.getPeriod() === "month") { - noteDateFormat = "MMM YYYY"; - } - noteTime = moment(notes[0].ts).format(noteDateFormat); - titleDom = "
" + noteTime + "
" + - "
View Notes (" + notes.length + ")
" + - "
"; - } - var graphNoteLabel = $('
'); - graphNoteLabel.attr({ - "title": titleDom, - "data-points": "[" + frontData.data[l] + "]" - }).css({ - "position": 'absolute', - "left": graphPoint.left, - "top": graphPoint.top - 53, - "display": 'none', - "border-color": frontData.color - }).appendTo(graphObj.getPlaceholder()).show(); - - $(".tipsy").remove(); - graphNoteLabel.tipsy({cssClass: 'tipsy-for-note', gravity: $.fn.tipsy.autoWE, offset: 3, html: true, trigger: 'hover', hoverable: true }); - } - } + else if (_period === "prevMonth") { + start = moment().subtract(1, "month").startOf("month"); + //start.add(1,"days"); + let current = new Date(); + let prevMonthCount = new Date(current.getFullYear(), current.getMonth(), 0).getDate(); + for (i = 0; i < prevMonthCount; i++) { + ticks.push([i, countlyCommon.formatDate(start, "D MMM")]); + tickTexts[i] = countlyCommon.formatDate(start, "D MMM, dddd"); + start.add(1, 'days'); } } - }; - - drawLabels(); - - $(container).on("mouseout", function() { - graphObj.unlockCrosshair(); - graphObj.clearCrosshair(); - graphObj.unhighlight(); - $("#graph-tooltip").fadeOut(200, function() { - $(this).remove(); - }); - }); - /** dShows tooltip - * @param {number} dataIndex - index - * @param {object} position - position - * @param {boolean} onPoint - if point found - */ - function showCrosshairTooltip(dataIndex, position, onPoint) { - - //increase dataIndex if ticks are padded - var tickIndex = dataIndex; - if ((tickObj.ticks && tickObj.ticks[0] && tickObj.ticks[0][0] < 0) && (tickObj.tickTexts && tickObj.tickTexts[0] === "")) { - tickIndex++; - } - var tooltip = $("#graph-tooltip"); - var crossHairPos = graphObj.p2c(position); - var minpoz = Math.max(200, tooltip.width()); - var tooltipLeft = (crossHairPos.left < minpoz) ? crossHairPos.left + 20 : crossHairPos.left - tooltip.width() - 20; - tooltip.css({ left: tooltipLeft }); - - if (onPoint) { - var dataSet = graphObj.getData(), - tooltipHTML = "
" + tickObj.tickTexts[tickIndex] + "
"; - - dataSet = _.sortBy(dataSet, function(obj) { - return obj.data[dataIndex][1]; - }); - - for (var m = dataSet.length - 1; m >= 0; --m) { - var series = dataSet[m], - formattedValue = series.data[dataIndex][1]; - - var addMe = ""; - // Change label to previous period if there is a ghost graph - if (series.mode === "ghost") { - series.label = jQuery.i18n.map["common.previous-period"]; - } - var opacity = "1.0"; - //add lines over color block for dashed - if (series.dashed && series.previous) { - addMe = ''; - } - if (series.alpha) { - opacity = series.alpha + ""; - } - if (formattedValue) { - formattedValue = parseFloat(formattedValue).toFixed(2).replace(/[.,]00$/, ""); + else { + var startYear = start.year(); + var endYear = moment().year(); + for (i = 0; i < days; i++) { + start.add(1, 'days'); + if (startYear < endYear) { + ticks.push([i, countlyCommon.formatDate(start, "D MMM YYYY")]); + tickTexts[i] = countlyCommon.formatDate(start, "D MMM YYYY, dddd"); } - if (series.data[dataIndex][2]) { - formattedValue = series.data[dataIndex][2]; // to show customized string value tips + else { + ticks.push([i, countlyCommon.formatDate(start, "D MMM")]); + tickTexts[i] = countlyCommon.formatDate(start, "D MMM, dddd"); } - - tooltipHTML += "
"; - tooltipHTML += "
" + addMe + "
"; - tooltipHTML += "
" + series.label + "
"; - tooltipHTML += "
" + formattedValue + "
"; - tooltipHTML += "
"; - } - - if (tooltip.length) { - tooltip.html(tooltipHTML); - } - else { - tooltip = $("
" + tooltipHTML + "
"); - - $(container).prepend(tooltip); - } - - if (tooltip.is(":visible")) { - tooltip.css({ - "transition": "left .15s" - }); - } - else { - tooltip.fadeIn(); } } } - $(container).unbind("plothover"); - - $(container).bind("plothover", function(event, pos) { - graphObj.unlockCrosshair(); - graphObj.unhighlight(); - - var dataset = graphObj.getData(), - pointFound = false; - - for (i = 0; i < dataset.length; ++i) { - var series = dataset[i]; - - // Find the nearest points, x-wise - for (j = 0; j < series.data.length; ++j) { - var currX = series.data[j][0], - currCrossX = pos.x.toFixed(2); + ticks = _.compact(ticks); + tickTexts = _.compact(tickTexts); + } - if ((currX - 0.10) < currCrossX && (currX + 0.10) > currCrossX) { + var labelCn = ticks.length; + if (!newChart) { + if (ticks.length <= 2) { + limitAdjustment = 0.02; + var tmpTicks = [], + tmpTickTexts = []; - graphObj.lockCrosshair({ - x: series.data[j][0], - y: series.data[j][1] - }); + tmpTickTexts[0] = ""; + tmpTicks[0] = [-0.02, ""]; - graphObj.highlight(series, j); - pointFound = true; - break; - } - } + for (var m = 0; m < ticks.length; m++) { + tmpTicks[m + 1] = [m, ticks[m][1]]; + tmpTickTexts[m + 1] = tickTexts[m]; } - showCrosshairTooltip(j, pos, pointFound); - }); - - - if (!(options && _.isObject(options) && $(container).parents("#dashboard-data").length > 0)) { - var zoomTarget = $(container), - zoomContainer = $(container).parent(); - - zoomContainer.find(".zoom").remove(); - zoomContainer.prepend("
"); - zoomTarget.addClass("pannable"); - zoomContainer.data("zoom", zoomContainer.data("zoom") || 1); - - zoomContainer.find(".zoom-in").tooltipster({ - theme: "tooltipster-borderless", - content: $.i18n.map["common.zoom-in"] - }); - - zoomContainer.find(".zoom-out").tooltipster({ - theme: "tooltipster-borderless", - content: $.i18n.map["common.zoom-out"] - }); - - zoomContainer.find(".zoom-reset").tooltipster({ - theme: "tooltipster-borderless", - content: {}, - functionFormat: function() { - return $.i18n.prop("common.zoom-reset", Math.round(zoomContainer.data("zoom") * 100)); - } - }); - - zoomContainer.find(".zoom-out").off("click").on("click", function() { - var plot = zoomTarget.data("plot"); - plot.zoomOut({ - amount: 1.5, - center: {left: plot.width() / 2, top: plot.height()} - }); - - zoomContainer.data("zoom", zoomContainer.data("zoom") / 1.5); - }); - - zoomContainer.find(".zoom-reset").off("click").on("click", function() { - var plot = zoomTarget.data("plot"); - - plot.zoomOut({ - amount: zoomContainer.data("zoom"), - center: {left: plot.width() / 2, top: plot.height()} - }); - - zoomContainer.data("zoom", 1); - - var yaxis = plot.getAxes().yaxis; - var panOffset = yaxis.p2c(0) - plot.height() + 2; - if (Math.abs(panOffset) > 2) { - plot.pan({top: panOffset}); - } - }); - - zoomContainer.find(".zoom-in").off("click").on("click", function() { - var plot = zoomTarget.data("plot"); - plot.zoom({ - amount: 1.5, - center: {left: plot.width() / 2, top: plot.height()} - }); - zoomContainer.data("zoom", zoomContainer.data("zoom") * 1.5); - }); - - zoomTarget.off("plotzoom").on("plotzoom", function() { - drawLabels(); - }); + tmpTickTexts.push(""); + tmpTicks.push([tmpTicks.length - 1 - 0.98, ""]); - zoomTarget.off("plotpan").on("plotpan", function() { - drawLabels(); - }); + ticks = tmpTicks; + tickTexts = tmpTickTexts; } - }, dataPoints, container, bucket); - }; - - /** - * Draws a gauge with provided value on procided container. - * @memberof countlyCommon - * @param {string|object} targetEl - selector for container or container object itself where to create graph - * @param {number} value - value to display on gauge - * @param {number} maxValue - maximal value of the gauge - * @param {string} gaugeColor - color of the gauge in hexadecimal string as #ffffff - * @param {string|object} textField - selector for container or container object itself where to output textual value - */ - countlyCommon.drawGauge = function(targetEl, value, maxValue, gaugeColor, textField) { - var opts = { - lines: 12, - angle: 0.15, - lineWidth: 0.44, - pointer: { - length: 0.7, - strokeWidth: 0.05, - color: '#000000' - }, - colorStart: gaugeColor, - colorStop: gaugeColor, - strokeColor: '#E0E0E0', - generateGradient: true - }; - - var gauge = new Gauge($(targetEl)[0]).setOptions(opts); - - if (textField) { - gauge.setTextField($(textField)[0]); - } - - gauge.maxValue = maxValue; - gauge.set(1); - gauge.set(value); - }; - - /** - * Draws horizibtally stacked bars like in platforms and density analytic sections. - * @memberof countlyCommon - * @param {array} data - data to draw in form of [{"data":[[0,85]],"label":"Test1"},{"data":[[0,79]],"label":"Test2"},{"data":[[0,78]],"label":"Test3"}] - * @param {object|string} intoElement - selector for container or container object itself where to create graph - * @param {number} colorIndex - index of color from {@link countlyCommon.GRAPH_COLORS} - */ - countlyCommon.drawHorizontalStackedBars = function(data, intoElement, colorIndex) { - var processedData = [], - tmpProcessedData = [], - totalCount = 0, - maxToDisplay = 10, - barHeight = 30; - var i = 0; - for (i = 0; i < data.length; i++) { - tmpProcessedData.push({ - label: data[i].label, - count: data[i].data[0][1], - index: i - }); - - totalCount += data[i].data[0][1]; - } - - var totalPerc = 0, - proCount = 0; + else if (!skipReduction && ticks.length > 10) { + var reducedTicks = [], + step = (Math.floor(ticks.length / 10) < 1) ? 1 : Math.floor(ticks.length / 10), + pickStartIndex = (Math.floor(ticks.length / 30) < 1) ? 1 : Math.floor(ticks.length / 30); - for (i = 0; i < tmpProcessedData.length; i++) { - if (i >= maxToDisplay) { - processedData.push({ - label: "Other", - count: totalCount - proCount, - perc: countlyCommon.round((100 - totalPerc), 2) + "%", - index: i - }); + for (var l = pickStartIndex; l < (ticks.length - 1); l = l + step) { + reducedTicks.push(ticks[l]); + } - break; + ticks = reducedTicks; } + else { + ticks[0] = null; - var perc = countlyCommon.round((tmpProcessedData[i].count / totalCount) * 100, 2); - tmpProcessedData[i].perc = perc + "%"; - totalPerc += perc; - proCount += tmpProcessedData[i].count; - - processedData.push(tmpProcessedData[i]); - } - - if (processedData.length > 0) { - var percentSoFar = 0; - - var chart = d3.select(intoElement) - .attr("width", "100%") - .attr("height", barHeight); - - var bar = chart.selectAll("g") - .data(processedData) - .enter().append("g"); - - bar.append("rect") - .attr("width", function(d) { - return ((d.count / totalCount) * 100) + "%"; - }) - .attr("x", function(d) { - var myPercent = percentSoFar; - percentSoFar = percentSoFar + (100 * (d.count / totalCount)); - - return myPercent + "%"; - }) - .attr("height", barHeight) - .attr("fill", function(d) { - if (colorIndex || colorIndex === 0) { - return countlyCommon.GRAPH_COLORS[colorIndex]; - } - else { - return countlyCommon.GRAPH_COLORS[d.index]; - } - }) - .attr("stroke", "#FFF") - .attr("stroke-width", 2); - - if (colorIndex || colorIndex === 0) { - bar.attr("opacity", function(d) { - return 1 - (0.05 * d.index); - }); + // Hourly ticks already contain 23 empty slots at the end + if (!(bucket === "hourly" && days !== 1)) { + ticks[ticks.length - 1] = null; + } } + } - percentSoFar = 0; - - bar.append("foreignObject") - .attr("width", function(d) { - return ((d.count / totalCount) * 100) + "%"; - }) - .attr("height", barHeight) - .attr("x", function(d) { - var myPercent = percentSoFar; - percentSoFar = percentSoFar + (100 * (d.count / totalCount)); - - return myPercent + "%"; - }) - .append("xhtml:div") - .attr("class", "hsb-tip") - .html(function(d) { - return "
" + d.perc + "
"; - }); - - percentSoFar = 0; + return { + min: 0 - limitAdjustment, + max: (limitAdjustment) ? tickTexts.length - 3 + limitAdjustment : tickTexts.length - 1, + tickTexts: tickTexts, + ticks: _.compact(ticks), + labelCn: labelCn + }; + }; - bar.append("text") - .attr("x", function(d) { - var myPercent = percentSoFar; - percentSoFar = percentSoFar + (100 * (d.count / totalCount)); + /** + * Checks if current graph type matches the one being drawn + * @memberof countlyCommon + * @param {string} type - graph type + * @param {object} settings - graph settings + * @returns {boolean} Return true if type is the same + */ + countlyCommon.checkGraphType = function(type, settings) { + var eType = "line"; + if (settings && settings.series && settings.series.bars && settings.series.bars.show === true) { + if (settings.series.stack === true) { + eType = "bar"; + } + else { + eType = "seperate-bar"; + } + } + else if (settings && settings.series && settings.series.pie && settings.series.pie.show === true) { + eType = "pie"; + } - return myPercent + 0.5 + "%"; - }) - .attr("dy", "1.35em") - .text(function(d) { - return d.label; - }); + if (type === eType) { + return true; } else { - var chart1 = d3.select(intoElement) - .attr("width", "100%") - .attr("height", barHeight); - - var bar1 = chart1.selectAll("g") - .data([{ text: jQuery.i18n.map["common.bar.no-data"] }]) - .enter().append("g"); - - bar1.append("rect") - .attr("width", "100%") - .attr("height", barHeight) - .attr("fill", "#FBFBFB") - .attr("stroke", "#FFF") - .attr("stroke-width", 2); - - bar1.append("foreignObject") - .attr("width", "100%") - .attr("height", barHeight) - .append("xhtml:div") - .attr("class", "no-data") - .html(function(d) { - return d.text; - }); + return false; } }; @@ -2659,281 +1810,60 @@ else { dbObj[year]["w" + weekly][level1][level2] = tmpUpdateObj[level1][level2]; } - } - } - } - - // Fix update of total user count - - if (updateObj[year]) { - if (updateObj[year].u) { - if (!dbObj[year]) { - dbObj[year] = {}; - } - - dbObj[year].u = updateObj[year].u; - } - - if (updateObj[year][month] && updateObj[year][month].u) { - if (!dbObj[year]) { - dbObj[year] = {}; - } - - if (!dbObj[year][month]) { - dbObj[year][month] = {}; - } - - dbObj[year][month].u = updateObj[year][month].u; - } - - if (updateObj[year]["w" + weekly] && updateObj[year]["w" + weekly].u) { - if (!dbObj[year]) { - dbObj[year] = {}; - } - - if (!dbObj[year]["w" + weekly]) { - dbObj[year]["w" + weekly] = {}; - } - - dbObj[year]["w" + weekly].u = updateObj[year]["w" + weekly].u; - } - } - }; - - /** - * Convert string to first letter uppercase and all other letters - lowercase for each word - * @memberof countlyCommon - * @param {string} str - string to convert - * @returns {string} converted string - * @example - * //outputs Hello World - * countlyCommon.toFirstUpper("hello world"); - */ - countlyCommon.toFirstUpper = function(str) { - return str.replace(/\w\S*/g, function(txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); - }; - - /** - * Safe division between numbers providing 0 as result in cases when dividing by 0 - * @memberof countlyCommon - * @param {number} val1 - number which to divide - * @param {number} val2 - number by which to divide - * @returns {number} result of division - * @example - * //outputs 0 - * countlyCommon.divide(100, 0); - */ - countlyCommon.divide = function(val1, val2) { - var temp = val1 / val2; - - if (!temp || temp === Number.POSITIVE_INFINITY) { - temp = 0; - } - - return temp; - }; - - /** - * Get Date graph ticks - * @memberof countlyCommon - * @param {string} bucket - time bucket, accepted values, hourly, weekly, monthly - * @param {boolean} overrideBucket - override existing bucket logic and simply use current date for generating ticks - * @param {boolean} newChart - new chart implementation - * @returns {object} object containing tick texts and ticks to use on time graphs - * @example Example output - *{ - * "min":0, - * "max":29, - * "tickTexts":["22 Dec, Thursday","23 Dec, Friday","24 Dec, Saturday","25 Dec, Sunday","26 Dec, Monday","27 Dec, Tuesday","28 Dec, Wednesday", - * "29 Dec, Thursday","30 Dec, Friday","31 Dec, Saturday","1 Jan, Sunday","2 Jan, Monday","3 Jan, Tuesday","4 Jan, Wednesday","5 Jan, Thursday", - * "6 Jan, Friday","7 Jan, Saturday","8 Jan, Sunday","9 Jan, Monday","10 Jan, Tuesday","11 Jan, Wednesday","12 Jan, Thursday","13 Jan, Friday", - * "14 Jan, Saturday","15 Jan, Sunday","16 Jan, Monday","17 Jan, Tuesday","18 Jan, Wednesday","19 Jan, Thursday","20 Jan, Friday"], - * "ticks":[[1,"23 Dec"],[4,"26 Dec"],[7,"29 Dec"],[10,"1 Jan"],[13,"4 Jan"],[16,"7 Jan"],[19,"10 Jan"],[22,"13 Jan"],[25,"16 Jan"],[28,"19 Jan"]] - *} - */ - countlyCommon.getTickObj = function(bucket, overrideBucket, newChart) { - var days = parseInt(countlyCommon.periodObj.numberOfDays, 10), - ticks = [], - tickTexts = [], - skipReduction = false, - limitAdjustment = 0; - - if (overrideBucket) { - var thisDay; - if (countlyCommon.periodObj.activePeriod) { - thisDay = moment(countlyCommon.periodObj.activePeriod, "YYYY.M.D"); - } - else { - thisDay = moment(countlyCommon.periodObj.currentPeriodArr[0], "YYYY.M.D"); - } - ticks.push([0, countlyCommon.formatDate(thisDay, "D MMM")]); - tickTexts[0] = countlyCommon.formatDate(thisDay, "D MMM, dddd"); - } - else if ((days === 1 && _period !== "month" && _period !== "day") || (days === 1 && bucket === "hourly")) { - //When period is an array or string like Xdays, Xweeks - for (var z = 0; z < 24; z++) { - ticks.push([z, (z + ":00")]); - tickTexts.push((z + ":00")); - } - skipReduction = true; - } - else { - var start = moment().subtract(days, 'days'); - if (Object.prototype.toString.call(countlyCommon.getPeriod()) === '[object Array]') { - start = moment(countlyCommon.periodObj.currentPeriodArr[countlyCommon.periodObj.currentPeriodArr.length - 1], "YYYY.MM.DD").subtract(days, 'days'); - } - var i = 0; - if (bucket === "monthly") { - var allMonths = []; - - //so we would not start from previous year - start.add(1, 'day'); - - var monthCount = 12; - - for (i = 0; i < monthCount; i++) { - allMonths.push(start.format(countlyCommon.getDateFormat("MMM YYYY"))); - start.add(1, 'months'); - } - - allMonths = _.uniq(allMonths); - - for (i = 0; i < allMonths.length; i++) { - ticks.push([i, allMonths[i]]); - tickTexts[i] = allMonths[i]; - } - } - else if (bucket === "weekly") { - var allWeeks = []; - for (i = 0; i < days; i++) { - start.add(1, 'days'); - if (i === 0 && start.isoWeekday() === 7) { - continue; - } - allWeeks.push(start.isoWeek() + " " + start.isoWeekYear()); - } - - allWeeks = _.uniq(allWeeks); - - for (i = 0; i < allWeeks.length; i++) { - var parts = allWeeks[i].split(" "); - //iso week falls in the year which has thursday of the week - if (parseInt(parts[1]) === moment().isoWeekYear(parseInt(parts[1])).isoWeek(parseInt(parts[0])).isoWeekday(4).year()) { - ticks.push([i, "W" + allWeeks[i]]); - - var weekText = countlyCommon.formatDate(moment().isoWeekYear(parseInt(parts[1])).isoWeek(parseInt(parts[0])).isoWeekday(1), ", D MMM YYYY"); - tickTexts[i] = "W" + parts[0] + weekText; - } - } - } - else if (bucket === "hourly") { - for (i = 0; i < days; i++) { - start.add(1, 'days'); - - for (var j = 0; j < 24; j++) { - //if (j === 0) { - ticks.push([((24 * i) + j), countlyCommon.formatDate(start, "D MMM") + " 0:00"]); - //} - - tickTexts.push(countlyCommon.formatDate(start, "D MMM, ") + j + ":00"); - } - } - } - else { - if (_period === "day") { - start.add(1, 'days'); - var now = new Date(); - // it will add the count of days of the current month to the x-axis label - var currentMonthCount = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate(); - for (i = 0; i < currentMonthCount; i++) { - ticks.push([i, countlyCommon.formatDate(start, "D MMM")]); - tickTexts[i] = countlyCommon.formatDate(start, "D MMM, dddd"); - start.add(1, 'days'); - } - } - else if (_period === "prevMonth") { - start = moment().subtract(1, "month").startOf("month"); - //start.add(1,"days"); - let current = new Date(); - let prevMonthCount = new Date(current.getFullYear(), current.getMonth(), 0).getDate(); - for (i = 0; i < prevMonthCount; i++) { - ticks.push([i, countlyCommon.formatDate(start, "D MMM")]); - tickTexts[i] = countlyCommon.formatDate(start, "D MMM, dddd"); - start.add(1, 'days'); - } - } - else { - var startYear = start.year(); - var endYear = moment().year(); - for (i = 0; i < days; i++) { - start.add(1, 'days'); - if (startYear < endYear) { - ticks.push([i, countlyCommon.formatDate(start, "D MMM YYYY")]); - tickTexts[i] = countlyCommon.formatDate(start, "D MMM YYYY, dddd"); - } - else { - ticks.push([i, countlyCommon.formatDate(start, "D MMM")]); - tickTexts[i] = countlyCommon.formatDate(start, "D MMM, dddd"); - } - } - } - } - - ticks = _.compact(ticks); - tickTexts = _.compact(tickTexts); + } + } } - var labelCn = ticks.length; - if (!newChart) { - if (ticks.length <= 2) { - limitAdjustment = 0.02; - var tmpTicks = [], - tmpTickTexts = []; - - tmpTickTexts[0] = ""; - tmpTicks[0] = [-0.02, ""]; + // Fix update of total user count - for (var m = 0; m < ticks.length; m++) { - tmpTicks[m + 1] = [m, ticks[m][1]]; - tmpTickTexts[m + 1] = tickTexts[m]; + if (updateObj[year]) { + if (updateObj[year].u) { + if (!dbObj[year]) { + dbObj[year] = {}; } - tmpTickTexts.push(""); - tmpTicks.push([tmpTicks.length - 1 - 0.98, ""]); - - ticks = tmpTicks; - tickTexts = tmpTickTexts; + dbObj[year].u = updateObj[year].u; } - else if (!skipReduction && ticks.length > 10) { - var reducedTicks = [], - step = (Math.floor(ticks.length / 10) < 1) ? 1 : Math.floor(ticks.length / 10), - pickStartIndex = (Math.floor(ticks.length / 30) < 1) ? 1 : Math.floor(ticks.length / 30); - for (var l = pickStartIndex; l < (ticks.length - 1); l = l + step) { - reducedTicks.push(ticks[l]); + if (updateObj[year][month] && updateObj[year][month].u) { + if (!dbObj[year]) { + dbObj[year] = {}; } - ticks = reducedTicks; + if (!dbObj[year][month]) { + dbObj[year][month] = {}; + } + + dbObj[year][month].u = updateObj[year][month].u; } - else { - ticks[0] = null; - // Hourly ticks already contain 23 empty slots at the end - if (!(bucket === "hourly" && days !== 1)) { - ticks[ticks.length - 1] = null; + if (updateObj[year]["w" + weekly] && updateObj[year]["w" + weekly].u) { + if (!dbObj[year]) { + dbObj[year] = {}; } + + if (!dbObj[year]["w" + weekly]) { + dbObj[year]["w" + weekly] = {}; + } + + dbObj[year]["w" + weekly].u = updateObj[year]["w" + weekly].u; } } + }; - return { - min: 0 - limitAdjustment, - max: (limitAdjustment) ? tickTexts.length - 3 + limitAdjustment : tickTexts.length - 1, - tickTexts: tickTexts, - ticks: _.compact(ticks), - labelCn: labelCn - }; + /** + * Convert string to first letter uppercase and all other letters - lowercase for each word + * @memberof countlyCommon + * @param {string} str - string to convert + * @returns {string} converted string + * @example + * //outputs Hello World + * countlyCommon.toFirstUpper("hello world"); + */ + countlyCommon.toFirstUpper = function(str) { + return str.replace(/\w\S*/g, function(txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + }); }; /** @@ -3019,161 +1949,6 @@ return countlyCommon.formatNumber(x); }; - /** - * Pad number with specified character from left to specified length - * @memberof countlyCommon - * @param {number} n - number to pad - * @param {number} width - pad to what length in symboles - * @param {string} z - character to pad with, default 0 - * @returns {string} padded number - * @example - * //outputs 0012 - * countlyCommon.pad(12, 4, "0"); - */ - countlyCommon.pad = function(n, width, z) { - z = z || '0'; - n = n + ''; - return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; - }; - - countlyCommon.getNoteDateIds = function(bucket) { - var _periodObj = countlyCommon.periodObj, - dateIds = [], - dotSplit = [], - tmpDateStr = ""; - var i = 0; - var j = 0; - if (!_periodObj.isSpecialPeriod && !bucket) { - for (i = _periodObj.periodMin; i < (_periodObj.periodMax + 1); i++) { - dotSplit = (_periodObj.activePeriod + "." + i).split("."); - tmpDateStr = ""; - - for (j = 0; j < dotSplit.length; j++) { - if (dotSplit[j].length === 1) { - tmpDateStr += "0" + dotSplit[j]; - } - else { - tmpDateStr += dotSplit[j]; - } - } - - dateIds.push(tmpDateStr); - } - } - else { - if (!_periodObj.currentPeriodArr && bucket === "daily") { - var tmpDate = new Date(); - _periodObj.currentPeriodArr = []; - - if (countlyCommon.getPeriod() === "month") { - for (i = 0; i < (tmpDate.getMonth() + 1); i++) { - var daysInMonth = moment().month(i).daysInMonth(); - - for (j = 0; j < daysInMonth; j++) { - _periodObj.currentPeriodArr.push(_periodObj.activePeriod + "." + (i + 1) + "." + (j + 1)); - - // If current day of current month, just break - if ((i === tmpDate.getMonth()) && (j === (tmpDate.getDate() - 1))) { - break; - } - } - } - } - else if (countlyCommon.getPeriod() === "day") { - for (i = 0; i < tmpDate.getDate(); i++) { - _periodObj.currentPeriodArr.push(_periodObj.activePeriod + "." + (i + 1)); - } - } - else { - _periodObj.currentPeriodArr.push(_periodObj.activePeriod); - } - } - - for (i = 0; i < (_periodObj.currentPeriodArr.length); i++) { - dotSplit = _periodObj.currentPeriodArr[i].split("."); - tmpDateStr = ""; - - for (j = 0; j < dotSplit.length; j++) { - if (dotSplit[j].length === 1) { - tmpDateStr += "0" + dotSplit[j]; - } - else { - tmpDateStr += dotSplit[j]; - } - } - - dateIds.push(tmpDateStr); - } - } - - var tmpDateIds = []; - switch (bucket) { - case "hourly": - for (i = 0; i < 25; i++) { - tmpDateIds.push(dateIds[0] + ((i < 10) ? "0" + i : i)); - } - - dateIds = tmpDateIds; - break; - case "monthly": - for (i = 0; i < dateIds.length; i++) { - countlyCommon.arrayAddUniq(tmpDateIds, moment(dateIds[i], "YYYYMMDD").format("YYYYMM")); - } - - dateIds = tmpDateIds; - break; - } - - return dateIds; - }; - - countlyCommon.getNotesForDateId = function(dateId, appIdsForNotes) { - var ret = []; - var notes = []; - appIdsForNotes && appIdsForNotes.forEach(function(appId) { - if (countlyGlobal.apps[appId] && countlyGlobal.apps[appId].notes) { - notes = notes.concat(countlyGlobal.apps[appId].notes); - } - }); - if (notes.length === 0) { - return ret; - } - for (var i = 0; i < notes.length; i++) { - if (!notes[i].dateId) { - notes[i].dateId = moment(notes[i].ts).format("YYYYMMDDHHmm"); - } - if (notes[i].dateId.indexOf(dateId) === 0) { - ret = ret.concat([notes[i]]); - } - } - return ret; - }; - - /** - * Add item or array to existing array only if values are not already in original array. given array is modified. - * @memberof countlyCommon - * @param {array} arr - original array where to add unique elements - * @param {string|number|array} item - item to add or array to merge - */ - countlyCommon.arrayAddUniq = function(arr, item) { - if (!arr) { - arr = []; - } - - if (toString.call(item) === "[object Array]") { - for (var i = 0; i < item.length; i++) { - if (arr.indexOf(item[i]) === -1) { - arr[arr.length] = item[i]; - } - } - } - else { - if (arr.indexOf(item) === -1) { - arr[arr.length] = item; - } - } - }; - /** * Format timestamp to twitter like time ago format with real date as tooltip and hidden data for exporting * @memberof countlyCommon @@ -3730,10 +2505,6 @@ return format; }; - countlyCommon.showTooltip = function(args) { - showTooltip(args); - }; - /** * Getter for period object * @memberof countlyCommon @@ -3757,42 +2528,6 @@ return calculatePeriodObject(period, currentTimeStamp); }; - countlyCommon.calculateUniqueFromMap = function(dbObj, uniqueMap) { - var u = 0; - for (var year in uniqueMap) { - var yearVal = countlyCommon.getDescendantProp(dbObj, year) || {}; - var calcYearVal = 0; - if (Object.keys(uniqueMap[year]).length > 0) { - for (var month in uniqueMap[year]) { - var ob = countlyCommon.getDescendantProp(dbObj, year + "." + month) || {}; - var monthVal = ob.u || 0; - var calcMonthVal = 0; - if (Object.keys(uniqueMap[year][month]).length > 0) { - for (var week in uniqueMap[year][month]) { - var ob2 = countlyCommon.getDescendantProp(dbObj, year + "." + week) || {}; - var weekVal = ob2.u || 0; - var calcWeekVal = 0; - - for (var day in uniqueMap[year][month][week]) { - var ob3 = countlyCommon.getDescendantProp(dbObj, year + "." + month + "." + day) || {}; - calcWeekVal += ob3.u || 0; - } - calcMonthVal += Math.min(weekVal, calcWeekVal); - } - } - else { - calcMonthVal = monthVal; - } - calcYearVal += Math.min(monthVal, calcMonthVal); - } - } - else { - calcYearVal = yearVal; - } - u += Math.min((yearVal.u || 0), calcYearVal); - } - return u; - }; /** * Calculate period function * @param {object} period - given period @@ -4389,61 +3124,6 @@ } } - /** Function to show the tooltip when any data point in the graph is hovered on. - * @param {object} args - tooltip info - * @param {number} args.x - x position - * @param {number} args.y- y position - * @param {string} args.contents - content for tooltip - * @param {string} args.title - title - * @param {string} args.notes - notes - */ - function showTooltip(args) { - var x = args.x || 0, - y = args.y || 0, - contents = args.contents, - title = args.title, - notes = args.notes; - - var tooltip = $('
').append('' + contents + ''); - - if (title) { - tooltip.prepend('' + title + ''); - } - - if (notes) { - var noteLines = (notes + "").split("==="); - - for (var i = 0; i < noteLines.length; i++) { - tooltip.append("
– " + noteLines[i] + "
"); - } - } - - $("#content").append("
" + $('
').append(tooltip.clone()).html() + "
"); - var widthVal = $("#graph-tooltip").outerWidth(), - heightVal = $("#graph-tooltip").outerHeight(); - $("#tooltip-calc").remove(); - - var newLeft = (x - (widthVal / 2)), - xReach = (x + (widthVal / 2)); - - if (notes) { - newLeft += 10.5; - xReach += 10.5; - } - - if (xReach > $(window).width()) { - newLeft = (x - widthVal); - } - else if (xReach < 340) { - newLeft = x; - } - - tooltip.css({ - top: y - heightVal - 20, - left: newLeft - }).appendTo("body").show(); - } - /** function adds leading zero to value. * @param {number} value - given value * @returns {string|number} fixed value @@ -4607,38 +3287,6 @@ } }; - /** - * add one more column in chartDP[index].data to show string in dp - * @memberof countlyCommon - * @param {array} chartDPs - chart data points - * @param {string} labelName - label name - * @return {array} chartDPs - * @example - * for example: - * chartDPs = [ - * {color:"#88BBC8", label:"duration", data:[[0, 23], [1, 22]}], - * {color:"#88BBC8", label:"count", data:[[0, 3], [1, 3]}], - * } - * lable = 'duration', - * - * will return - * chartDPs = [ - * {color:"#88BBC8", label:"duration", data:[[0, 23, "00:00:23"], [1, 22, "00:00:22"]}], - * {color:"#88BBC8", label:"count", data:[[0, 3], [1, 3]}], - * } - */ - countlyCommon.formatSecondForDP = function(chartDPs, labelName) { - for (var k = 0; k < chartDPs.length; k++) { - if (chartDPs[k].label === labelName) { - var dp = chartDPs[k]; - for (var i = 0; i < dp.data.length; i++) { - dp.data[i][2] = countlyCommon.formatSecond(dp.data[i][1]); - } - } - } - return chartDPs; - }; - /** * Getter/setter for dot notatons: * @memberof countlyCommon @@ -4674,73 +3322,6 @@ } }; - /** - * Save division, handling division by 0 and rounding up to 2 decimals - * @memberof countlyCommon - * @param {number} dividend - object to use - * @param {number} divisor - path of properties to get - * @returns {number} division - */ - countlyCommon.safeDivision = function(dividend, divisor) { - var tmpAvgVal; - tmpAvgVal = dividend / divisor; - if (!tmpAvgVal || tmpAvgVal === Number.POSITIVE_INFINITY) { - tmpAvgVal = 0; - } - return tmpAvgVal.toFixed(2); - }; - - /** - * Returns a string with a language-sensitive representation of this number. - * @memberof countlyCommon - * @param {string} value - expected value to be formatted - * @param {number} currencyVal - expected currency to be formatted - * @returns {string} formatted value - */ - countlyCommon.numberToLocaleString = function(value, currencyVal) { - if (!value) { - return 0; - } - if (typeof value !== 'number') { - value = countlyCommon.localeStringToNumber(value); - } - - return value.toLocaleString('en-US', { currency: currencyVal || "USD" }); - }; - - /** - * Formats and returns local string to number - * @memberof countlyCommon - * @param {string} localeString - expected value to be formatted - * @returns {number} formatted value - */ - countlyCommon.localeStringToNumber = function(localeString) { - var number = null, fractionFloat; - if (localeString && typeof localeString === "string") { - var isContainDot = localeString.includes('.'); - - if (isContainDot) { - if (localeString.split('.')[1].length) { - var fractionString = localeString.split('.')[1]; - var fractionNumber = parseInt(fractionString); - var pow = fractionString.length; - fractionFloat = fractionNumber / Math.pow(10, pow); - } - else { - fractionFloat = 0.00; - } - - number = parseFloat(localeString.split('.')[0].replaceAll(',', '')) + fractionFloat; - } - else { - number = parseInt(localeString.replaceAll(',', '')); - } - - return number; - } - return localeString; - }; - /** * Get timestamp range in format as [startTime, endTime] with period and base time * @memberof countlyCommon @@ -4948,30 +3529,6 @@ } }; - countlyCommon.getNotesPopup = function(dateId, appIds) { - var notes = countlyCommon.getNotesForDateId(dateId, appIds); - var dialog = $("#cly-popup").clone().removeAttr("id").addClass('graph-notes-popup'); - dialog.removeClass('black'); - var content = dialog.find(".content"); - var notesPopupHTML = Handlebars.compile($("#graph-notes-popup").html()); - notes.forEach(function(n) { - n.ts_display = moment(n.ts).format("D MMM, YYYY, HH:mm"); - var app = countlyGlobal.apps[n.app_id] || {}; - n.app_name = app.name; - }); - var noteDateFormat = "D MMM, YYYY"; - if (countlyCommon.getPeriod() === "month") { - noteDateFormat = "MMM YYYY"; - } - var notePopupTitleTime = moment(notes[0].ts).format(noteDateFormat); - content.html(notesPopupHTML({notes: notes, notePopupTitleTime: notePopupTitleTime})); - CountlyHelpers.revealDialog(dialog); - $(".close-note-popup-button").off("click").on("click", function() { - CountlyHelpers.removeDialog(dialog); - }); - window.app.localize(); - }; - countlyCommon.getGraphNotes = function(appIds, filter, callBack) { if (!appIds) { appIds = []; @@ -5014,47 +3571,6 @@ } }); }; - /** - * Compare two versions - * @memberof countlyCommon - * @param {String} a, First version - * @param {String} b, Second version - * @returns {Number} returns -1, 0 or 1 by result of comparing - */ - countlyCommon.compareVersions = function(a, b) { - var aParts = a.split('.'); - var bParts = b.split('.'); - - for (var j = 0; j < aParts.length && j < bParts.length; j++) { - var aPartNum = parseInt(aParts[j], 10); - var bPartNum = parseInt(bParts[j], 10); - - var cmp = Math.sign(aPartNum - bPartNum); - - if (cmp !== 0) { - return cmp; - } - } - - if (aParts.length === bParts.length) { - return 0; - } - - var longestArray = aParts; - if (bParts.length > longestArray.length) { - longestArray = bParts; - } - - var continueIndex = Math.min(aParts.length, bParts.length); - - for (var i = continueIndex; i < longestArray.length; i += 1) { - if (parseInt(longestArray[i], 10) > 0) { - return longestArray === bParts ? -1 : +1; - } - } - - return 0; - }; /** * Converts cohort time period to string. @@ -5255,28 +3771,6 @@ return obj; }; - /** - * Function to change HEX to RGBA - * @param {String} h - hex code - * @returns {String} rgba string - */ - countlyCommon.hexToRgba = function(h) { - var r = 0, g = 0, b = 0, a = 1; - - if (h.length === 4) { - r = "0x" + h[1] + h[1]; - g = "0x" + h[2] + h[2]; - b = "0x" + h[3] + h[3]; - } - else if (h.length === 7) { - r = "0x" + h[1] + h[2]; - g = "0x" + h[3] + h[4]; - b = "0x" + h[5] + h[6]; - } - - return "rgba(" + +r + "," + +g + "," + +b + "," + a + ")"; - }; - /** * Unescapes provided string. * -- Please use carefully -- @@ -5291,19 +3785,6 @@ } return _.unescape(text || df).replace(/'/g, "'"); }; - - /** - * Remove spaces, tabs, and newlines from the start and end of the string - * @param {String} str - Arbitrary string - * @returns {String} Trimmed string - */ - countlyCommon.trimWhitespaceStartEnd = function(str) { - if (typeof str !== 'string') { - return str; - } - str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); - return str; - }; }; window.CommonConstructor = CommonConstructor; diff --git a/frontend/express/public/javascripts/countly/countly.helpers.js b/frontend/express/public/javascripts/countly/countly.helpers.js index 50b3283efae..070b566b2aa 100644 --- a/frontend/express/public/javascripts/countly/countly.helpers.js +++ b/frontend/express/public/javascripts/countly/countly.helpers.js @@ -1,4 +1,4 @@ -/* global _, countlyGlobal, countlyCommon, _JSONEditor, app, TableTools, countlyDeviceDetails, moment, jQuery, $, store, Handlebars, countlyTaskManager, countlyVue*/ +/* global _, countlyGlobal, countlyCommon, app, countlyDeviceDetails, jQuery, $, countlyVue*/ /* Some helper functions to be used throughout all views. Includes custom popup, alert and confirm dialogs for the time being. @@ -84,226 +84,6 @@ delete countlyGlobal.message; }; - /** - * Display modal popup that requires confirmation input from user and optional checkbox - * @param {string} msg - message to display in alert popup - * @param {string} type - type of alert red for errors and green for success - * @param {boolean} hasCheckbox - popup has checkbox? or not. - * @param {string} checkboxTitle - title of checkbox element - * @param {function} callback - to determine result of the input - * @param {array=} buttonText - [0] element for cancle button text and [1] element for confirm button text - * @example - * CountlyHelpers.confirmWithCheckbox("Are you sure?", "red", true, "Chechbox label text", function (result) { - * if (!result) { - * //user did not confirm, just exit - * return true; - * } - * //user confirmed, do what you need to do - * }); - */ - CountlyHelpers.confirmWithCheckbox = function(msg, type, hasCheckbox, checkboxTitle, callback, buttonText) { - var dialog = $("#cly-confirm").clone(); - dialog.removeAttr("id"); - dialog.find(".message").html(msg); - if (hasCheckbox) { - dialog.find(".buttons").append("" + checkboxTitle + ""); - } - if (buttonText && buttonText.length === 2) { - dialog.find("#dialog-cancel").text(buttonText[0]); - dialog.find("#dialog-continue").text(buttonText[1]); - } - - dialog.addClass(type); - revealDialog(dialog); - - dialog.find("#dialog-cancel").on('click', function() { - callback(false); - }); - - dialog.find("#dialog-continue").on('click', function() { - callback(true); - }); - }; - - /** - * Create drawer - * @param {object} options - Options object - * @param {string} options.id - Optional. Id for drawer - * @param {object} options.template - Handelbars template object(optional). After creating element from template ".details" and ".buttons" are moved to drawer object. Other parts are not used. - * @param {object} options.templateData - Data for template (optional) - * @param {object} options.form - (optional) Existing html element with form. ".details" and ".buttons" are moved to drawer object. Options.form element is removed. - * @param {string} options.title - (optional) Title for drawer - * @param {object} options.root - (optional) Element to which drawer should be appended. If not set drawer is appended to (".widget"). - * @param {boolean} options.saveButtonText - (optional) If there is only single button and there is not set any button using form or template - then passing this string sets text for save button. - * @param {boolean} options.preventBaseReset - (optional) If true then when reseting form base reset function,which empties text fields won't be called. - * @param {object} options.applyChangeTriggers -(optional) If true - Ads event listeners on textaria and input[text], cly-multi-select, cly-single select in form to trigger "cly-drawer-form-updated" on drawer. * This event callls options.onUpdate function. - * @param {function} options.onUpdate - (optional) function called when "cly-drawer-form-updated" is triggered on drawer. - * @param {function} options.onClose(callback) - (optional) function called when calling drawer.close() or hitting [X] button. Has one parameter - callback function. Only if callback function returns true as first param - drawer is closed. - * @param {function} options.onClosed(callback) - (optional) function called after drawer is successfully closed. - * @returns {object} Drawer object - * @example - * var drawer = CountlyHelpers.createDrawer({ - * id: "my-id", - * form: $('#id-of-elem'), //if using form - * title: 'My Drawer title', - * applyChangeTriggers: true, //add triggers - * onUpdate: function(){ - * //check all fields here - * }, - * resetForm: function() { - * //empty all fields. Text fields are emptied automatically because options.preventBaseReset is not set. - * }, - * onClose: function(callback) { - * callback(true); //allow closing form - * callback(false); //don't close form - * }, - * onClosed: function() { - * //form is closed - * } - * }); - * //After creation drawer object is returned. Object has multiple functions: - * drawer.open() //opens drawer - * drawer.close(force); //closes drawer. force - close anyway even if there is onClose function set. (Withot validating) - * drawer.resetForm(); //resets drawer (Normally called after closing or before opening drawer) - * - */ - CountlyHelpers.createDrawer = function(options) { - var drawer = $("#cly-drawer-template").clone(); - drawer.removeAttr("id"); - - if (options.template) { //from template or string - var newPage = ""; - if (typeof options.template === 'function') { - newPage = $("
" + options.template(options.templateData || {}) + "
"); - } - else { - newPage = $("
" + options.template + "
"); - } - $(drawer).find('.details').first().replaceWith($(newPage).find('.details').first()); //copy details - $(drawer).find('.buttons').first().replaceWith($(newPage).find('.buttons').first()); //copy buttons - } - - if (options.form) { //from existing html element - $(drawer).find('.details').first().replaceWith($(options.form).find('.details').first()); //copy details - $(drawer).find('.buttons').first().replaceWith($(options.form).find('.buttons').first()); //copy buttons - options.form.remove(); - } - - if (options.id) { //sets id - $(drawer).attr("id", options.id); - } - if (options.title) { //sets title - $(drawer).find(".title span").first().html(options.title); - } - if (options.saveButtonText) { - $(drawer).find(".buttons .save-drawer-button").first().html(options.saveButtonText); - } - - //appends drawer to - if (options.root) { - options.root.append(drawer); - } - else { - $(".widget").first().append(drawer); - } - - if (options.onClose && typeof options.onClose === 'function') { - drawer.onClose = options.onClose; - } - - $(drawer).find(".close").off("click").on("click", function() { - drawer.close(); - }); - - app.localize(drawer); - - drawer._resetForm = function() { - $(this.drawerElement).find("input[type=text]").val(""); - $(this.drawerElement).find("textarea").val(""); - }; - if (options.resetForm) { - drawer.resetForm = function() { - if (!options.preventBaseReset) { - this._resetForm(); - } - options.resetForm(); - }; - } - else { - drawer.resetForm = drawer._resetForm; - } - if (options.initForm) { - options.initForm(); - } - - drawer.open = function() { - $(".cly-drawer").removeClass("open editing"); //closes all drawers - $(this).addClass("open"); - }; - - drawer.close = function(force) { - if (force) { - $(drawer).removeClass("open editing"); - drawer.trigger('cly-drawer-closed'); - } - else if (drawer.onClose && typeof drawer.onClose === 'function') { - drawer.onClose(function(closeMe) { - if (closeMe) { - $(drawer).removeClass("open editing"); - drawer.trigger('cly-drawer-closed'); - } - }); - } - else { - $(drawer).removeClass("open editing"); - drawer.trigger('cly-drawer-closed'); - } - }; - - drawer._changeDefaultHandler = function() { - $(drawer).trigger('cly-drawer-form-updated'); - }; - drawer._changeDefaultGreenCheckBoxHandler = function() { - var isChecked = $(this).hasClass("fa-check-square"); //now is checked - if (isChecked) { - $(this).addClass("fa-square-o"); - $(this).removeClass("fa-check-square"); - } - else { - $(this).removeClass("fa-square-o"); - $(this).addClass("fa-check-square"); - } - $(drawer).trigger('cly-drawer-form-updated'); - }; - drawer._applyChangeTrigger = function() { - var domDict = [ - {s: '.on-off-switch input', e: 'change'}, - {s: 'input[type=text]', e: 'keyup'}, - {s: 'textarea', e: 'keyup'}, - {s: '.cly-select', e: 'cly-select-change'}, - ]; - domDict.forEach(function(d) { - $(drawer).find(d.s).off(d.e, drawer._changeDefaultHandler).on(d.e, drawer._changeDefaultHandler); - }); - - //multi select - $(drawer).off('cly-multi-select-change', drawer._changeDefaultHandler).on('cly-multi-select-change', drawer._changeDefaultHandler); - - //green checkboxes - $(drawer).find(".check-green").off("click", drawer._changeDefaultGreenCheckBoxHandler).on("click", drawer._changeDefaultGreenCheckBoxHandler); - }; - - if (options.applyChangeTriggers) { - drawer._applyChangeTrigger(drawer); - } - if (options.onUpdate) { - $(drawer).on('cly-drawer-form-updated', options.onUpdate); - } - if (options.onClosed) { - $(drawer).on('cly-drawer-closed', options.onClosed); - } - return drawer; - }; /** * Display dashboard notification using Amaran JS library @@ -429,245 +209,6 @@ CountlyHelpers.isActiveAppMobile = function() { return countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].type === 'mobile'; }, - /** - * Create new model - */ - CountlyHelpers.model = function() { - var self = this; - $("#overlay").click(function() { - var model = $(".model:visible"); - if (model.length) { - model.fadeOut().remove(); - $(this).hide(); - } - }); - - var cnFn = function() { - $(this).trigger("model-continue"); - $(this).parents(".model:visible").fadeOut().remove(); - }; - - var clFn = function() { - $(this).trigger("model-cancel"); - $(this).parents(".model:visible").fadeOut().remove(); - }; - - this.resetModel = function() { - self.continue = [cnFn]; - self.cancel = [clFn]; - }; - - $(document).on('click', "#model-continue", function() { - var breakStatus = false; - for (var i = 0; i < self.continue.length; i++) { - var call = self.continue[i].bind(this); - if (!call()) { - breakStatus = true; - break; - } - } - - if (breakStatus) { - $(this).trigger("model-continue"); - } - - if (!$('.model:visible').length) { - $("#overlay").hide(); - } - }); - - $(document).on('click', "#model-cancel", function() { - var breakStatus = false; - for (var i = 0; i < self.cancel.length; i++) { - var call = self.cancel[i].bind(this); - if (!call()) { - breakStatus = true; - break; - } - } - - if (breakStatus) { - $(this).trigger("model-cancel"); - } - - if (!$('.model:visible').length) { - $("#overlay").hide(); - } - }); - - $(document).keyup(function(e) { - if (e.keyCode === 27) { - $(".model:visible").animate({ - top: 0, - opacity: 0 - }, { - duration: 1000, - easing: 'easeOutQuart', - complete: function() { - $(this).remove(); - } - }); - - $("#overlay").hide(); - } - }); - - self.continue = [cnFn]; - self.cancel = [clFn]; - }; - - /** - * Create new model - * @param {object} json - json object - * @param {string=} type - classname - * @param {function=} callback - callback function - */ - CountlyHelpers.newJSONEditor = function(json, type, callback) { - var self = this; - - var dialog = $("#cly-json-editor").clone(); - dialog.removeAttr("id"); - - dialog.addClass(type); - CountlyHelpers.revealDialog(dialog); - - var element = dialog.find(".body")[0]; - var statusElements = { - validElement: dialog.find(".valid-json"), - invalidElement: dialog.find(".invalid-json"), - }; - - this.JSONEditor = new _JSONEditor(element, json, statusElements); - - this.JSONEditor.editor.on("change", function() { - dialog.find("#dialog-continue").removeClass("disabled"); - if (!self.JSONEditor.jsonStatus) { - dialog.find("#dialog-continue").addClass("disabled"); - } - }); - - dialog.find("#dialog-cancel").on('click', function() { - callback(true); - }); - - dialog.find("#dialog-continue").on('click', function() { - if (self.JSONEditor.jsonStatus) { - return callback(false, self.JSONEditor.returnJSON()); - } - - return callback(true); - }); - - dialog.find("#dialog-format").on("click", function() { - self.JSONEditor.format(); - }); - }; - - CountlyHelpers.blinkDots = function(times, speed, element) { - element.blinkCn = times; - if ($(element).hasClass("blink")) { - return; - } - $(element).addClass("blink"); - element.blinkElement = function() { - var self = this; - if (!$(element).hasClass("blink")) { - return; - } - if (this.blinkCn > 0 || this.blinkCn === -1) { - if (this.blinkCn > 0) { - this.blinkCn -= 1; - } - var dots = $(element).find("span"); - $(dots[0]).fadeTo(speed, 0.1, function() { - $(dots[0]).fadeTo(speed, 1.0, function() { - $(dots[1]).fadeTo(speed, 0.1, function() { - $(dots[1]).fadeTo(speed, 1.0, function() { - $(dots[2]).fadeTo(speed, 0.1, function() { - $(dots[2]).fadeTo(speed, 1.0, function() { - self.blinkElement(); - }); - }); - }); - }); - }); - }); - } - }; - element.blinkElement(); - }; - - CountlyHelpers.stopBlinking = function(element) { - $(element).removeClass("blink"); - }; - CountlyHelpers.applyColors = function() { - $('#custom-color-styles').remove(); - // overview bars - var barStyles = ''; - $(barStyles).appendTo('head'); - }; - - /** - * Display modal popup UI - * @param {string|object} element - if third parameter isHTML is true, then HTML code as string is expected, else element's selector or element itself is expected and it's HTML contents will be copied into popup - * @param {string=} custClass - add custom css class to dialog for easier manipulation - * @param {boolean=} isHTML - changes the behavior of first parameter element - * @example - * CountlyHelpers.popup("

Hello

", "red", true); - */ - CountlyHelpers.popup = function(element, custClass, isHTML) { - var dialog = $("#cly-popup").clone(); - dialog.removeAttr("id"); - if (custClass) { - dialog.addClass(custClass); - } - - if (isHTML) { - dialog.find(".content").html(element); - } - else { - dialog.find(".content").html($(element).html()); - } - - revealDialog(dialog); - }; - - /** - * Display modal popup with external resource from provided URL in iframe. Make sure to use https version of resource for it to work on both http and https dashboard - * @param {string} url - full absolute url to external resource to display in popup - * @example - * CountlyHelpers.openResource("http://resources.count.ly/docs"); - */ - CountlyHelpers.openResource = function(url) { - var dialog = $("#cly-resource").clone(); - dialog.removeAttr("id"); - dialog.find(".content").html(""); - - revealDialog(dialog); - }; /** * Display modal alert popup for quick short messages that require immediate user's attention, as error submitting form @@ -782,24 +323,6 @@ } }; - /** - * Displays loading icong and returns reference to dialog so you could close it once loading is done - * @param {string} msg - message to display in loading popup - * @returns {object} jQuery object reference to dialog - * @example - * var dialog = CountlyHelpers.loading("we are doing something"); - * //later when done - * CountlyHelpers.removeDialog(dialog); - */ - CountlyHelpers.loading = function(msg) { - var dialog = $("#cly-loading").clone(); - dialog.removeAttr("id"); - dialog.find(".message").html(msg); - dialog.addClass('cly-loading'); - revealDialog(dialog); - return dialog; - }; - /** * Display modal popup that blocks the screen and cannot be closed * @param {string} msg - message to display in popup @@ -833,1758 +356,70 @@ * @param {string} content - modal popup content * @example * CountlyHelpers.showQuickstartDialog(); - */ - CountlyHelpers.showQuickstartPopover = function(content) { - if (countlyGlobal.ssr) { - return; - } - - if (window.countlyVue && window.countlyVue.vuex) { - var payload = { - intent: "quickstart", - message: content, - width: "314", - }; - - var currentStore = window.countlyVue.vuex.getGlobalStore(); - if (currentStore) { - currentStore.dispatch('countlyCommon/onAddDialog', payload); - } - } - }; - - /** - * Check the value which passing as parameter - * isJSON or not - * return result as boolean - * @param {object} val - value of form data - * @returns {boolean} is this a json object? - * @example - * CountlyHelpers.isJSON(variable); - */ - CountlyHelpers.isJSON = function(val) { - try { - JSON.parse(val); - return true; - } - catch (notJSONError) { - return false; - } - }; - /** function to show selected column count in export dialog - * @param {object} dialog - dialog - */ - function show_selected_column_count(dialog) { - - var allSelected = dialog.find('.export-all-columns.fa-check-square'); - - - var boxesCn = dialog.find('.columns-wrapper .checkbox-line'); - if (boxesCn) { - boxesCn = boxesCn.length; - } - var selectedCn = dialog.find('.columns-wrapper .fa-check-square'); - if (selectedCn) { - selectedCn = selectedCn.length; - } - if (allSelected.length === 0 && selectedCn !== boxesCn) { - dialog.find(".export-columns-selector p:first").html(jQuery.i18n.map["export.columns-to-export"] + "" + jQuery.i18n.prop("export.export-columns-selected-count", selectedCn, boxesCn) + ""); - } - else { - dialog.find(".export-columns-selector p:first span").text(""); - } - } - - /** function to show selected column count in export dialog - * @param {object} dialog - dialog - * @param {object} data - object with information about formating - * @param {object} instance - refenrence to instance - */ - function show_formatting_warning(dialog, data, instance) { - - dialog.find(".export-format-option i").not(".tooltipstered").tooltipster({ - animation: "fade", - animationDuration: 50, - delay: 100, - theme: 'tooltipster-borderless', - side: ['top'], - maxWidth: 300, - trigger: 'hover', - interactive: true, - functionBefore: function(instance2) { - instance2.content("

" + jQuery.i18n.map["export.format-if-possible-explain"] + "

"); - }, - contentAsHTML: true, - functionInit: function(instance2) { - instance2.content("

" + jQuery.i18n.map["export.format-if-possible-explain"] + "

"); - } - }); - - if (data && data.fields && Object.keys(data.fields).length > 0) { - dialog.find(".export-format-option").css("display", "none"); - if (dialog.find(".export-columns-selector:visible").length > 0) { - if (dialog.find(".export-all-columns").hasClass("fa-check-square")) { - //export all columns no need for projections - for (var filed in data.fields) { - if (data.fields[filed].to === "time") { - dialog.find(".export-format-option").css("display", "block"); - } - } - } - else { - var projection = {}; - - var checked = dialog.find('.columns-wrapper .fa-check-square'); - for (var kz = 0; kz < checked.length; kz++) { - projection[$(checked[kz]).data("index")] = true; - } - - if (instance && instance.fixProjectionParams) { - projection = instance.fixProjectionParams(projection); - } - - for (var filed2 in data.fields) { - if (data.fields[filed2].to === "time" && projection[filed2]) { - dialog.find(".export-format-option").css("display", "block"); - } - } - - } - } - } - else { - dialog.find(".export-format-option").css("display", "none"); - } - } - /** - * Displays database export dialog - * @param {number} count - total count of documents to export - * @param {object} data - data for export query to use when constructing url - * @param {boolean} asDialog - open it as dialog - * @param {boolean} exportByAPI - export from api request, export from db when set to false - * @param {boolean} instance - optional. Reference to table to get correct colum names(only if there is need to select columns to export) There must be changes made in table settings to allow it. (table.addColumnExportSelector = true and each column must have columnsSelectorIndex value as field in db) - * @returns {object} jQuery object reference to dialog - * @example - * var dialog = CountlyHelpers.export(300000); - * //later when done - * CountlyHelpers.removeDialog(dialog); - */ - CountlyHelpers.export = function(count, data, asDialog, exportByAPI, instance) { - //var hardLimit = countlyGlobal.config.export_limit; - //var pages = Math.ceil(count / hardLimit); - var dialog = $("#cly-export").clone(); - var type = "csv"; - //var page = 0; - var tableCols; - - var formatData = data.formatFields || ""; - try { - formatData = JSON.parse(formatData); - } - catch (e) { - formatData = {}; - } - dialog.removeAttr("id"); - /*dialog.find(".details").text(jQuery.i18n.prop("export.export-number", (count + "").replace(/(\d)(?=(\d{3})+$)/g, '$1 '), pages)); - if (count <= hardLimit) { - dialog.find(".cly-select").hide(); - } - else { - dialog.find(".select-items > div").append('
' + jQuery.i18n.map["common.all"] + " " + jQuery.i18n.map["export.documents"] + '
'); - for (var i = 0; i < pages; i++) { - dialog.find(".select-items > div").append('
' + ((i * hardLimit + 1) + "").replace(/(\d)(?=(\d{3})+$)/g, '$1 ') + ' - ' + (Math.min((i + 1) * hardLimit, count) + "").replace(/(\d)(?=(\d{3})+$)/g, '$1 ') + " " + jQuery.i18n.map["export.documents"] + '
'); - } - dialog.find(".export-data").addClass("disabled"); - }*/ - - var str = ""; - if (instance && instance.addColumnExportSelector && instance.fnSettings) { - tableCols = instance.fnSettings().aoColumns || []; - } - - if (tableCols && Array.isArray(tableCols) && tableCols.length > 0) { - var disabled = ""; //left in case want to add disabled column feature - var myClass = ""; - var myClass2 = ""; - for (var colIndex = 0; colIndex < tableCols.length; colIndex++) { - if (tableCols[colIndex].columnSelectorIndex) { - var colName = tableCols[colIndex].columnSelectorIndex; - myClass = 'fa-check-square'; - myClass2 = ""; - - - if (tableCols[colIndex].bVisible === true) { - //selectedC++; - } - else { - myClass = 'fa-square-o'; - myClass2 = ' not-checked'; - } - str += "
" + tableCols[colIndex].sTitle + "
"; - } - } - dialog.find(".export-columns-selector .columns-wrapper").html(str); - dialog.find(".export-columns-selector").css("display", "block"); - - - dialog.find('.columns-wrapper').slimScroll({ - height: '100%', - start: 'top', - wheelStep: 10, - position: 'right', - disableFadeOut: true - }); - - $(".data-table-column-selector").on("click", function(e) { - e.stopPropagation(); - }); - - dialog.find(".export-columns-selector").on("click", ".checkbox-line", function() { - var checkbox = $(this).find("a").first(); - var isChecked = $(checkbox).hasClass("fa-check-square");//is now checked - - if (isChecked) { - $(checkbox).addClass("fa-square-o"); - $(checkbox).removeClass("fa-check-square"); - if ($(checkbox).hasClass("export-all-columns")) { - dialog.find(".export-columns-selector").removeClass("hide-column-selectors"); - } - } - else { - $(checkbox).removeClass("fa-square-o"); - $(checkbox).addClass("fa-check-square"); - if ($(checkbox).hasClass("export-all-columns")) { - dialog.find(".export-columns-selector").addClass("hide-column-selectors"); - } - } - show_selected_column_count(dialog); - show_formatting_warning(dialog, formatData, instance); - }); - - - - dialog.on("click", ".export-format-option", function() { - var checkbox = $(this).find("a").first(); - var isChecked = $(checkbox).hasClass("fa-check-square");//is now checked - - if (isChecked) { - $(checkbox).addClass("fa-square-o"); - $(checkbox).removeClass("fa-check-square"); - } - else { - $(checkbox).removeClass("fa-square-o"); - $(checkbox).addClass("fa-check-square"); - } - }); - - show_selected_column_count(dialog); - setTimeout(function() { - show_formatting_warning(dialog, formatData, instance); - }, 10); - dialog.find(".export-columns-search input").on("keyup", function() { - var value = dialog.find(".export-columns-search input").val(); - value = new RegExp((value || ""), 'i'); - for (var z = 0;z < tableCols.length; z++) { - if (tableCols[z].sTitle.match(value)) { - dialog.find(".export-columns-selector .columns-wrapper .checkbox-line[data-selectorname='" + tableCols[z].columnSelectorIndex + "']").css("display", "block"); - } - else { - dialog.find(".export-columns-selector .columns-wrapper .checkbox-line[data-selectorname='" + tableCols[z].columnSelectorIndex + "']").css("display", "none"); - } - } - - }); - } - else { - dialog.find(".export-columns-selector .columns-wrapper").html(""); - dialog.find(".export-columns-selector").css("display", "none"); - } - - dialog.find(".button").click(function() { - dialog.find(".button-selector .button").removeClass("selected"); - dialog.find(".button-selector .button").removeClass("active"); - $(this).addClass("selected"); - $(this).addClass("active"); - type = $(this).attr("id").replace("export-", ""); - }); - /*dialog.find(".segmentation-option").on("click", function() { - page = $(this).data("value"); - dialog.find(".export-data").removeClass("disabled"); - });*/ - dialog.find(".export-data").click(function() { - if ($(this).hasClass("disabled")) { - return; - } - data.type = type; - data.limit = ""; - data.skip = 0; - /*if (page !== -1) { - data.limit = hardLimit; - data.skip = page * hardLimit; - } - else { - data.limit = ""; - data.skip = 0; - }*/ - if (dialog.find(".export-columns-selector:visible").length > 0) { - delete data.projection; - if (dialog.find(".export-all-columns").hasClass("fa-check-square")) { - //export all columns no need for projections - } - else { - var projection = {}; - var checked = dialog.find('.columns-wrapper .fa-check-square'); - for (var kz = 0; kz < checked.length; kz++) { - projection[$(checked[kz]).data("index")] = true; - } - - if (instance && instance.fixProjectionParams) { - projection = instance.fixProjectionParams(projection); - } - data.projection = JSON.stringify(projection); - } - } - - if (!(dialog.find(".export-format-columns").hasClass("fa-check-square"))) { - delete data.formatFields; - } - var url = countlyCommon.API_URL + (exportByAPI ? "/o/export/request" : "/o/export/db"); - if (data.url) { - url = data.url; - } - - var form = $('
'); - $.each(data, function(k, v) { - if (CountlyHelpers.isJSON(v)) { - form.append($('')); - } - else { - form.append($('')); - } - }); - if (exportByAPI && url === "/o/export/requestQuery") { - if (Array.isArray(data.prop)) { - data.prop = data.prop.join(","); - } - $.ajax({ - type: "POST", - url: countlyCommon.API_PARTS.data.r + "/export/requestQuery", - data: data, - success: function(result) { - var task_id = null; - var fileid = null; - if (result && result.result && result.result.task_id) { - task_id = result.result.task_id; - countlyTaskManager.monitor(task_id); - CountlyHelpers.displayExportStatus(null, fileid, task_id); - } - $(".save-table-data").click(); - - }, - error: function(xhr, status, error) { - var filename = null; - if (xhr && xhr.responseText && xhr.responseText !== "") { - var ob = JSON.parse(xhr.responseText); - if (ob.result && ob.result.message) { - error = ob.result.message; - } - if (ob.result && ob.result.filename) { - filename = ob.result.filename; - } - } - CountlyHelpers.displayExportStatus(error, filename, null); - } - }); - } - else { - $('body').append(form); - form.submit(); - } - }); - if (asDialog) { - revealDialog(dialog); - } - return dialog; - }; - - CountlyHelpers.displayExportStatus = function(error, export_id, task_id) { - if (error) { - CountlyHelpers.alert(error, "red"); - } - else if (export_id) { - CountlyHelpers.notify({ - type: "ok", - title: jQuery.i18n.map["common.success"], - message: jQuery.i18n.map["export.export-finished"], - info: jQuery.i18n.map["app-users.export-finished-click"], - sticky: false, - clearAll: true, - onClick: function() { - var win = window.open(countlyCommon.API_PARTS.data.r + "/export/download/" + task_id + "?auth_token=" + countlyGlobal.auth_token + "&app_id=" + countlyCommon.ACTIVE_APP_ID, '_blank'); - win.focus(); - } - }); - self.refresh(); - } - else if (task_id) { - CountlyHelpers.notify({type: "ok", title: jQuery.i18n.map["common.success"], message: jQuery.i18n.map["export.export-started"], sticky: false, clearAll: false}); - // self.refresh(); - } - else { - CountlyHelpers.alert(jQuery.i18n.map["export.export-failed"], "red"); - } - }; - - /** - * Displays raw data table export dialog - * @param {opject} dtable - data - * @param {object} data - data for export query to use when constructing url - * @param {boolean} asDialog - open it as dialog - * @param {object} oSettings - oSettings object of the dataTable - * @returns {object} jQuery object reference to dialog - * @example - * var dialog = CountlyHelpers.export(300000); - * //later when done - * CountlyHelpers.removeDialog(dialog); - */ - CountlyHelpers.tableExport = function(dtable, data, asDialog, oSettings) { - /** gets file name for export - * @returns {string} filename - */ - function getFileName() { - var name = "countly"; - if ($(".widget-header .title").length) { - name = jQuery.trim($(".widget-header .title").first().text()).replace(/[\r\n]+/g, " ").split(" ")[0]; - } - if ($(".widget #date-selector").length) { - //include export range - name += "_for_" + countlyCommon.getDateRange(); - } - else { - //include export date - name += "_on_" + moment().format("DD-MMM-YYYY"); - } - return (name.charAt(0).toUpperCase() + name.slice(1).toLowerCase()); - } - /** gets export data from data table - * @param {object} dtable_pd - data table - * @returns {array} table data - */ - function getExportData(dtable_pd) { - var tableCols = oSettings ? oSettings.aoColumns : dtable_pd.fnSettings().aoColumns, - tableData = []; - if (tableCols[0].sExport && app.dataExports[tableCols[0].sExport]) { - tableData = app.dataExports[tableCols[0].sExport](); - } - else { - var i = 0; - // TableTools deprecated by offical, - // fix bug with workaround for export table - TableTools.fnGetInstance = function(node) { - if (typeof node !== 'object') { - node = document.getElementById(node); - } - var iLen = TableTools._aInstances.length; - if (iLen > 0) { - for (i = iLen - 1 ; i >= 0 ; i--) { - if (TableTools._aInstances[i].s.master && TableTools._aInstances[i].dom.table === node) { - return TableTools._aInstances[i]; - } - } - } - return null; - }; - tableData = TableTools.fnGetInstance(dtable_pd[0] || oSettings.nTable).fnGetTableData({"sAction": "data", "sTag": "default", "sLinerTag": "default", "sButtonClass": "DTTT_button_xls", "sButtonText": "Save for Excel", "sTitle": "", "sToolTip": "", "sCharSet": "utf16le", "bBomInc": true, "sFileName": "*.csv", "sFieldBoundary": "", "sFieldSeperator": "\t", "sNewLine": "auto", "mColumns": "all", "bHeader": true, "bFooter": true, "bOpenRows": false, "bSelectedOnly": false, "fnMouseover": null, "fnMouseout": null, "fnSelect": null, "fnComplete": null, "fnInit": null, "fnCellRender": null, "sExtends": "xls"}); - tableData = tableData.split(/\r\n|\r|\n/g); - tableData.shift(); - - for (i = 0; i < tableData.length; i++) { - tableData[i] = tableData[i].split('\t'); - } - var retData = []; - for (i = 0; i < tableData.length; i++) { - var ob = {}; - for (var colIndex = 0; colIndex < tableCols.length; colIndex++) { - try { - if (!(tableData[i] && tableData[i][colIndex]) || (tableCols[colIndex] && tableCols[colIndex].noExport)) { - continue; - } - if (tableCols[colIndex].sType === "formatted-num") { - ob[tableCols[colIndex].sTitle] = tableData[i][colIndex].replace(/,/g, ""); - } - else if (tableCols[colIndex].sType === "percent") { - ob[tableCols[colIndex].sTitle] = tableData[i][colIndex].replace("%", ""); - } - else if (tableCols[colIndex].sType === "format-ago" || tableCols[colIndex].sType === "event-timeline") { - ob[tableCols[colIndex].sTitle] = tableData[i][colIndex].split("|").pop(); - } - else { - ob[tableCols[colIndex].sTitle] = tableData[i][colIndex]; - } - } - catch (e) { - //not important - } - } - retData.push(ob); - } - tableData = retData; - } - return tableData; - } - var dialog = $("#cly-export").clone(); - var type = "csv"; - dialog.removeAttr("id"); - dialog.find(".details").hide(); - dialog.find(".cly-select").hide(); - dialog.find(".button").click(function() { - dialog.find(".button-selector .button").removeClass("selected"); - dialog.find(".button-selector .button").removeClass("active"); - $(this).addClass("selected"); - $(this).addClass("active"); - type = $(this).attr("id").replace("export-", ""); - }); - dialog.find(".export-data").click(function() { - if ($(this).hasClass("disabled")) { - return; - } - data.type = type; - data.data = JSON.stringify(getExportData(dtable, type)); - data.filename = getFileName(type); - - var url = countlyCommon.API_URL + "/o/export/data"; - var form = $(''); - - $.each(data, function(k, v) { - if (CountlyHelpers.isJSON(v)) { - form.append($('')); - } - else { - form.append($('')); - } - }); - $('body').append(form); - form.submit(); - }); - if (asDialog) { - revealDialog(dialog); - } - return dialog; - }; - - /** - * Instead of creating dialog object you can use this method and directly pass jquery element to be used as dialog content, which means complete customization - * @param {jquery_object} dialog - jQuery object unnattached, like cloned existing object - * @example - * var dialog = $("#cly-popup").clone().removeAttr("id").addClass('campaign-create'); - * CountlyHelpers.revealDialog(dialog); - */ - CountlyHelpers.revealDialog = function(dialog) { - $("body").append(dialog); - var dialogHeight = dialog.outerHeight(), - dialogWidth = dialog.outerWidth() + 2; - - dialog.css({ - "height": dialogHeight, - "margin-top": Math.floor(-dialogHeight / 2), - "width": dialogWidth, - "margin-left": Math.floor(-dialogWidth / 2) - }); - - $("#overlay").fadeIn(); - dialog.fadeIn(app.tipsify.bind(app, $("#help-toggle").hasClass("active"), dialog)); - CountlyHelpers.makeSelectNative(); - }; - - /** - * If contents of the popup change, you may want to resice the popup - * @param {jquery_object} dialog - jQuery dialog reference - * @param {boolean} animate - should resizing be animated - * @example - * var dialog = $("#cly-popup").clone().removeAttr("id").addClass('campaign-create'); - * CountlyHelpers.revealDialog(dialog); - * //when content changes - * CountlyHelpers.changeDialogHeight(dialog, true) - */ - CountlyHelpers.changeDialogHeight = function(dialog, animate) { - var dialogHeight = 0, - dialogWidth = dialog.width(), - maxHeight = $("#sidebar").height() - 40; - - dialog.children().each(function() { - dialogHeight += $(this).outerHeight(true); - }); - - if (dialogHeight > maxHeight) { - dialog[animate ? 'animate' : 'css']({ - "height": maxHeight, - "margin-top": Math.floor(-maxHeight / 2), - "width": dialogWidth, - "margin-left": Math.floor(-dialogWidth / 2), - "overflow-y": "auto" - }); - } - else { - dialog[animate ? 'animate' : 'css']({ - "height": dialogHeight, - "margin-top": Math.floor(-dialogHeight / 2), - "width": dialogWidth, - "margin-left": Math.floor(-dialogWidth / 2) - }); - } - }; - - var revealDialog = CountlyHelpers.revealDialog; - - //var changeDialogHeight = CountlyHelpers.changeDialogHeight; - not used anywhere anymore - - /** - * Remove existing dialog - * @param {jquery_object} dialog - jQuery dialog reference - * @example - * var dialog = $("#cly-popup").clone().removeAttr("id").addClass('campaign-create'); - * CountlyHelpers.revealDialog(dialog); - * //when dialog not needed anymore - * CountlyHelpers.removeDialog(dialog); - */ - CountlyHelpers.removeDialog = function(dialog) { - dialog.remove(); - $("#overlay").fadeOut(); - }; - - CountlyHelpers.setUpDateSelectors = function(self) { - $("#month").text(moment().year()); - $("#day").text(moment().format("MMMM, YYYY")); - $("#yesterday").text(moment().subtract(1, "days").format("Do")); - - $("#date-selector").find(".date-selector").click(function() { - if ($(this).hasClass("selected")) { - return true; - } - - self.dateFromSelected = null; - self.dateToSelected = null; - - $(".date-selector").removeClass("selected").removeClass("active"); - $(this).addClass("selected"); - var selectedPeriod = $(this).attr("id"); - - if (countlyCommon.getPeriod() === selectedPeriod) { - return true; - } - - countlyCommon.setPeriod(selectedPeriod); - - self.dateChanged(selectedPeriod); - app.runRefreshScripts(); - - $("#" + selectedPeriod).addClass("active"); - $("#date-picker").hide(); - $("#date-selector .calendar").removeClass("selected").removeClass("active"); - $("#selected-date").text(countlyCommon.getDateRangeForCalendar()); - - }); - - $("#date-selector").find(".date-selector").each(function() { - if (countlyCommon.getPeriod() === $(this).attr("id")) { - $(this).addClass("active").addClass("selected"); - } - }); - }; - - /** - * Initialize countly dropdown select. In most cases it is done automatically, only in some cases, when content loaded via ajax request outside of view lifecycle, you may need to initialize it yourself for your content specifically - * @param {object} element - jQuery object reference - * @example - * CountlyHelpers.initializeSelect($("#my-dynamic-div")); - */ - CountlyHelpers.initializeSelect = function(element) { - element = element || $("body"); - var showOptions = function(context) { - if ($(context).hasClass("disabled")) { - return true; - } - - $(context).removeClass("req"); - - var selectItems = $(context).find(".select-items"), - itemCount = selectItems.find(".item").length; - - if (!selectItems.length) { - return false; - } - - $(".cly-select").find(".search").remove(); - $(".cly-multi-select").find(".search").remove(); - - if (selectItems.is(":visible")) { - $(context).removeClass("active"); - } - else { - $(".cly-select").removeClass("active"); - $(".cly-multi-select").removeClass("active"); - $(".select-items").hide(); - $(context).addClass("active"); - - if (itemCount > 10 || $(context).hasClass("big-list")) { - $("").insertBefore($(context).find(".select-items")); - } - } - - if ($(context).hasClass("centered")) { - if ((itemCount > 5 && $(context).offset().top > 400) || $(context).hasClass("force")) { - var height = $(context).find(".select-items").height(), - searchItem = $(context).find(".search"); - - var addThis = 0; - - if (searchItem.length) { - addThis = (searchItem.height() / 2).toFixed(0) - 1; - $(context).find(".select-items").css({"min-height": height}); - } - else { - $(context).find(".select-items").css({"min-height": "auto"}); - height = $(context).find(".select-items").height(); - } - - $(context).find(".select-items").css("margin-top", (-(height / 2).toFixed(0) - ($(context).height() / 2).toFixed(0) + parseInt(addThis)) + "px"); - $(context).find(".search").css("margin-top", (-(height / 2).toFixed(0) - searchItem.height()) + "px"); - } - else { - $(context).find(".select-items").css({"min-height": "auto"}); - $(context).find(".select-items").css("margin-top", ''); - $(context).find(".search").css("margin-top", ''); - } - } - if ($(context).find(".select-items").is(":visible")) { - $(context).find(".select-items").hide(); - } - else { - $(context).find(".select-items").show(); - if ($(context).find(".select-items").find(".scroll-list").length === 0) { - $(context).find(".select-items").wrapInner("
"); - $(context).find(".scroll-list").slimScroll({ - height: '100%', - start: 'top', - wheelStep: 10, - position: 'right', - disableFadeOut: true - }); - } - } - $(context).find(".select-items").find(".item").removeClass("hidden"); - $(context).find(".select-items").find(".group").show(); - $(context).find(".select-items").find(".item").removeClass("last"); - $(context).find(".select-items").find(".item:visible:last").addClass("last"); - $(context).find(".search input").focus(); - $("#date-picker").hide(); - $(context).find(".search").off("click").on("click", function(e1) { - e1.stopPropagation(); - }); - }; - var activeOption = 0; - - var hideOptions = function() { - var $clySelect = $(".cly-select"); - - $clySelect.find(".select-items").hide(); - $clySelect.find(".search").remove(); - $clySelect.removeClass("active"); - }; - - element.off("click", ".cly-select").on("click", ".cly-select", function(e) { - showOptions(this); - activeOption = 0; - e.stopPropagation(); - }); - - element.off("keyup", ".cly-select").on("keyup", ".cly-select", function(e) { - if (e.keyCode === 32) { - showOptions(this); - } - if (e.keyCode === 27) { - hideOptions(); - } - - // UP ARROW - if (e.keyCode === 38) { - if (typeof $(this).find('.scroll-list > div').first() !== "undefined" && !($(this).find('.scroll-list').first().children().length > 1)) { - $($(this).find('.scroll-list > div').first().children[activeOption]).css({"background-color": "white"}); - if (activeOption === 0) { - activeOption = $(this).find('.scroll-list > div').first().children().length - 1; - } - else { - activeOption--; - } - $(this).find('.scroll-list > div').first().children().eq(activeOption).css({'background-color': '#f3f3f3'}); - } - else if ($(this).find('.scroll-list').first().children().length > 1) { - $(this).find('.scroll-list').first().children().eq(activeOption).css({"background-color": "white"}); - if (activeOption === 0) { - activeOption = $(this).find('.scroll-list').children().length - 1; - } - else { - activeOption--; - } - - $(this).find('.scroll-list').first().children().eq(activeOption).css({'background-color': '#f3f3f3'}); - } - } - // DOWN ARROW - if (e.keyCode === 40) { - if (typeof $(this).find('.scroll-list > div').first() !== "undefined" && !($(this).find('.scroll-list').first().children().length > 1)) { - $(this).find('.scroll-list > div').first().children().eq(activeOption).css({"background-color": "white"}); - if ($(this).find('.scroll-list > div').first().children().length === activeOption + 1) { - activeOption = 0; - } - else { - activeOption++; - } - $(this).find('.scroll-list > div').first().children().eq(activeOption).css({'background-color': '#f3f3f3'}); - } - else if ($(this).find('.scroll-list').first().children().length > 1) { - $(this).find('.scroll-list').first().children().eq(activeOption).css({"background-color": "white"}); - if ($(this).find('.scroll-list').first().children().length === activeOption + 1) { - activeOption = 0; - } - else { - activeOption++; - } - $(this).find('.scroll-list').first().children().eq(activeOption).css({'background-color': '#f3f3f3'}); - } - } - //ENTER - if (e.keyCode === 13) { - var selectedItem = $(this).find(".text"); - var activeKeyItem = $(this).find('.scroll-list').first().children().eq(activeOption); - if ($(this).hasClass("disabling-on") && activeKeyItem.hasClass("disabled")) { - e.stopPropagation(); - return; - } - if ($(this).find('.scroll-list').first().children().length > 1) { - if ($(this).find('.scroll-list').first().children().eq(activeOption).find('div > span').length > 0) { - selectedItem.text($(this).find('.scroll-list').first().children().eq(activeOption).find('div > span').text()); - } - else { - selectedItem.text($(this).find('.scroll-list').first().children().eq(activeOption).first().text()); - } - selectedItem.data("value", $(this).find('.scroll-list').first().children().eq(activeOption).find('div').data('value')); - } - else { - selectedItem.text($(this).find('.scroll-list > div').first().children().eq(activeOption).text()); - selectedItem.data("value", $(this).find('.scroll-list > div').first().children().eq(activeOption).data('value')); - } - hideOptions(); - } - e.stopPropagation(); - }); - - element.off("click", ".cly-select .select-items .item").on("click", ".cly-select .select-items .item", function(e) { - var clySelect = $(this).parents(".cly-select"); - var selectedItem = clySelect.find(".text"); - if (clySelect.hasClass("disabling-on") && $(this).hasClass("disabled")) { - e.stopPropagation(); - return; - } - selectedItem.text($(this).text()); - selectedItem.data("value", $(this).data("value")); - clySelect.trigger("cly-select-change", [$(this).data("value")]); - }); - - element.off("keyup", ".cly-select .search input").on("keyup", ".cly-select .search input", function() { - if (!$(this).val()) { - $(this).parents(".cly-select").find(".item").removeClass("hidden"); - $(this).parents(".cly-select").find(".group").show(); - } - else { - $(this).parents(".cly-select").find(".item:not(:contains('" + $(this).val() + "'))").addClass("hidden"); - $(this).parents(".cly-select").find(".item:contains('" + $(this).val() + "')").removeClass("hidden"); - var prevHeader = $(this).parents(".cly-select").find(".group").first(); - prevHeader.siblings().each(function() { - if ($(this).hasClass("group")) { - if (prevHeader) { - prevHeader.hide(); - } - prevHeader = $(this); - } - else if ($(this).hasClass("item") && $(this).is(":visible")) { - prevHeader = null; - } - - if (!$(this).next().length && prevHeader) { - prevHeader.hide(); - } - }); - } - }); - - element.off('mouseenter').on('mouseenter', ".cly-select .item", function() { - var item = $(this); - - if (this.offsetWidth < this.scrollWidth && !item.attr('title')) { - item.attr('title', item.text()); - } - }); - - $(window).click(function() { - hideOptions(); - }); - - $.fn.clySelectSetItems = function(items) { - var $selectItems = $(this).find(".select-items"); - - if ($selectItems) { - $selectItems.html(""); - - for (var i = 0; i < items.length; i++) { - var current = items[i]; - if (current.type === 'group') { - $selectItems.append('
' + current.name + '
'); - } - else if (current.disabled) { - // effective when .cly-select element has disabling-on class - $selectItems.append('
' + current.name + '
'); - } - else { - $selectItems.append('
' + current.name + '
'); - } - } - } - }; - - $.fn.clySelectGetSelection = function() { - return $(this).find(".select-inner .text").data("value") || null; - }; - - $.fn.clySelectSetSelection = function(value, name) { - $(this).find(".select-inner .text").data("value", value); - $(this).find(".select-inner .text").text($('
').html(name).text()); - $(this).trigger("cly-select-change", [value]); - }; - }; - - CountlyHelpers.makeSelectNative = function() { - var rows = $('body').find('.cly-select'); - for (var i = 0; i < rows.length; i++) { - $(rows[i]).attr('tabindex', '0'); - } - }; - - /** - * Initialize countly dropdown multi select. In most cases it is done automatically, only in some cases, when content loaded via ajax request outside of view lifecycle, you may need to initialize it yourself for your content specifically - * @param {object} element - jQuery object reference - * @example - * CountlyHelpers.initializeMultiSelect($("#my-dynamic-div")); - */ - CountlyHelpers.initializeMultiSelect = function(element) { - element = element || $("body"); - - element.off("click", ".cly-multi-select").on("click", ".cly-multi-select", function(e) { - if ($(this).hasClass("disabled")) { - return true; - } - - $(this).removeClass("req"); - - var selectItems = $(this).find(".select-items"), - itemCount = selectItems.find(".item").length; - - if (!selectItems.length) { - return false; - } - - $(".cly-select").find(".search").remove(); - $(".cly-multi-select").find(".search").remove(); - - if (selectItems.is(":visible")) { - $(this).removeClass("active"); - } - else { - $(".cly-select").removeClass("active"); - $(".cly-multi-select").removeClass("active"); - $(".select-items").hide(); - $(this).addClass("active"); - - if (itemCount > 10) { - $("").insertBefore($(this).find(".select-items")); - } - } - - if ($(this).find(".select-items").is(":visible")) { - $(this).find(".select-items").hide(); - } - else { - $(this).find(".select-items").show(); - if ($(this).find(".select-items").find(".scroll-list").length === 0) { - $(this).find(".select-items").wrapInner("
"); - $(this).find(".scroll-list").slimScroll({ - height: '100%', - start: 'top', - wheelStep: 10, - position: 'right', - disableFadeOut: true - }); - } - } - - $(this).find(".select-items").find(".item").removeClass("hidden"); - $(this).find(".select-items").find(".group").show(); - $(this).find(".select-items").find(".item").removeClass("last"); - $(this).find(".select-items").find(".item:visible:last").addClass("last"); - - $(this).find(".search input").focus(); - - $("#date-picker").hide(); - - $(this).find(".search").off("click").on("click", function(e1) { - e1.stopPropagation(); - }); - - e.stopPropagation(); - - var $multiSelect = $(this); - - setTimeout(function() { - var maxToSelect = $multiSelect.data("max"); - var selectedItems = getSelected($multiSelect) || []; - for (var i = 0; i < selectedItems.length; i++) { - $multiSelect.find(".item[data-value='" + selectedItems[i] + "']").addClass("disabled"); - } - - if (maxToSelect) { - if (selectedItems.length >= maxToSelect) { - $multiSelect.find(".item").addClass("disabled"); - } - } - }, 0); - }); - - element.off("click", ".cly-multi-select .select-items .item").on("click", ".cly-multi-select .select-items .item", function(e) { - if ($(this).hasClass("disabled")) { - e.stopPropagation(); - return; - } - - var $multiSelect = $(this).parents(".cly-multi-select"), - selectionContainer = $multiSelect.find(".text"), - selectedValue = $(this).data("value"), - maxToSelect = $multiSelect.data("max"); - - if ($(this).hasClass("selected")) { - selectionContainer.find(".selection[data-value='" + selectedValue + "']").remove(); - $(this).removeClass("selected"); - } - else { - var $selection = $("
"); - - $selection.text($(this).text()); - $selection.attr("data-value", selectedValue); - $selection.append("
"); - - selectionContainer.append($selection); - - $(this).addClass("selected"); - } - - if (maxToSelect) { - if (getSelected($multiSelect).length >= maxToSelect) { - $multiSelect.find(".item").addClass("disabled"); - } - } - - if ($multiSelect.find(".item.selected").length > 0) { - $multiSelect.addClass("selection-exists"); - } - else { - $multiSelect.removeClass("selection-exists"); - } - - $multiSelect.data("value", getSelected($multiSelect)); - $multiSelect.trigger("cly-multi-select-change", [getSelected($multiSelect)]); - e.stopPropagation(); - }); - - element.off("keyup", ".cly-multi-select .search input").on("keyup", ".cly-multi-select .search input", function() { - var $multiSelect = $(this).parents(".cly-multi-select"); - - if (!$(this).val()) { - $multiSelect.find(".item").removeClass("hidden"); - $multiSelect.find(".group").show(); - } - else { - $multiSelect.find(".item:not(:contains('" + $(this).val() + "'))").addClass("hidden"); - $multiSelect.find(".item:contains('" + $(this).val() + "')").removeClass("hidden"); - var prevHeader = $multiSelect.find(".group").first(); - prevHeader.siblings().each(function() { - if ($(this).hasClass("group")) { - if (prevHeader) { - prevHeader.hide(); - } - prevHeader = $(this); - } - else if ($(this).hasClass("item") && $(this).is(":visible")) { - prevHeader = null; - } - - if (!$(this).next().length && prevHeader) { - prevHeader.hide(); - } - }); - } - }); - - element.off('mouseenter').on('mouseenter', ".cly-multi-select .item", function() { - var item = $(this); - - if (this.offsetWidth < this.scrollWidth && !item.attr('title')) { - item.attr('title', item.text()); - } - }); - - element.off("click", ".cly-multi-select .selection").on("click", ".cly-multi-select .selection", function(e) { - e.stopPropagation(); - }); - - element.off("click", ".cly-multi-select .selection .remove").on("click", ".cly-multi-select .selection .remove", function(e) { - var $multiSelect = $(this).parents(".cly-multi-select"); - - $multiSelect.find(".item[data-value='" + $(this).parent(".selection").data("value") + "']").removeClass("selected"); - - if ($multiSelect.find(".item.selected").length > 0) { - $multiSelect.addClass("selection-exists"); - } - else { - $multiSelect.removeClass("selection-exists"); - } - - $(this).parent(".selection").remove(); - - var maxToSelect = $multiSelect.data("max") || 99; - - if (maxToSelect) { - if (getSelected($multiSelect).length < maxToSelect) { - $multiSelect.find(".item").removeClass("disabled"); - } - } - - var selectedItems = getSelected($multiSelect) || []; - for (var i = 0; i < selectedItems.length; i++) { - $multiSelect.find(".item[data-value='" + selectedItems[i] + "']").addClass("disabled"); - } - - $multiSelect.data("value", getSelected($multiSelect)); - $multiSelect.trigger("cly-multi-select-change", [getSelected($multiSelect)]); - - e.stopPropagation(); - }); - - $(window).click(function() { - var $clyMultiSelect = $(".cly-multi-select"); - - $clyMultiSelect.find(".select-items").hide(); - $clyMultiSelect.find(".search").remove(); - $clyMultiSelect.removeClass("active"); - }); - /** get selected from multi select - * @param {object} multiSelectEl multi select element - * @returns {array} array of selected values - */ - function getSelected(multiSelectEl) { - var selected = []; - - multiSelectEl.find(".text .selection").each(function() { - selected.push($(this).data("value")); - }); - - return selected; - } - - $.fn.clyMultiSelectSetItems = function(items) { - var $selectItems = $(this).find(".select-items"); - - if ($selectItems) { - $selectItems.html(""); - - for (var i = 0; i < items.length; i++) { - $selectItems.append('
' + items[i].name + '
'); - } - } - }; - - $.fn.clyMultiSelectGetItems = function() { - var items = []; - $(this).find(".item").each(function() { - items.push({name: $(this).text(), value: $(this).data("value")}); - }); - return items; - }; - - $.fn.clyMultiSelectGetSelection = function() { - return getSelected($(this)); - }; - - $.fn.clyMultiSelectSetSelection = function(valNameArr) { - var $multiSelect = $(this), - $selectionContainer = $multiSelect.find(".text"); - - $(this).find(".selection").remove(); - - for (var i = 0; i < valNameArr.length; i++) { - var name = valNameArr[i].name, - value = valNameArr[i].value; - - var $selection = $("
"); - - $selection.text($('
').html(name).text()); - $selection.attr("data-value", value); - $selection.append("
"); - - $selectionContainer.append($selection); - } - - $(this).addClass("selection-exists"); - $(this).data("value", getSelected($(this))); - $(this).trigger("cly-multi-select-change", [getSelected($(this))]); - }; - - $.fn.clyMultiSelectClearSelection = function() { - $(this).find(".selection").remove(); - $(this).data("value", getSelected($(this))); - $(this).removeClass("selection-exists"); - $(this).trigger("cly-multi-select-change", [getSelected($(this))]); - }; - }; - - /** - * Initialize dropdown options list usually used on datatables. Firstly you need to add list with class 'cly-button-menu' to your template or add it in the view. Additionally you can add class `dark` to use dark theme. - * After that datatables last column for options should return a element with `cly-list-options` class and should have cell classes shrink and right and should not be sortable - * Then call this method in your view and you can start listening to events like: - * cly-list.click - when your cly-list-options element is clicked, passing click event as data - * cly-list.open - when list is opened, passing click event as data - * cly-list.close - when list is closed, passing click event as data - * cly-list.item - when item is clicked, passing click event as data - * @param {object} element - jQuery object reference for container - * @example Adding list to HTML template - *
- * - * - *
- * @example Creating last column in datatables - * { "mData": function(row, type){ - * return ''; - * }, "sType":"string", "sTitle": "", "sClass":"shrink center", bSortable: false } - * @example Listening to events - * $(".cly-button-menu").on("cly-list.click", function(event, data){ - * var id = $(data.target).parents("tr").data("id"); - * }); - */ - CountlyHelpers.initializeTableOptions = function(element) { - element = element || $('body'); - element.find("tbody").off("click", ".cly-list-options").on("click", ".cly-list-options", function(event) { - event.stopPropagation(); - event.preventDefault(); - $(".cly-button-menu").trigger('cly-list.click', event); - $(event.target).toggleClass("active"); - if ($(event.target).hasClass("active")) { - element.find(".cly-list-options").removeClass("active"); - $(event.target).addClass("active"); - var pos = $(event.target).offset(); - element.find('.cly-button-menu').css({ - top: (pos.top + 25) + "px", - right: 22 + "px" - }); - element.find('.cly-button-menu').addClass("active"); - element.find('.cly-button-menu').focus(); - $(".cly-button-menu").trigger('cly-list.open', event); - } - else { - $(event.target).removeClass("active"); - element.find('.cly-button-menu').removeClass("active"); - $(".cly-button-menu").trigger('cly-list.close', event); - } - return false; - }); - - element.find('.cly-button-menu .item').off("click").on("click", function(event) { - $(".cly-button-menu").trigger('cly-list.item', event); - element.find('.cly-button-menu').removeClass("active"); - element.find(".cly-list-options").removeClass("active"); - $(".cly-button-menu").trigger('cly-list.close', event); - }); - - element.find('.cly-button-menu').off("blur").on("blur", function() { - element.find('.cly-button-menu').removeClass("active"); - element.find(".cly-list-options").removeClass("active"); - $(".cly-button-menu").trigger('cly-list.close', event); - }); - }; - - /** Adds column selector to data table - * @param {object} dtable - data table jquery object - * @param {object} config - configuration for disabling columns - * @param {object} config.disabled - object for disabled column names. Optional. If nothing set, you can disable all columns. Example: {"name1":true,"name2":true} - * @param {object} config.visible -Default visible columns. If none set - first N are taken to not exceed max column count. If user has changed it, it gets overwritten by data stored in local storage. - * @param {number} config.maxCol - max column count. If not set - max == all columns. - * @param {string} tableName - table name. Used to create name for storage. need to be unique for every table. - * - * Example: - * CountlyHelpers.addColumnSelector(dtable,{"disabled:"{"name1":true,"name2":true},maxCol:6},"myTableName"); - * Safe way would be adding in "fnInitComplete" function: - * - * "fnInitComplete": function(oSettings, json) { - * $.fn.dataTable.defaults.fnInitComplete(oSettings, json); - * CountlyHelpers.addColumnSelector(this, {"disabled":{"name1":true,"name2":true}, "maxCol":5 }, "viewsTable"); - * }, - */ - CountlyHelpers.addColumnSelector = function(dtable, config, tableName) { - config = config || {}; - config.disabled = config.disabled || {}; - - var haveConfigVisible = false; - if (!config.visible) { - config.visible = {}; - } - else { - haveConfigVisible = true; - } - - var settings = store.get(tableName + "VisibleDataTableColumns"); - var settingsOld = store.get(tableName + "HiddenDataTableColumns") ; - var saveSettings = false; - var tableCols = dtable.fnSettings().aoColumns || []; - var maxCol = config.maxCol || tableCols.length; - var colIndex = 0; - - //Take values if selection is stored in old format - if (settingsOld && typeof settingsOld === 'object' && Object.keys(settingsOld).length > 0) { - settings = settings || {}; - var dd = {}; - for (colIndex = 0; colIndex < tableCols.length; colIndex++) { - if (tableCols[colIndex].columnSelectorIndex) { - dd[tableCols[colIndex].columnSelectorIndex] = true; - } - } - for (var z in settingsOld) { - var i = parseInt(z, 10); - if (tableCols[i] && tableCols[i].columnSelectorIndex) { - dd[tableCols[i].columnSelectorIndex] = false; - } - } - - for (var zz in config.disabled) { - if (dd && dd[zz]) { - dd[zz] = false; - } - } - var cc = 0; - for (var p in dd) { - if (dd[p] === true && cc < maxCol) { - settings[p] = true; - cc = cc + 1; - } - } - saveSettings = true; - store.remove(tableName + "HiddenDataTableColumns"); - } - - if (settings && typeof settings === 'object') { - config.visible = settings; - haveConfigVisible = true; - } - else { - saveSettings = true; - } - - var totalCol = 0; - var SelectedReviewMap = {}; - - dtable.CoultyColumnSel = {}; - dtable.CoultyColumnSel.tableCol = 0; - - var str = ""; - var selectedC = 0; - - - //Clear out keys not represented in table - for (var k in config.visible) { - SelectedReviewMap[k] = 4; - } - for (colIndex = 0; colIndex < tableCols.length; colIndex++) { - if (tableCols[colIndex].columnSelectorIndex) { - if (!(config.disabled[tableCols[colIndex].columnSelectorIndex])) { - totalCol = totalCol + 1; - } - if (SelectedReviewMap[tableCols[colIndex].columnSelectorIndex]) { - SelectedReviewMap[tableCols[colIndex].columnSelectorIndex] = 5; - } - } - } - - for (var zp in SelectedReviewMap) { - if (SelectedReviewMap[zp] === 4) { - delete config.visible[zp]; - saveSettings = true; - } - } - - //Take first N values if none set by config or stored selection - if (!haveConfigVisible) { - var cp = 0; - for (colIndex = 0; colIndex < tableCols.length && cp < maxCol; colIndex++) { - if (tableCols[colIndex].columnSelectorIndex) { - if (!(config.disabled[tableCols[colIndex].columnSelectorIndex])) { - config.visible[tableCols[colIndex].columnSelectorIndex] = true; - cp++; - } - } - } - saveSettings = true; - } - - if (saveSettings) { // we don't have stored value - store.set(tableName + "VisibleDataTableColumns", config.visible); - } - str = redrawColumnsVisibilityTable(tableCols, config, dtable, ""); - selectedC = str.selectedC || 0; - str = str.str || ""; - dtable.CoultyColumnSel.maxCol = Math.min(maxCol, totalCol); - $(dtable[0]).parent().find(".select-column-table-data").first().after('
' + jQuery.i18n.map["common.select-columns-to-display"] + '' + selectedC + '/' + dtable.CoultyColumnSel.maxCol + '
' + str + '
'); - if (tableCols.length > 8) { - $(dtable[0]).parent().find('.scrollable').slimScroll({ - height: '100%', - start: 'top', - wheelStep: 10, - position: 'right', - disableFadeOut: true - }); - } - - if (selectedC >= dtable.CoultyColumnSel.maxCol) { - $(dtable[0]).parent().find(".columncounter").first().addClass('red'); - $(dtable[0]).parent().find(".data-table-column-selector").first().addClass('full-select'); - } - - $(dtable[0]).parent().find(".select-column-table-data").first().on("click", function(e) { - if ($(this).hasClass('active')) { - $(this).removeClass('active'); - } - else { - $(this).addClass('active'); - } - e.stopPropagation(); - }); - - $("body").on("click", function() { - $(dtable[0]).parent().find(".select-column-table-data").first().removeClass("active"); - }); - - $(".data-table-column-selector").on("click", function(e) { - e.stopPropagation(); - }); - - $($(dtable[0]).parent().find(".data-table-column-selector")).on("click", "td", function() { - var checkbox = $(this).find(".data-table-toggle-column").first(); - var isChecked = $(checkbox).hasClass("fa-check-square");//is now checked - if (!(config.disabled && config.disabled[$(this).data("selectorname")] && config.disabled[$(this).data("selectorname")] === true)) { - if (isChecked) { - $(checkbox).addClass("fa-square-o"); - $(checkbox).removeClass("fa-check-square"); - $(this).addClass('not-checked'); - CountlyHelpers.changeDTableColVis(config, dtable, tableName, $(this).data("selectorname"), false); - } - else { - if (CountlyHelpers.changeDTableColVis(config, dtable, tableName, $(this).data("selectorname"), true)) { - $(checkbox).removeClass("fa-square-o"); - $(checkbox).addClass("fa-check-square"); - $(this).removeClass('not-checked'); - } - } - } - }); - - $(dtable[0]).parent().find(".export-columns-search input").on("keyup", function() { - var value = $(dtable[0]).parent().find(".export-columns-search input").val(); - var settings_my = store.get(tableName + "VisibleDataTableColumns") || {}; - var vv = redrawColumnsVisibilityTable(tableCols, {visible: settings_my, disabled: config.disabled, maxCol: config.maxCol}, dtable, value); - $(dtable[0]).parent().find(".data-table-column-selector .all_columns table").first().replaceWith("" + vv.str + "
"); - }); - - - $(dtable[0]).parent().find(".select-column-table-data").css("display", "table-cell"); - - - var visibleColCount = dtable.oApi._fnVisbleColumns(dtable.fnSettings()); - $(dtable).find('.dataTables_empty').first().attr("colspan", visibleColCount); - }; - - var redrawColumnsVisibilityTable = function(tableCols, config, dtable, value) { - if (value) { - value = new RegExp((value || ""), 'i'); - } - var myClass = ""; - var myClass2 = ""; - var disabled = ""; - var str = ""; - var startLine = true; - var selectedC = 0; - - - for (var colIndex = 0; colIndex < tableCols.length; colIndex++) { - if (tableCols[colIndex].columnSelectorIndex) { - var colName = tableCols[colIndex].columnSelectorIndex; - myClass = 'fa-check-square'; - myClass2 = ""; - disabled = ""; - - if (config.disabled && config.disabled[tableCols[colIndex].columnSelectorIndex] && config.disabled[tableCols[colIndex].columnSelectorIndex] === true) { - disabled = " disabled"; - } - else if (config.visible && config.visible[tableCols[colIndex].columnSelectorIndex] && config.visible[tableCols[colIndex].columnSelectorIndex] === true) { - selectedC++; - } - else { - myClass = 'fa-square-o'; - myClass2 = ' not-checked'; - dtable.fnSetColumnVis(parseInt(colIndex), false, false); - } - var hideMe = false; - if (value && !tableCols[colIndex].sTitle.match(value)) { - hideMe = true; - } - if (hideMe) { - if (startLine) { - str += "
" + tableCols[colIndex].sTitle + ""; - } - else { - str += "
" + tableCols[colIndex].sTitle + ""; - } - } - else if (startLine === true) { - str += "
" + tableCols[colIndex].sTitle + ""; - startLine = false; - } - else { - str += "
" + tableCols[colIndex].sTitle + ""; - startLine = true; - } - } - } - if (!startLine) { - str += ""; - } - - return {str: str, selectedC: selectedC}; - }; - - /** function hides column in data table and stores config in local storage - * @param {object} config - config object for table - * @param {object} dtable - data table object - * @param {string} tableName - name to use to save in local storage settings - * @param {number} col - column number - * @param {boolean} visible - true - if need to show - * @returns {boolean} if changes were applied - true, if not false. Changes could not be applied if selecting this column means selecting more columns than allowed - */ - CountlyHelpers.changeDTableColVis = function(config, dtable, tableName, col, visible) { - var settings = store.get(tableName + "VisibleDataTableColumns") || {}; - var applyChanges = true; - if (visible) { - if (!settings[col] && Object.keys(settings).length < dtable.CoultyColumnSel.maxCol) { - settings[col] = true; - } - else { - applyChanges = false; - } - } - else { - delete settings[col]; - } - - var selC = 0; - - - if (applyChanges) { - var tableCols = dtable.fnSettings().aoColumns; - for (var colIndex = 0; colIndex < tableCols.length; colIndex++) { - if (tableCols[colIndex].columnSelectorIndex) { - if (settings[tableCols[colIndex].columnSelectorIndex] === true) { - dtable.fnSetColumnVis(colIndex, true, true); - selC++; - } - else if (config.disabled[tableCols[colIndex].columnSelectorIndex] === true) { - dtable.fnSetColumnVis(colIndex, true, false); - } - else { - dtable.fnSetColumnVis(colIndex, false, false); - } - } - } - - $(dtable[0]).parent().find(".columncounter").first().html(selC + "/" + dtable.CoultyColumnSel.maxCol); - - if (selC >= dtable.CoultyColumnSel.maxCol) { - $(dtable[0]).parent().find(".columncounter").first().addClass('red'); - $(dtable[0]).parent().find(".data-table-column-selector").first().addClass('full-select'); - } - else { - $(dtable[0]).parent().find(".columncounter").first().removeClass('red'); - $(dtable[0]).parent().find(".data-table-column-selector").first().removeClass('full-select'); - } - - store.set(tableName + "VisibleDataTableColumns", settings); - var visibleColCount = dtable.oApi._fnVisbleColumns(dtable.fnSettings()); - $(dtable).find('.dataTables_empty').first().attr("colspan", visibleColCount); - - var wrapper = dtable.parents('.dataTables_wrapper').first(); - if ($(wrapper).find('.sticky-header').length > 0) { //check if we have sticky header - dtable.stickyTableHeaders(); //fix sticky header - } - } - return applyChanges; - }; - - /** - * Refresh existing datatable instance on view refresh, providing new data - * @param {object} dTable - jQuery object datatable reference - * @param {object} newDataArr - array with new data in same format as provided while initializing table - * @example - * CountlyHelpers.refreshTable(self.dtable, data); - */ - CountlyHelpers.refreshTable = function(dTable, newDataArr) { - var oSettings = dTable.fnSettings(); - dTable.fnClearTable(false); - - if (newDataArr && newDataArr.length) { - for (var i = 0; i < newDataArr.length; i++) { - dTable.oApi._fnAddData(oSettings, newDataArr[i]); - } - } - - if (store.get(dTable[0].id + '_sort')) { - oSettings.aaSorting = [store.get(dTable[0].id + '_sort')]; - } - - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - dTable.fnStandingRedraw(); - dTable.trigger("table.refresh"); - }; - - /** - * In some cases you may want to allow expanding rows of your datatable. To do that you must add unique id to each row via datatables fnRowCallback property - * @param {object} dTable - jQuery object datatable reference - * @param {function} getData - callback function to be called when clicking ont he row. This function will receive original row data object you passed to data tables and should return HTML string to display in subcell - * @param {object} context - this context if needed, which will be passed to getData function as second parameter - * @example - * function formatData(data){ - * // `data` is the original data object for the row - * //return string to display in subcell - * var str = ''; - * if(data){ - * str += '
'+ - * JSON.stringify(data)+ - * '
'; - * } - * return str; - * } - * this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - * "aaData": crashData.data, - * "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { - * $(nRow).attr("id", aData._id); - * }, - * "aoColumns": [ - * { "mData": "ts"}, "sType":"format-ago", "sTitle": jQuery.i18n.map["crashes.crashed"]}, - * { "mData": "os", "sType":"string", "sTitle": jQuery.i18n.map["crashes.os_version"] }, - * { "mData": "device"}, "sType":"string", "sTitle": jQuery.i18n.map["crashes.device"]}, - * { "mData": "app_version", "sType":"string", "sTitle": jQuery.i18n.map["crashes.app_version"] } - * ] - * })); - * CountlyHelpers.expandRows(this.dtable, formatData); - */ - CountlyHelpers.expandRows = function(dTable, getData, context) { - dTable.aOpen = []; - dTable.on("click", "tr", function() { - var nTr = this; - var id = $(nTr).attr("id"); - if (id) { - var i = $.inArray(id, dTable.aOpen); - - if (i === -1) { - $(nTr).addClass("selected"); - var nDetailsRow = dTable.fnOpen(nTr, getData(dTable.fnGetData(nTr), context), 'details'); - $('div.datatablesubrow', nDetailsRow).show(); - dTable.aOpen.push(id); - dTable.trigger("row.open", id); - } - else { - $(nTr).removeClass("selected"); - $('div.datatablesubrow', $(nTr).next()[0]).hide(); - dTable.fnClose(nTr); - dTable.aOpen.splice(i, 1); - dTable.trigger("row.close", id); - } - var expandIcon = $(nTr).find(".expand-row-icon"); - if (expandIcon.length === 1) { - expandIcon.text("keyboard_arrow_" + ((i === -1) ? "up" : "down")); - } - } - }); - }; + */ + CountlyHelpers.showQuickstartPopover = function(content) { + if (countlyGlobal.ssr) { + return; + } + if (window.countlyVue && window.countlyVue.vuex) { + var payload = { + intent: "quickstart", + message: content, + width: "314", + }; - CountlyHelpers.expandRowIconColumn = function() { - return { - "mData": - function() { - return ' keyboard_arrow_down '; - }, - "sType": "string", - "sTitle": '', - "bSortable": false, - "noExport": true, - 'sWidth': '1px' - }; + var currentStore = window.countlyVue.vuex.getGlobalStore(); + if (currentStore) { + currentStore.dispatch('countlyCommon/onAddDialog', payload); + } + } }; /** - * If you allow to open/expand rows, then when refreshing table they will close again. To avoid that you must call this function on each refresh after calling {@link CountlyHelpers.refreshTable} - * @param {object} dTable - jQuery object datatable reference - * @param {function} getData - callback function to be called when clicking ont he row. This function will receive original row data object you passed to data tables and should return HTML string to display in subcell - * @param {object} context - this context if needed, which will be passed to getData function as second parameter + * Check the value which passing as parameter + * isJSON or not + * return result as boolean + * @param {object} val - value of form data + * @returns {boolean} is this a json object? * @example - * CountlyHelpers.refreshTable(self.dtable, data); - * CountlyHelpers.reopenRows(self.dtable, formatData); + * CountlyHelpers.isJSON(variable); */ - CountlyHelpers.reopenRows = function(dTable, getData, context) { - var nTr; - if (dTable.aOpen) { - $.each(dTable.aOpen, function(i, id) { - nTr = $("#" + id)[0]; - $(nTr).addClass("selected"); - $(nTr).find('i.expand-row-icon').text('keyboard_arrow_up'); - var nDetailsRow = dTable.fnOpen(nTr, getData(dTable.fnGetData(nTr), context), 'details'); - $('div.datatablesubrow', nDetailsRow).show(); - dTable.trigger("row.reopen", id); - }); + CountlyHelpers.isJSON = function(val) { + try { + JSON.parse(val); + return true; + } + catch (notJSONError) { + return false; } }; - /** - * Close all opened datatables rows - * @param {object} dTable - jQuery object datatable reference - * @example - * CountlyHelpers.closeRows(self.dtable); - */ - CountlyHelpers.closeRows = function(dTable) { - if (dTable.aOpen) { - $.each(dTable.aOpen, function(i, id) { - var nTr = $("#" + id)[0]; - $(nTr).removeClass("selected"); - $(nTr).find('i.expand-row-icon').text('keyboard_arrow_down'); - $('div.datatablesubrow', $(nTr).next()[0]).slideUp(function() { - dTable.fnClose(nTr); - dTable.aOpen.splice(i, 1); - }); - dTable.trigger("row.close", id); + CountlyHelpers.displayExportStatus = function(error, export_id, task_id) { + if (error) { + CountlyHelpers.alert(error, "red"); + } + else if (export_id) { + CountlyHelpers.notify({ + type: "ok", + title: jQuery.i18n.map["common.success"], + message: jQuery.i18n.map["export.export-finished"], + info: jQuery.i18n.map["app-users.export-finished-click"], + sticky: false, + clearAll: true, + onClick: function() { + var win = window.open(countlyCommon.API_PARTS.data.r + "/export/download/" + task_id + "?auth_token=" + countlyGlobal.auth_token + "&app_id=" + countlyCommon.ACTIVE_APP_ID, '_blank'); + win.focus(); + } }); + self.refresh(); + } + else if (task_id) { + CountlyHelpers.notify({type: "ok", title: jQuery.i18n.map["common.success"], message: jQuery.i18n.map["export.export-started"], sticky: false, clearAll: false}); + // self.refresh(); + } + else { + CountlyHelpers.alert(jQuery.i18n.map["export.export-failed"], "red"); } }; @@ -2665,36 +500,6 @@ document.getElementsByTagName("head")[0].appendChild(fileref); }; - CountlyHelpers.messageText = function(messagePerLocale) { - if (!messagePerLocale) { - return ''; - } - else if (messagePerLocale.default) { - return messagePerLocale.default; - } - else if (messagePerLocale.en) { - return messagePerLocale.en; - } - else { - for (var locale in messagePerLocale) { - return messagePerLocale[locale]; - } - } - return ''; - }; - /** - * Creates function to be used as mRender for datatables to clip long values - * @param {function=} f - optional function to change passed data to render and return changed object - * @param {string=} nothing - text to display in cellS - * @returns {function} to be used as mRender for datatables to clip long values - */ - CountlyHelpers.clip = function(f, nothing) { - return function(opt) { - var res = typeof f === 'function' ? f(opt) : opt; - return '
' + (res || nothing) + '
'; - }; - }; - /** * Create Countly metric model to fetch metric data from server and provide it to views * @param {object} countlyMetric - initial metric object if you want to pre provide some methods, etc @@ -3407,80 +1212,6 @@ }; - /** - * Initialize countly text select. In most cases it is done automatically, only in some cases, when content loaded via ajax request outside of view lifecycle, you may need to initialize it yourself for your content specifically - * @param {object} element - jQuery object reference - * @example - * CountlyHelpers.initializeTextSelect($("#my-dynamic-div")); - */ - CountlyHelpers.initializeTextSelect = function(element) { - element = element || $("#content-container"); - - element.off("click", ".cly-text-select").on("click", ".cly-text-select", function(e) { - if ($(this).hasClass("disabled")) { - return true; - } - - initItems($(this)); - - $("#date-picker").hide(); - e.stopPropagation(); - }); - - element.off("click", ".cly-text-select .select-items .item").on("click", ".cly-text-select .select-items .item", function() { - var selectedItem = $(this).parents(".cly-text-select").find(".text"); - selectedItem.text($(this).text()); - selectedItem.data("value", $(this).data("value")); - selectedItem.val($(this).text()); - }); - - element.off("keyup", ".cly-text-select input").on("keyup", ".cly-text-select input", function() { - initItems($(this).parents(".cly-text-select"), true); - - $(this).data("value", $(this).val()); - - if (!$(this).val()) { - $(this).parents(".cly-text-select").find(".item").removeClass("hidden"); - } - else { - $(this).parents(".cly-text-select").find(".item:not(:contains('" + $(this).val() + "'))").addClass("hidden"); - $(this).parents(".cly-text-select").find(".item:contains('" + $(this).val() + "')").removeClass("hidden"); - } - }); - /** - * @param {object} select - html select element - * @param {boolean} forceShow - if true shows element list - * @returns {boolean} - returns false if there are no elements - */ - function initItems(select, forceShow) { - select.removeClass("req"); - - var selectItems = select.find(".select-items"); - - if (!selectItems.length) { - return false; - } - - if (select.find(".select-items").is(":visible") && !forceShow) { - select.find(".select-items").hide(); - } - else { - select.find(".select-items").show(); - select.find(".select-items>div").addClass("scroll-list"); - select.find(".scroll-list").slimScroll({ - height: '100%', - start: 'top', - wheelStep: 10, - position: 'right', - disableFadeOut: true - }); - } - } - - $(window).click(function() { - $(".select-items").hide(); - }); - }; /** * Shuffle string using crypto.getRandomValues * @param {string} text - text to be shuffled @@ -3593,43 +1324,6 @@ return false; }; - /** - * Upload file by the passed optional parameters - * @param {object} el - dom element - * @param {string} url - upload url - * @param {object} data - data object that will send with upload request - * @param {function} callback - callback for upload result - */ - CountlyHelpers.upload = function(el, url, data, callback) { - $(el).simpleUpload(url, { - data: data, - success: function(response) { - callback(null, response); - }, - error: function(e) { - callback(e, null); - } - }); - }; - - /** - * Function to add breadcrumbs - * @param {Array} breadcrumbs - Array of links with name and url - * @param {DOMELement} el - This is the element to which the breadcrumb will be prepended to in the beginning - */ - CountlyHelpers.initBreadcrumbs = function(breadcrumbs, el) { - var breadcrumbsEl = $("
    "); - for (var i = 0; i < breadcrumbs.length; i++) { - var b = breadcrumbs[i]; - var li = "
  • " + b.name + "
  • "; - $(breadcrumbsEl).find("ul").append(li); - } - - el = el ? $(el) : $("#content .widget"); - - $(breadcrumbsEl).prependTo(el); - }; - /** * Get currently selected period that can be used in ajax requests * @memberof CountlyHelpers @@ -3661,97 +1355,6 @@ return parseFloat((Math.round(value * 100)).toFixed(decimalPlaces)); }; - /* - * Function that returns difference between two arrays - * @param {Array} a1 - first array - * @param {Array} a2 - second array - */ - CountlyHelpers.arrayDiff = function(a1, a2) { - var a = [], diff = []; - - for (var i1 = 0; i1 < a1.length; i1++) { - a[a1[i1]] = true; - } - - for (var i2 = 0; i2 < a2.length; i2++) { - if (a[a2[i2]]) { - delete a[a2[i2]]; - } - else { - a[a2[i2]] = true; - } - } - - for (var k in a) { - diff.push(k); - } - - return diff; - }; - - /* - * Function that returns difference between two arrays - * @param {*} item - item - * @param {Array} array - array - */ - CountlyHelpers.removeItemFromArray = function(item, array) { - var index = array.indexOf(item); - if (index > -1) { - array.splice(index, 1); - } - return array; - }; - - /** - * Function that clean duplicates from passed array. - * @param {Array} array - array - * @return {Array} - array without duplicates - */ - CountlyHelpers.arrayUnique = function(array) { - var a = array.concat(); - for (var i = 0; i < a.length; ++i) { - for (var j = i + 1; j < a.length; ++j) { - if (a[i] === a[j]) { - a.splice(j--, 1); - } - } - } - return a; - }; - - /** - * Function that remove empty values from array. - * @param {array} array - array that contain empty values - * @return {array} - array without empty values - */ - CountlyHelpers.removeEmptyValues = function(array) { - for (var i = array.length - 1; i >= 0; i--) { - if (array[i] === "") { - array.splice(i, 1); - } - } - return array; - }; - - /** - * Function that creates a shallow copy of an object excluding specified fields. - * Warning: If no excluded fields specified, returns the original reference - * @param {Object} obj Main object - * @param {Array} excluded Array of excluded fields - * @returns {Object} Shallow copy (If no excluded fields, the original reference) - */ - CountlyHelpers.objectWithoutProperties = function(obj, excluded) { - if (!obj || !excluded || excluded.length === 0) { - return obj; - } - return Object.keys(obj).reduce(function(acc, val) { - if (excluded.indexOf(val) === -1) { - acc[val] = obj[val]; - } - return acc; - }, {}); - }; - /** function sha1 * @param {string} str - string to encode * @returns {string} encoded sring @@ -3902,44 +1505,9 @@ return temp.toLowerCase(); }; - - $(document).ready(function() { - $("#overlay").click(function() { - var dialog = $(".dialog:visible:not(.cly-loading)"); - if (dialog.length) { - dialog.fadeOut().remove(); - $(this).hide(); - } - }); - - $(document).on('click', "#dialog-ok, #dialog-cancel, #dialog-continue", function() { - $(this).parents(".dialog:visible").fadeOut().remove(); - if (!$('.dialog:visible').length) { - $("#overlay").hide(); - } - }); - - $(document).keyup(function(e) { - // ESC - if (e.keyCode === 27) { - $(".dialog:visible").animate({ - top: 0, - opacity: 0 - }, { - duration: 1000, - easing: 'easeOutQuart', - complete: function() { - $(this).remove(); - } - }); - - $("#overlay").hide(); - } - }); - }); - }(window.CountlyHelpers = window.CountlyHelpers || {})); + var Template = function() { this.cached = {}; this.raw = {}; @@ -4056,12 +1624,7 @@ $.extend(Template.prototype, { */ store: function(name, raw) { T.raw[name] = raw; - try { - T.cached[name] = Handlebars.compile(raw); - } - catch (ex) { - T.cached[name] = raw; - } + T.cached[name] = raw; }, /** * Generate request URL for template @@ -4077,333 +1640,3 @@ $.extend(Template.prototype, { return name + "?" + countlyGlobal.countlyVersion; } }); - - -if ($.widget) { - $.widget("cly.datepickerExtended", { - _init: function() { - var self = this; - - if (this.options.range === true) { - this._initRangeSelection(); - } - else { - this._initDateSelection(); - } - - $(this.element).addClass("datepicker-extended"); - - this.baseInstance = this.element.datepicker(this.options); - - if (this.options.textEdit === true) { - this._initTextEdit(); - } - setTimeout(function() { - self._finalizeInit(); - }, 0); - }, - - // Private, range picker - _initRangeSelection: function() { - var self = this, - originalOnSelect = this.options.onSelect, - originalBeforeShowDay = this.options.beforeShowDay || function() { - return [true, "", ""]; - }, - currentFirst = null, - currentSecond = null, - $el = this.element; - - this.committedRange = null; - this.temporaryRange = null; - this.isSelectingSecond = false; - - /** - * Wraps onSelect callback of jQuery UI Datepicker and - * injects the necessary business logic needed for range picking - * @param {String} dateText Date as string, passed by Datepicker - * @param {Object} inst Instance object, passed by Datepicker - */ - function _onSelect(dateText, inst) { - var point = self.isSelectingSecond ? "second" : "first"; - if (originalOnSelect) { - originalOnSelect.apply($($el), [dateText, inst, point]); - } - - var instance = $($el).data("datepicker"); - var parsedDate = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, dateText, instance.settings); - parsedDate.setHours(0, 0, 0, 0); - var reset = false; - - if (self.isSelectingSecond && parsedDate < currentFirst) { - self.isSelectingSecond = false; - reset = true; - // reset - } - - if (self.isSelectingSecond) { - currentSecond = parsedDate; - self.temporaryRange = null; - self._commitRange(currentFirst, currentSecond, true); - $($el).find(".text-fields input").removeClass("focused"); - } - else { - currentFirst = parsedDate; - $($el).find(".input-1").addClass("focused"); - } - self.isSelectingSecond = !self.isSelectingSecond; - if (reset) { - self._onTemporaryRangeUpdate(currentFirst, null); - } - } - - /** - * Wraps beforeShowDay callback of jQuery UI Datepicker and - * injects the necessary business logic needed for highlighting - * the current and temporary range. - * @param {Date} date Date as Date, passed by Datepicker - * @returns {Array} Array structure requested by Datepicker UI - */ - function _beforeShowDay(date) { - var returned = originalBeforeShowDay.apply($($el), [date]); - var targetRange = self.committedRange; - if (self.isSelectingSecond) { - targetRange = self.temporaryRange; - } - if (targetRange) { - if (targetRange[0] < date && date < targetRange[1]) { - return [returned[0], returned[1] + " in-range", returned[2]]; - } - if (targetRange[0].getTime() === date.getTime() || date.getTime() === targetRange[1].getTime()) { - return [returned[0], returned[1] + " point", returned[2]]; - } - } - return returned; - } - - this.options.beforeShowDay = _beforeShowDay; - this.options.onSelect = _onSelect; - - $($el).addClass("datepicker-range"); - - $($el).on("mouseover", ".ui-state-default", function() { - self._onTemporaryRangeUpdate(currentFirst, self._cellToDate($(this).parent())); - }); - - $($el).on("mouseout", ".ui-state-default", function() { - self._onTemporaryRangeUpdate(currentFirst, null); - }); - }, - _onTemporaryRangeUpdate: function(currentFirst, temporarySecond) { - var self = this; - if (!self.isSelectingSecond) { - return; - } - if (temporarySecond && currentFirst <= temporarySecond) { - self.temporaryRange = [currentFirst, temporarySecond]; - } - else { - self.temporaryRange = [currentFirst, currentFirst]; - } - self._syncWith("picker", 0); - self._syncWith("picker", 1); - self._refreshCellStates(); - }, - _commitRange: function(dateFirst, dateSecond, fireOnCommit) { - var self = this, - $el = this.element; - - self.committedRange = [dateFirst, dateSecond].sort(function(a, b) { - return a - b; - }); - - var minDate = self.baseInstance.datepicker("option", "minDate"), - maxDate = self.baseInstance.datepicker("option", "maxDate"); - - minDate = minDate ? moment(minDate, "MM/DD/YYYY").toDate() : false; - maxDate = maxDate ? moment(maxDate, "MM/DD/YYYY").toDate() : false; - - if (minDate && minDate - self.committedRange[0] > 0) { - self.committedRange[0] = new Date(minDate.getTime()); - } - - if (maxDate && self.committedRange[1] - maxDate > 0) { - self.committedRange[1] = new Date(maxDate.getTime()); - } - - self.committedRange[0].setHours(0, 0, 0, 0); - self.committedRange[1].setHours(0, 0, 0, 0); - - if (fireOnCommit && self.options.onCommit) { - self.options.onCommit.apply($($el), self.committedRange); - } - self._syncWith("picker", 0, { onlyCommitted: true }); - self._syncWith("picker", 1, { onlyCommitted: true }); - }, - - // Private, generic - _initDateSelection: function() { - var self = this, - originalOnSelect = this.options.onSelect, - $el = this.element; - - /** - * Wraps onSelect callback of jQuery UI Datepicker and - * injects the necessary business logic needed for picker -> text field - * data binding. - * @param {String} dateText Date as string, passed by Datepicker - * @param {Object} inst Instance object, passed by Datepicker - */ - function _onSelect(dateText, inst) { - originalOnSelect.apply($($el), [dateText, inst]); - self._syncWith("picker", 0); - } - - this.options.onSelect = _onSelect; - }, - _initTextEdit: function() { - var $el = this.element, - self = this; - - $($el).addClass("datepicker-text-edit"); - $($el).prepend("
    "); - - $el.find(".text-fields").append(''); - if (this.options.range === true) { - $el.find(".text-fields").append(''); - } - - $($el).on("keyup", ".text-fields input", function(event) { - if (event.keyCode === 13) { - var date = moment($(this).val(), "MM/DD/YYYY"); - var inputIdx = parseInt($(this).data("input"), 10); - - if (date.isValid()) { - // update the picker value - self._syncWith("text", inputIdx, {isDOMEvent: true}); - } - else { - // revert back to the original value - self._syncWith("picker", inputIdx); - } - } - }); - }, - _syncWith: function(source, inputIdx, syncOptions) { - - if (!this.options.textEdit) { - return; - } - - syncOptions = syncOptions || {}; - - var $el = this.element, - self = this; - - if (source === "text") { - var parsedDate = moment($($el).find(".text-fields .input-" + inputIdx).val(), "MM/DD/YYYY").toDate(); - if (self.options.range !== true && inputIdx === 0) { - self.setDate(parsedDate); - if (syncOptions.isDOMEvent) { - // manually trigger onSelect - self.baseInstance.find('.ui-datepicker-current-day').click(); // represents the current day - } - } - else if (self.options.range === true) { - if (self.isSelectingSecond) { - self.isSelectingSecond = false; - // abort the ongoing picking - } - if (inputIdx === 0) { - self._commitRange(parsedDate, self.committedRange[1], syncOptions.isDOMEvent); - } - else if (inputIdx === 1) { - self._commitRange(self.committedRange[0], parsedDate, syncOptions.isDOMEvent); - } - this.baseInstance.datepicker("setDate", parsedDate); - this.baseInstance.datepicker("refresh"); - } - } - else if (source === "picker") { - if (self.options.range !== true && inputIdx === 0) { - $($el).find(".text-fields .input-" + inputIdx).val(moment(self.getDate()).format("MM/DD/YYYY")); - } - else if (self.options.range === true) { - var targetRange = self.committedRange; - if (self.isSelectingSecond && !syncOptions.onlyCommitted) { - targetRange = self.temporaryRange; - } - var selectedDate = targetRange[inputIdx]; - $($el).find(".text-fields .input-" + inputIdx).val(moment(selectedDate).format("MM/DD/YYYY")); - } - } - }, - _finalizeInit: function() { - if (this.options.range === true) { - if (this.options.defaultRange) { - this.setRange(this.options.defaultRange); - } - else { - this.setRange([moment().subtract(8, "d").startOf("d").toDate(), moment().subtract(1, "d").startOf("d").toDate()]); - } - } - }, - _cellToDate: function(element) { - var day = parseInt($(element).find("a").text(), 10); - var month = parseInt($(element).data("month"), 10); - var year = parseInt($(element).data("year"), 10); - if (Number.isInteger(day) && Number.isInteger(month) && Number.isInteger(year)) { - return new Date(year, month, day, 0, 0, 0, 0); - } - else { - return null; - } - }, - _refreshCellStates: function() { - var self = this, - $el = this.element; - - $($el).find(".ui-datepicker-calendar td").each(function() { - var parsedDate = self._cellToDate($(this)); - if (parsedDate) { - var returned = self.options.beforeShowDay(parsedDate); - $(this).attr('class', returned[1]); - } - }); - }, - - // Public - abortRangePicking: function() { - if (this.options.range === true) { - this.isSelectingSecond = false; - this._syncWith("picker", 0); - this._syncWith("picker", 1); - this.temporaryRange = null; - $(this.element).find(".text-fields input").removeClass("focused"); - this.baseInstance.datepicker("refresh"); - } - }, - getRange: function() { - return this.committedRange; - }, - getDate: function() { - if (this.options.range === true) { - return this.getRange(); - } - return this.baseInstance.datepicker("getDate"); - }, - setRange: function(dateRange) { - this._commitRange(dateRange[0], dateRange[1]); - this.baseInstance.datepicker("setDate", dateRange[1]); - }, - setDate: function(date) { - if (this.options.range === true) { - this.setRange(date); - } - else { - this.baseInstance.datepicker("setDate", date); - this._syncWith("picker", 0); - } - }, - }); -} diff --git a/frontend/express/public/javascripts/countly/countly.template.js b/frontend/express/public/javascripts/countly/countly.template.js index 2873caaf92b..961f8392d6b 100644 --- a/frontend/express/public/javascripts/countly/countly.template.js +++ b/frontend/express/public/javascripts/countly/countly.template.js @@ -1,295 +1,4 @@ -/* global Backbone, countlyAuth, Handlebars, countlyEvent, countlyCommon, countlyGlobal, countlyView, CountlyHelpers, countlySession, moment, Drop, _, store, countlyLocation, jQuery, $, T, countlyVue*/ -/** - * View class to expand by plugins which need configuration under Management->Applications. - * @name countlyManagementView - * @global - * @namespace countlyManagementView - */ -window.countlyManagementView = countlyView.extend({ - /** - * Handy function which returns currently saved configuration of this plugin or empty object. - * @memberof countlyManagementView - * @return {Object} app object - */ - config: function() { - return countlyGlobal.apps[this.appId] && - countlyGlobal.apps[this.appId].plugins && - countlyGlobal.apps[this.appId].plugins[this.plugin] || {}; - }, - - /** - * Set current app id - * @memberof countlyManagementView - * @param {string} appId - app Id to set - */ - setAppId: function(appId) { - if (appId !== this.appId) { - this.appId = appId; - this.resetTemplateData(); - this.savedTemplateData = JSON.stringify(this.templateData); - } - }, - - /** - * Reset template data when changing app - * @memberof countlyManagementView - */ - resetTemplateData: function() { - this.templateData = {}; - }, - - /** - * Title of plugin configuration tab, override with your own title. - * @memberof countlyManagementView - * @return {String} tab title - */ - titleString: function() { - return 'Default plugin configuration'; - }, - - /** - * Saving string displayed when request takes more than 0.3 seconds, override if needed. - * @memberof countlyManagementView - * @return {String} saving string - */ - savingString: function() { - return 'Saving...'; - }, - - /** - * Callback function called before tab is expanded. Override if needed. - * @memberof countlyManagementView - */ - beforeExpand: function() {}, - - /** - * Callback function called after tab is collapsed. Override if needed. - * @memberof countlyManagementView - */ - afterCollapse: function() {}, - - /** - * Function used to determine whether save button should be visible. Used whenever UI is redrawn or some value changed. Override if needed. - * @memberof countlyManagementView - * @return {Boolean} true if enabled - */ - isSaveAvailable: function() { - return JSON.stringify(this.templateData) !== this.savedTemplateData.toString(); - }, - - /** - * Callback function called to apply changes. Override if validation is needed. - * @memberof countlyManagementView - * @return {String} error to display to user if validation didn't pass - */ - validate: function() { - return null; - }, - - /** - * Function which prepares data to the format required by the server, must return a Promise. - * @memberof countlyManagementView - * @return {Promise} which resolves to object of {plugin-name: {config: true, options: true}} format or rejects with error string otherwise - */ - prepare: function() { - var o = {}; o[this.plugin] = this.templateData; return $.when(o); - }, - - /** - * Show error message returned by server or by validate function. Override if needed. - * @memberof countlyManagementView - * @param {string} error - error message to show - */ - showError: function(error) { - CountlyHelpers.alert(error, 'popStyleGreen', {title: jQuery.i18n.map['management-applications.plugins.smth'], image: 'empty-icon', button_title: jQuery.i18n.map['management-applications.plugins.ok']}); - }, - - /** - * Called whenever element value with name in parameter have been changed. Override if needed. - * @memberof countlyManagementView - */ - onChange: function(/* name */) { }, - - /** - * Called whenever element value with name in parameter have been changed. - * @memberof countlyManagementView - * @param {string} name - key - * @param {string} value - value to set - */ - doOnChange: function(name, value) { - - if (name && countlyCommon.dot(this.templateData, name) !== value) { - countlyCommon.dot(this.templateData, name, value); - } - - if (this.isSaveAvailable()) { - this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').show(); - } - else { - this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').hide(); - } - - if (name) { - this.onChange(name, value); - } - }, - - /** - * Save logic: validate, disable save button, submit to the server, - * show loading dialog if it takes long enough, hide it when done, show error if any, enable save button. - * @memberof countlyManagementView - * @param {event} ev - event - * @returns {object} error - */ - save: function(ev) { - ev.preventDefault(); - ev.stopPropagation(); - if (this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').hasClass('disabled') || !this.isSaveAvailable()) { - return; - } - - var error = this.validate(), self = this; - if (error) { - return this.showError(error === true ? jQuery.i18n.map['management-applications.plugins.save.nothing'] : error); - } - - this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').addClass('disabled'); - - this.prepare().then(function(data) { - var dialog, timeout = setTimeout(function() { - dialog = CountlyHelpers.loading(jQuery.i18n.map['management-applications.plugins.saving']); - }, 300); - - $.ajax({ - type: "POST", - url: countlyCommon.API_PARTS.apps.w + '/update/plugins', - data: { - app_id: self.appId, - args: JSON.stringify(data) - }, - dataType: "json", - success: function(result) { - self.el.parent().find("h3[aria-controls=" + self.el.attr("id") + "]").find('.icon-button').removeClass('disabled'); - clearTimeout(timeout); - if (dialog) { - CountlyHelpers.removeDialog(dialog); - } - if (result.result === 'Nothing changed') { - CountlyHelpers.notify({type: 'warning', message: jQuery.i18n.map['management-applications.plugins.saved.nothing']}); - } - else { - CountlyHelpers.notify({title: jQuery.i18n.map['management-applications.plugins.saved.title'], message: jQuery.i18n.map['management-applications.plugins.saved']}); - if (!countlyGlobal.apps[result._id].plugins) { - countlyGlobal.apps[result._id].plugins = {}; - } - self.savedTemplateData = JSON.stringify(self.templateData); - for (var k in result.plugins) { - countlyGlobal.apps[result._id].plugins[k] = result.plugins[k]; - } - self.resetTemplateData(); - self.render(); - } - self.doOnChange(); - }, - error: function(resp) { - try { - resp = JSON.parse(resp.responseText); - } - catch (ignored) { - //ignored excep - } - - self.el.parent().find("h3[aria-controls=" + self.el.attr("id") + "]").removeClass('disabled'); - clearTimeout(timeout); - if (dialog) { - CountlyHelpers.removeDialog(dialog); - } - self.showError(resp.result || jQuery.i18n.map['management-applications.plugins.error.server']); - } - }); - }, function(error1) { - self.el.parent().find("h3[aria-controls=" + self.el.attr("id") + "]").removeClass('disabled'); - self.showError(error1); - }); - }, - - beforeRender: function() { - var self = this; - if (this.templatePath && this.templatePath !== "") { - return $.when(T.render(this.templatePath, function(src) { - self.template = src; - })); - } - else { - return; - } - }, - - render: function() { //backbone.js view render function - var self = this; - - if (!this.savedTemplateData) { - this.savedTemplateData = JSON.stringify(this.templateData); - } - this.el.html(this.template(this.templateData)); - if (!this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').length) { - setTimeout(function() { - $('Save').hide().appendTo(self.el.parent().find("h3[aria-controls=" + self.el.attr("id") + "]")); - }); - - } - - this.el.find('.cly-select').each(function(i, select) { - $(select).off('click', '.item').on('click', '.item', function() { - self.doOnChange($(select).data('name') || $(select).attr('id'), $(this).data('value')); - }); - }); - - this.el.find(' input[type=number]').off('input').on('input', function() { - self.doOnChange($(this).attr('name') || $(this).attr('id'), parseFloat($(this).val())); - }); - - this.el.find('input[type=text], input[type=password]').off('input').on('input', function() { - self.doOnChange($(this).attr('name') || $(this).attr('id'), $(this).val()); - }); - - this.el.find('input[type=file]').off('change').on('change', function() { - self.doOnChange($(this).attr('name') || $(this).attr('id'), $(this).val()); - }); - - this.el.find('.on-off-switch input').on("change", function() { - var isChecked = $(this).is(":checked"), - attrID = $(this).attr("id"); - self.doOnChange(attrID, isChecked); - }); - - setTimeout(function() { - self.el.parent().find("h3[aria-controls=" + self.el.attr("id") + "]").find('.icon-button').off('click').on('click', self.save.bind(self)); - }); - if (this.isSaveAvailable()) { - this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').show(); - } - else { - this.el.parent().find("h3[aria-controls=" + this.el.attr("id") + "]").find('.icon-button').hide(); - } - - app.localize(); - - this.afterRender(); - - return this; - }, -}); - -/** -* Drop class with embeded countly theme, use as any Drop class/instance -* @name CountlyDrop -* @global -* @namespace CountlyDrop -*/ -var CountlyDrop = Drop.createContext({ - classPrefix: 'countly-drop', -}); +/* global Backbone, countlyAuth, countlyCommon, countlyGlobal, CountlyHelpers, moment, _, store, jQuery, $, countlyVue*/ //redefine contains selector for jquery to be case insensitive $.expr[":"].contains = $.expr.createPseudo(function(arg) { @@ -298,32 +7,6 @@ $.expr[":"].contains = $.expr.createPseudo(function(arg) { }; }); -/** -* Set menu items by restriction status, hiding empty menu-categories -* @name setMenuItems -* @global -*/ -function setMenuItems() { - // hide empty section headers - var type = countlyCommon.ACTIVE_APP_ID && countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID] && countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].type ? countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].type : "mobile"; - var categories = $('#' + type + '-type .menu-category'); - for (var j = 0; j < categories.length; j++) { - var children = categories[j].children; - var isEmpty = true; - for (var k = 0; k < children.length; k++) { - if (children[k].className.indexOf('restrict') === -1 && children[k].className.indexOf('item') !== -1) { - isEmpty = false; - } - } - if (isEmpty) { - $(categories[j]).hide(); - } - else { - $(categories[j]).show(); - } - } -} - /** * Main app instance of Backbone AppRouter used to control views and view change flow * @name app @@ -383,9 +66,6 @@ var AppRouter = Backbone.Router.extend({ }, switchApp: function(app_id, callback) { countlyCommon.setActiveApp(app_id); - $("#active-app-name").text(countlyGlobal.apps[app_id].name); - $("#active-app-name").attr('title', countlyGlobal.apps[app_id].name); - $("#active-app-icon").css("background-image", "url('" + countlyGlobal.path + "appimages/" + app_id + ".png')"); //removing requests saved in app app._removeUnfinishedRequests(); @@ -451,40 +131,9 @@ var AppRouter = Backbone.Router.extend({ * node.callback */ }); - - var menu = $("
    "); - menu.addClass("menu-category"); - menu.addClass(category + "-category"); - menu.attr("data-priority", node.priority); - if (node.classes) { - menu.addClass(node.classes); - } - if (node.style) { - menu.attr("style", node.style); - } - menu.append(''); - if (node.html) { - menu.append(node.html); - } this._internalMenuCategories.push(category); - var added = false; - var selector = "#sidebar-menu .sidebar-menu"; - //try adding before first greater priority - $(selector + " > div.menu-category").each(function() { - var cur = parseInt($(this).attr("data-priority")); - if (node.priority < cur) { - added = true; - $(this).before(menu); - return false; - } - }); - - //if not added, maybe we are first or last, so just add it - if (!added) { - $(selector).append(menu); - } if (typeof node.callback === "function") { - node.callback(category, node, menu); + node.callback(category, node); } }, /** @@ -557,62 +206,12 @@ var AppRouter = Backbone.Router.extend({ this._menuForTypes[app_type].push({category: category, node: node}); return; } - //create menu element - var menu = $(""); - menu.addClass("item"); - menu.attr("data-priority", node.priority); - menu.attr("id", node.code + "-menu"); - if (node.url) { - menu.attr("href", node.url); - } - if (node.classes) { - menu.addClass(node.classes); - } - if (node.style) { - menu.attr("style", node.style); - } - menu.append(node.icon); - menu.append('
    ' + (jQuery.i18n.map[node.text] || node.text) + '
    '); - if (node.html) { - menu.append(node.html); - } - if (!node.url && category !== "management" && category !== "users") { this._subMenus[node.code] = true; - menu.hide(); - menu = menu.add('').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e
    ');h.css({zIndex:c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){if(c.disabled)return;a(this).removeClass("ui-resizable-autohide"),b._handles.show()},function(){if(c.disabled)return;b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}return this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement),this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");return a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b),!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);return l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui()),!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}return a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),ea.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;return p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null),a},_proportionallyResize:function(){var b=this.options;if(!this._proportionallyResizeElements.length)return;var c=this.helper||this.element;for(var d=0;d
    ');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.22"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!i)return;e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/d.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*d.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.ui.selectable.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("
    ")},destroy:function(){return this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy(),this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(this.options.disabled)return;var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");return d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element}),!1}})},_mouseDrag:function(b){var c=this;this.dragged=!0;if(this.options.disabled)return;var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}return this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!i||i.element==c.element[0])return;var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.righth||i.bottome&&i.rightf&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f)return e=a(this),!1});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}return this.currentItem=e,this._removeCurrentsFromItems(),!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(!b)return;a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+jf&&b+ka[this.floating?"width":"height"]?l:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return e||(b.style.visibility="hidden"),b},update:function(a,b){if(e&&!d.forcePlaceholderSize)return;b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.containers[d].floating?this.items[i].item.offset().left:this.items[i].item.offset().top;Math.abs(j-h)0?"down":"up")}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;return d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height()),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.leftthis.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.topthis.containment[3]?h-this.offset.click.topthis.containment[2]?i-this.offset.click.left=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");return(b.autoHeight||b.fillHeight)&&c.css("height",""),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(this.options.disabled||b.altKey||b.ctrlKey)return;var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}return f?(a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus(),!1):!0},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];return this._clickHandler({target:b},b),this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(d.disabled)return;if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!g)return;return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(this.running)return;this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data)}}),a.extend(a.ui.accordion,{version:"1.8.22",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size()){b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);return}if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.ui.autocomplete.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.isMultiLine=this.element.is("textarea"),this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(b.options.disabled||b.element.propAttr("readOnly"))return;d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._keyEvent("previous",c);break;case e.DOWN:b._keyEvent("next",c);break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){if(b.options.disabled)return;b.selectedItem=null,b.previous=b.element.val()}).bind("blur.autocomplete",function(a){if(b.options.disabled)return;clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150)}),this._initSource(),this.menu=a("
      ").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,c,d;a.isArray(this.options.source)?(c=this.options.source,this.source=function(b,d){d(a.ui.autocomplete.filter(c,b.term))}):typeof this.options.source=="string"?(d=this.options.source,this.source=function(c,e){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:d,data:c,dataType:"json",success:function(a,b){e(a)},error:function(){e([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length").data("item.autocomplete",c).append(a("
      ").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible")){this.search(null,b);return}if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)},widget:function(){return this.menu.element},_keyEvent:function(a,b){if(!this.isMultiLine||this.menu.element.is(":visible"))this._move(a,b),b.preventDefault()}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(!a(c.target).closest(".ui-menu-item a").length)return;c.preventDefault(),b.select(c)}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){if(!this.active)return;this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active){this.activate(c,this.element.children(b));return}var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:first")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend(""),d.secondary&&b.append(""),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.ui.dialog.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||" ",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("
      ")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){return b.close(a),!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;return a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle),a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1===c._trigger("beforeClose",b))return;return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d),c},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;return e.modal&&!b||!e.stack&&!e.modal?d._trigger("focus",c):(e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c),d)},open:function(){if(this._isOpen)return;var b=this,c=b.options,d=b.uiDialog;return b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode!==a.ui.keyCode.TAB)return;var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey)return d.focus(1),!1;if(b.target===d[0]&&b.shiftKey)return e.focus(1),!1}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open"),b},_createButtons:function(b){var c=this,d=!1,e=a("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("
      ").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){if(a==="click")return;a in f?e[a](b):e.attr(a,b)}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||" "))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.22",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");return b||(this.uuid+=1,b=this.uuid),"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()
      ").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});return a.fn.bgiframe&&c.bgiframe(),this.instances.push(c),c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;return a.browser.msie&&a.browser.version<7?(b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),b
      ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;ic&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i),j===!1?!1:(this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0,!0))},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);return this._slide(a,this._handleIndex,c),!1},_mouseStop:function(a){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;return this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e,this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};return this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c1){this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);return}if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;return Math.abs(c)*2>=b&&(d+=c>0?b:-b),parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.22"})})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.ui.tabs.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){function e(){return++c}function f(){return++d}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
      ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
    • #{label}
    • "},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash)return e.selected=a,!1}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1)return this.blur(),!1;e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected"))return e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur(),!1;if(!f.length)return e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur(),!1}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){return typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$='"+a+"']"))),a},destroy:function(){var b=this.options;return this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie),this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);return j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e])),this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();return d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0])),this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)==-1)return;return this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b])),this},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;return a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a]))),this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;return this.anchors.eq(a).trigger(this.options.event+".tabs"),this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}return this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs"),this},abort:function(){return this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup(),this},url:function(a,b){return this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b),this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.22"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a'))}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);if(!c.length)return;c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);if($.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])||!d.length)return;d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover")})}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}$.extend($.ui,{datepicker:{version:"1.8.22"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){return extendRemove(this._defaults,a||{}),this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('
      ')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);if(c.hasClass(this.markerClassName))return;this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a)},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$(''+c+""),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('').addClass(this._triggerClass).html(g==""?f:$("").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=a[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(a[0])):$.datepicker._showDatepicker(a[0]),!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;db&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);if(c.hasClass(this.markerClassName))return;c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block")},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$(''),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f),this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(d){$.datepicker.log(d)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if($.datepicker._isDisabledDatepicker(a)||$.datepicker._lastInput==a)return;var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){return e|=$(this).css("position")=="fixed",!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a)),this._attachHandlers(a);var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+(c?0:$(document).scrollLeft()),i=document.documentElement.clientHeight+(c?0:$(document).scrollTop());return b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0),b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!b||a&&b!=$.data(a,PROP_NAME))return;if(this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=function(){$.datepicker._tidyDialog(b)};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,e):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,e),c||e(),this._datepickerShowing=!1;var f=this._get(b,"onClose");f&&f.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!$.datepicker._curInst)return;var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);if(this._isDisabledDatepicker(d[0]))return;this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e)},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if($(d).hasClass(this._unselectableClass)||this._isDisabledDatepicker(e[0]))return;var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1-1){j=1,k=l;do{var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}while(!0)}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+112?a.getHours()+2:0),a):null},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_attachHandlers:function(a){var b=this._get(a,"stepMonths"),c="#"+a.id;a.dpDiv.find("[data-handler]").map(function(){var a={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(c,-b,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(c,+b,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(c)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(c,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(c,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(c,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),a[this.getAttribute("data-handler")])})},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&pp)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?''+q+"":e?"":''+q+"",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?''+s+"":e?"":''+s+"",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'",x=d?'
      '+(c?w:"")+(this._isInRange(a,v)?'":"")+(c?"":w)+"
      ":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='
      '+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'
      '+"";var R=z?'":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="=5?' class="ui-datepicker-week-end"':"")+">"+''+C[T]+""}Q+=R+"";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z";var _=z?'":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Ym;_+='",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+""}n++,n>11&&(n=0,o++),Q+="
      '+this._get(a,"weekHeader")+"
      '+this._get(a,"calculateWeek")(Y)+""+(bb&&!G?" ":bc?''+Y.getDate()+"":''+Y.getDate()+"")+"
      "+(j?""+(g[0]>0&&N==g[1]-1?'
      ':""):""),M+=Q}K+=M}return K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'':""),a._keyEvent=!1,K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='
      ',m="";if(f||!i)m+=''+g[b]+"";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='"}k||(l+=m+(f||!i||!j?" ":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+=''+c+"";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='",l+=a.yearshtml,a.yearshtml=null}}return l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?" ":"")+m),l+="
      ",l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&bd?d:e,e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));return b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth())),this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");return b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10),{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);return typeof a!="string"||a!="isDisabled"&&a!="getDate"&&a!="widget"?a=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b)):this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)}):$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.22",window["DP_jQuery_"+dpuuid]=$})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.ui.progressbar.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("
      ").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){return a===b?this._value():(this._setOption("value",a),this)},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;return typeof a!="number"&&(a=0),Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.22"})})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.effects.core.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -jQuery.effects||function(a,b){function c(b){var c;return b&&b.constructor==Array&&b.length==3?b:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))?[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]:(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))?[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))?[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)]:(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))?[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)]:(c=/rgba\(0, 0, 0, 0\)/.exec(b))?e.transparent:e[a.trim(b).toLowerCase()]}function d(b,d){var e;do{e=(a.curCSS||a.css)(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};return a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete,[b,c,d,e]}function l(b){return!b||typeof b=="number"||a.fx.speeds[b]?!0:typeof b=="string"&&!a.effects[b]?!0:!1}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){return a.isFunction(d)&&(e=d,d=null),this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class")||"";a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.22",save:function(a,b){for(var c=0;c").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;try{e.id}catch(f){e=document.body}return b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;return b.parent().is(".ui-effects-wrapper")?(c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus(),c):b},setTransition:function(b,c,d,e){return e=e||{},a.each(c,function(a,c){var f=b.cssUnit(c);f[0]>0&&(e[c]=f[0]*d+f[1])}),e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];return a.fx.off||!i?h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)}):i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);return b[1].mode="show",this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);return b[1].mode="hide",this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);return c[1].mode="toggle",this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];return a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])}),d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return b==0?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.effects.fade.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.effects.fold.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.effects.highlight.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.effects.pulsate.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show"),e=(b.options.times||5)*2-1,f=b.duration?b.duration/2:a.fx.speeds._default/2,g=c.is(":visible"),h=0;g||(c.css("opacity",0).show(),h=1),(d=="hide"&&g||d=="show"&&!g)&&e--;for(var i=0;i').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);; \ No newline at end of file diff --git a/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js b/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js deleted file mode 100644 index 05e680507dd..00000000000 --- a/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js +++ /dev/null @@ -1,1670 +0,0 @@ -/*! jQuery UI - v1.8.22 - 2012-07-24 -* https://github.com/jquery/jquery-ui -* Includes: jquery.ui.datepicker-af.js, jquery.ui.datepicker-ar-DZ.js, jquery.ui.datepicker-ar.js, jquery.ui.datepicker-az.js, jquery.ui.datepicker-bg.js, jquery.ui.datepicker-bs.js, jquery.ui.datepicker-ca.js, jquery.ui.datepicker-cs.js, jquery.ui.datepicker-cy-GB.js, jquery.ui.datepicker-da.js, jquery.ui.datepicker-de.js, jquery.ui.datepicker-el.js, jquery.ui.datepicker-en-AU.js, jquery.ui.datepicker-en-GB.js, jquery.ui.datepicker-en-NZ.js, jquery.ui.datepicker-eo.js, jquery.ui.datepicker-es.js, jquery.ui.datepicker-et.js, jquery.ui.datepicker-eu.js, jquery.ui.datepicker-fa.js, jquery.ui.datepicker-fi.js, jquery.ui.datepicker-fo.js, jquery.ui.datepicker-fr-CH.js, jquery.ui.datepicker-fr.js, jquery.ui.datepicker-gl.js, jquery.ui.datepicker-he.js, jquery.ui.datepicker-hi.js, jquery.ui.datepicker-hr.js, jquery.ui.datepicker-hu.js, jquery.ui.datepicker-hy.js, jquery.ui.datepicker-id.js, jquery.ui.datepicker-is.js, jquery.ui.datepicker-it.js, jquery.ui.datepicker-ja.js, jquery.ui.datepicker-ka.js, jquery.ui.datepicker-kk.js, jquery.ui.datepicker-km.js, jquery.ui.datepicker-ko.js, jquery.ui.datepicker-lb.js, jquery.ui.datepicker-lt.js, jquery.ui.datepicker-lv.js, jquery.ui.datepicker-mk.js, jquery.ui.datepicker-ml.js, jquery.ui.datepicker-ms.js, jquery.ui.datepicker-nl-BE.js, jquery.ui.datepicker-nl.js, jquery.ui.datepicker-no.js, jquery.ui.datepicker-pl.js, jquery.ui.datepicker-pt-BR.js, jquery.ui.datepicker-pt.js, jquery.ui.datepicker-rm.js, jquery.ui.datepicker-ro.js, jquery.ui.datepicker-ru.js, jquery.ui.datepicker-sk.js, jquery.ui.datepicker-sl.js, jquery.ui.datepicker-sq.js, jquery.ui.datepicker-sr-SR.js, jquery.ui.datepicker-sr.js, jquery.ui.datepicker-sv.js, jquery.ui.datepicker-ta.js, jquery.ui.datepicker-th.js, jquery.ui.datepicker-tj.js, jquery.ui.datepicker-tr.js, jquery.ui.datepicker-uk.js, jquery.ui.datepicker-vi.js, jquery.ui.datepicker-zh-CN.js, jquery.ui.datepicker-zh-HK.js, jquery.ui.datepicker-zh-TW.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ - -/* Afrikaans initialisation for the jQuery UI date picker plugin. */ -/* Written by Renier Pretorius. */ -jQuery(function($){ - $.datepicker.regional['af'] = { - closeText: 'Selekteer', - prevText: 'Vorige', - nextText: 'Volgende', - currentText: 'Vandag', - monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie', - 'Julie','Augustus','September','Oktober','November','Desember'], - monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', - 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'], - dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'], - dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'], - dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['af']); -}); - -/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ -/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ - -jQuery(function($){ - $.datepicker.regional['ar-DZ'] = { - closeText: 'إغلاق', - prevText: '<السابق', - nextText: 'التالي>', - currentText: 'اليوم', - monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان', - 'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'], - monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], - dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - weekHeader: 'أسبوع', - dateFormat: 'dd/mm/yy', - firstDay: 6, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ar-DZ']); -}); - -/* Arabic Translation for jQuery UI date picker plugin. */ -/* Khaled Alhourani -- me@khaledalhourani.com */ -/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ -jQuery(function($){ - $.datepicker.regional['ar'] = { - closeText: 'إغلاق', - prevText: '<السابق', - nextText: 'التالي>', - currentText: 'اليوم', - monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', - 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], - monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], - dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], - weekHeader: 'أسبوع', - dateFormat: 'dd/mm/yy', - firstDay: 6, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ar']); -}); -/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Jamil Najafov (necefov33@gmail.com). */ -jQuery(function($) { - $.datepicker.regional['az'] = { - closeText: 'Bağla', - prevText: '<Geri', - nextText: 'İrəli>', - currentText: 'Bugün', - monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun', - 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'], - monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun', - 'İyul','Avq','Sen','Okt','Noy','Dek'], - dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'], - dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'], - dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'], - weekHeader: 'Hf', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['az']); -}); -/* Bulgarian initialisation for the jQuery UI date picker plugin. */ -/* Written by Stoyan Kyosev (http://svest.org). */ -jQuery(function($){ - $.datepicker.regional['bg'] = { - closeText: 'затвори', - prevText: '<назад', - nextText: 'напред>', - nextBigText: '>>', - currentText: 'днес', - monthNames: ['Януари','Февруари','Март','Април','Май','Юни', - 'Юли','Август','Септември','Октомври','Ноември','Декември'], - monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни', - 'Юли','Авг','Сеп','Окт','Нов','Дек'], - dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'], - dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'], - dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'], - weekHeader: 'Wk', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['bg']); -}); - -/* Bosnian i18n for the jQuery UI date picker plugin. */ -/* Written by Kenan Konjo. */ -jQuery(function($){ - $.datepicker.regional['bs'] = { - closeText: 'Zatvori', - prevText: '<', - nextText: '>', - currentText: 'Danas', - monthNames: ['Januar','Februar','Mart','April','Maj','Juni', - 'Juli','August','Septembar','Oktobar','Novembar','Decembar'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], - dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], - dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], - weekHeader: 'Wk', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['bs']); -}); -/* Inicialització en català per a l'extenció 'calendar' per jQuery. */ -/* Writers: (joan.leon@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['ca'] = { - closeText: 'Tancar', - prevText: '<Ant', - nextText: 'Seg>', - currentText: 'Avui', - monthNames: ['Gener','Febrer','Març','Abril','Maig','Juny', - 'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'], - monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun', - 'Jul','Ago','Set','Oct','Nov','Des'], - dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'], - dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'], - dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ca']); -}); -/* Czech initialisation for the jQuery UI date picker plugin. */ -/* Written by Tomas Muller (tomas@tomas-muller.net). */ -jQuery(function($){ - $.datepicker.regional['cs'] = { - closeText: 'Zavřít', - prevText: '<Dříve', - nextText: 'Později>', - currentText: 'Nyní', - monthNames: ['leden','únor','březen','duben','květen','červen', - 'červenec','srpen','září','říjen','listopad','prosinec'], - monthNamesShort: ['led','úno','bře','dub','kvě','čer', - 'čvc','srp','zář','říj','lis','pro'], - dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'], - dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'], - dayNamesMin: ['ne','po','út','st','čt','pá','so'], - weekHeader: 'Týd', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['cs']); -}); - -/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ -/* Written by William Griffiths. */ -jQuery(function($){ - $.datepicker.regional['cy-GB'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', - 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], - monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', - 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], - dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], - dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], - dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], - weekHeader: 'Wy', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['cy-GB']); -}); -/* Danish initialisation for the jQuery UI date picker plugin. */ -/* Written by Jan Christensen ( deletestuff@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['da'] = { - closeText: 'Luk', - prevText: '<Forrige', - nextText: 'Næste>', - currentText: 'Idag', - monthNames: ['Januar','Februar','Marts','April','Maj','Juni', - 'Juli','August','September','Oktober','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], - dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'], - dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], - weekHeader: 'Uge', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['da']); -}); - -/* German initialisation for the jQuery UI date picker plugin. */ -/* Written by Milian Wolff (mail@milianw.de). */ -jQuery(function($){ - $.datepicker.regional['de'] = { - closeText: 'schließen', - prevText: '<zurück', - nextText: 'Vor>', - currentText: 'heute', - monthNames: ['Januar','Februar','März','April','Mai','Juni', - 'Juli','August','September','Oktober','November','Dezember'], - monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dez'], - dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], - dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], - dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], - weekHeader: 'KW', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['de']); -}); - -/* Greek (el) initialisation for the jQuery UI date picker plugin. */ -/* Written by Alex Cicovic (http://www.alexcicovic.com) */ -jQuery(function($){ - $.datepicker.regional['el'] = { - closeText: 'Κλείσιμο', - prevText: 'Προηγούμενος', - nextText: 'Επόμενος', - currentText: 'Τρέχων Μήνας', - monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος', - 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'], - monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν', - 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'], - dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'], - dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'], - dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'], - weekHeader: 'Εβδ', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['el']); -}); -/* English/Australia initialisation for the jQuery UI date picker plugin. */ -/* Based on the en-GB initialisation. */ -jQuery(function($){ - $.datepicker.regional['en-AU'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['en-AU']); -}); - -/* English/UK initialisation for the jQuery UI date picker plugin. */ -/* Written by Stuart. */ -jQuery(function($){ - $.datepicker.regional['en-GB'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['en-GB']); -}); - -/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ -/* Based on the en-GB initialisation. */ -jQuery(function($){ - $.datepicker.regional['en-NZ'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['en-NZ']); -}); - -/* Esperanto initialisation for the jQuery UI date picker plugin. */ -/* Written by Olivier M. (olivierweb@ifrance.com). */ -jQuery(function($){ - $.datepicker.regional['eo'] = { - closeText: 'Fermi', - prevText: '<Anta', - nextText: 'Sekv>', - currentText: 'Nuna', - monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio', - 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aŭg','Sep','Okt','Nov','Dec'], - dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'], - dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'], - dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'], - weekHeader: 'Sb', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['eo']); -}); - -/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ -/* Traducido por Vester (xvester@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['es'] = { - closeText: 'Cerrar', - prevText: '<Ant', - nextText: 'Sig>', - currentText: 'Hoy', - monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', - 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], - monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', - 'Jul','Ago','Sep','Oct','Nov','Dic'], - dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], - dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], - dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['es']); -}); -/* Estonian initialisation for the jQuery UI date picker plugin. */ -/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ -jQuery(function($){ - $.datepicker.regional['et'] = { - closeText: 'Sulge', - prevText: 'Eelnev', - nextText: 'Järgnev', - currentText: 'Täna', - monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni', - 'Juuli','August','September','Oktoober','November','Detsember'], - monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', - 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'], - dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], - dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], - dayNamesMin: ['P','E','T','K','N','R','L'], - weekHeader: 'näd', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['et']); -}); -/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */ -/* Karrikas-ek itzulia (karrikas@karrikas.com) */ -jQuery(function($){ - $.datepicker.regional['eu'] = { - closeText: 'Egina', - prevText: '<Aur', - nextText: 'Hur>', - currentText: 'Gaur', - monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', - 'uztaila','abuztua','iraila','urria','azaroa','abendua'], - monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', - 'uzt.','abu.','ira.','urr.','aza.','abe.'], - dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], - dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], - dayNamesMin: ['ig','al','ar','az','og','ol','lr'], - weekHeader: 'As', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['eu']); -}); -/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ -/* Javad Mowlanezhad -- jmowla@gmail.com */ -/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ -jQuery(function($) { - $.datepicker.regional['fa'] = { - closeText: 'بستن', - prevText: '<قبلی', - nextText: 'بعدی>', - currentText: 'امروز', - monthNames: [ - 'فروردين', - 'ارديبهشت', - 'خرداد', - 'تير', - 'مرداد', - 'شهريور', - 'مهر', - 'آبان', - 'آذر', - 'دی', - 'بهمن', - 'اسفند' - ], - monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], - dayNames: [ - 'يکشنبه', - 'دوشنبه', - 'سه‌شنبه', - 'چهارشنبه', - 'پنجشنبه', - 'جمعه', - 'شنبه' - ], - dayNamesShort: [ - 'ی', - 'د', - 'س', - 'چ', - 'پ', - 'ج', - 'ش' - ], - dayNamesMin: [ - 'ی', - 'د', - 'س', - 'چ', - 'پ', - 'ج', - 'ش' - ], - weekHeader: 'هف', - dateFormat: 'yy/mm/dd', - firstDay: 6, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fa']); -}); -/* Finnish initialisation for the jQuery UI date picker plugin. */ -/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['fi'] = { - closeText: 'Sulje', - prevText: '«Edellinen', - nextText: 'Seuraava»', - currentText: 'Tänään', - monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', - 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], - monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', - 'Heinä','Elo','Syys','Loka','Marras','Joulu'], - dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], - dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], - dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], - weekHeader: 'Vk', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fi']); -}); - -/* Faroese initialisation for the jQuery UI date picker plugin */ -/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ -jQuery(function($){ - $.datepicker.regional['fo'] = { - closeText: 'Lat aftur', - prevText: '<Fyrra', - nextText: 'Næsta>', - currentText: 'Í dag', - monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni', - 'Juli','August','September','Oktober','November','Desember'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', - 'Jul','Aug','Sep','Okt','Nov','Des'], - dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'], - dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'], - dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'], - weekHeader: 'Vk', - dateFormat: 'dd-mm-yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fo']); -}); - -/* Swiss-French initialisation for the jQuery UI date picker plugin. */ -/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ -jQuery(function($){ - $.datepicker.regional['fr-CH'] = { - closeText: 'Fermer', - prevText: '<Préc', - nextText: 'Suiv>', - currentText: 'Courant', - monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', - 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], - monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', - 'Jul','Aoû','Sep','Oct','Nov','Déc'], - dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], - dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], - dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], - weekHeader: 'Sm', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fr-CH']); -}); -/* French initialisation for the jQuery UI date picker plugin. */ -/* Written by Keith Wood (kbwood{at}iinet.com.au), - Stéphane Nahmani (sholby@sholby.net), - Stéphane Raimbault */ -jQuery(function($){ - $.datepicker.regional['fr'] = { - closeText: 'Fermer', - prevText: 'Précédent', - nextText: 'Suivant', - currentText: 'Aujourd\'hui', - monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', - 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], - monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin', - 'Juil.','Août','Sept.','Oct.','Nov.','Déc.'], - dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], - dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], - dayNamesMin: ['D','L','M','M','J','V','S'], - weekHeader: 'Sem.', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fr']); -}); - -/* Galician localization for 'UI date picker' jQuery extension. */ -/* Translated by Jorge Barreiro . */ -jQuery(function($){ - $.datepicker.regional['gl'] = { - closeText: 'Pechar', - prevText: '<Ant', - nextText: 'Seg>', - currentText: 'Hoxe', - monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', - 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], - monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', - 'Xul','Ago','Set','Out','Nov','Dec'], - dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], - dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], - dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['gl']); -}); -/* Hebrew initialisation for the UI Datepicker extension. */ -/* Written by Amir Hardon (ahardon at gmail dot com). */ -jQuery(function($){ - $.datepicker.regional['he'] = { - closeText: 'סגור', - prevText: '<הקודם', - nextText: 'הבא>', - currentText: 'היום', - monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', - 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], - monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', - 'יולי','אוג','ספט','אוק','נוב','דצמ'], - dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], - dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], - dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['he']); -}); - -/* Hindi initialisation for the jQuery UI date picker plugin. */ -/* Written by Michael Dawart. */ -jQuery(function($){ - $.datepicker.regional['hi'] = { - closeText: 'बंद', - prevText: 'पिछला', - nextText: 'अगला', - currentText: 'आज', - monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', - 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], - monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', - 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], - dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], - dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], - dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], - weekHeader: 'हफ्ता', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['hi']); -}); - -/* Croatian i18n for the jQuery UI date picker plugin. */ -/* Written by Vjekoslav Nesek. */ -jQuery(function($){ - $.datepicker.regional['hr'] = { - closeText: 'Zatvori', - prevText: '<', - nextText: '>', - currentText: 'Danas', - monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj', - 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'], - monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip', - 'Srp','Kol','Ruj','Lis','Stu','Pro'], - dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], - dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], - dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], - weekHeader: 'Tje', - dateFormat: 'dd.mm.yy.', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['hr']); -}); -/* Hungarian initialisation for the jQuery UI date picker plugin. */ -/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */ -jQuery(function($){ - $.datepicker.regional['hu'] = { - closeText: 'bezár', - prevText: 'vissza', - nextText: 'előre', - currentText: 'ma', - monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', - 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], - monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', - 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'], - dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], - dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'], - dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], - weekHeader: 'Hét', - dateFormat: 'yy.mm.dd.', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['hu']); -}); - -/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ -jQuery(function($){ - $.datepicker.regional['hy'] = { - closeText: 'Փակել', - prevText: '<Նախ.', - nextText: 'Հաջ.>', - currentText: 'Այսօր', - monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս', - 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'], - monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս', - 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'], - dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'], - dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], - dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], - weekHeader: 'ՇԲՏ', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['hy']); -}); -/* Indonesian initialisation for the jQuery UI date picker plugin. */ -/* Written by Deden Fathurahman (dedenf@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['id'] = { - closeText: 'Tutup', - prevText: '<mundur', - nextText: 'maju>', - currentText: 'hari ini', - monthNames: ['Januari','Februari','Maret','April','Mei','Juni', - 'Juli','Agustus','September','Oktober','Nopember','Desember'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', - 'Jul','Agus','Sep','Okt','Nop','Des'], - dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'], - dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'], - dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'], - weekHeader: 'Mg', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['id']); -}); -/* Icelandic initialisation for the jQuery UI date picker plugin. */ -/* Written by Haukur H. Thorsson (haukur@eskill.is). */ -jQuery(function($){ - $.datepicker.regional['is'] = { - closeText: 'Loka', - prevText: '< Fyrri', - nextText: 'Næsti >', - currentText: 'Í dag', - monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní', - 'Júlí','Ágúst','September','Október','Nóvember','Desember'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún', - 'Júl','Ágú','Sep','Okt','Nóv','Des'], - dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'], - dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'], - dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'], - weekHeader: 'Vika', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['is']); -}); -/* Italian initialisation for the jQuery UI date picker plugin. */ -/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['it'] = { - closeText: 'Chiudi', - prevText: '<Prec', - nextText: 'Succ>', - currentText: 'Oggi', - monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', - 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], - monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', - 'Lug','Ago','Set','Ott','Nov','Dic'], - dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], - dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], - dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['it']); -}); - -/* Japanese initialisation for the jQuery UI date picker plugin. */ -/* Written by Kentaro SATO (kentaro@ranvis.com). */ -jQuery(function($){ - $.datepicker.regional['ja'] = { - closeText: '閉じる', - prevText: '<前', - nextText: '次>', - currentText: '今日', - monthNames: ['1月','2月','3月','4月','5月','6月', - '7月','8月','9月','10月','11月','12月'], - monthNamesShort: ['1月','2月','3月','4月','5月','6月', - '7月','8月','9月','10月','11月','12月'], - dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'], - dayNamesShort: ['日','月','火','水','木','金','土'], - dayNamesMin: ['日','月','火','水','木','金','土'], - weekHeader: '週', - dateFormat: 'yy/mm/dd', - firstDay: 0, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - $.datepicker.setDefaults($.datepicker.regional['ja']); -}); -/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['ka'] = { - closeText: 'დახურვა', - prevText: '< წინა', - nextText: 'შემდეგი >', - currentText: 'დღეს', - monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], - monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], - dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], - dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], - dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], - weekHeader: 'კვირა', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ka']); -}); - -/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['kk'] = { - closeText: 'Жабу', - prevText: '<Алдыңғы', - nextText: 'Келесі>', - currentText: 'Бүгін', - monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', - 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], - monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', - 'Шіл','Там','Қыр','Қаз','Қар','Жел'], - dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], - dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], - dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], - weekHeader: 'Не', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['kk']); -}); - -/* Khmer initialisation for the jQuery calendar extension. */ -/* Written by Chandara Om (chandara.teacher@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['km'] = { - closeText: 'ធ្វើ​រួច', - prevText: 'មុន', - nextText: 'បន្ទាប់', - currentText: 'ថ្ងៃ​នេះ', - monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', - 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], - monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', - 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], - dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], - dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], - dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], - weekHeader: 'សប្ដាហ៍', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['km']); -}); - -/* Korean initialisation for the jQuery calendar extension. */ -/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ -jQuery(function($){ - $.datepicker.regional['ko'] = { - closeText: '닫기', - prevText: '이전달', - nextText: '다음달', - currentText: '오늘', - monthNames: ['1월','2월','3월','4월','5월','6월', - '7월','8월','9월','10월','11월','12월'], - monthNamesShort: ['1월','2월','3월','4월','5월','6월', - '7월','8월','9월','10월','11월','12월'], - dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], - dayNamesShort: ['일','월','화','수','목','금','토'], - dayNamesMin: ['일','월','화','수','목','금','토'], - weekHeader: 'Wk', - dateFormat: 'yy-mm-dd', - firstDay: 0, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '년'}; - $.datepicker.setDefaults($.datepicker.regional['ko']); -}); -/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ -/* Written by Michel Weimerskirch */ -jQuery(function($){ - $.datepicker.regional['lb'] = { - closeText: 'Fäerdeg', - prevText: 'Zréck', - nextText: 'Weider', - currentText: 'Haut', - monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', - 'Juli','August','September','Oktober','November','Dezember'], - monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', - 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], - dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], - dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], - dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], - weekHeader: 'W', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['lb']); -}); - -/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* @author Arturas Paleicikas */ -jQuery(function($){ - $.datepicker.regional['lt'] = { - closeText: 'Uždaryti', - prevText: '<Atgal', - nextText: 'Pirmyn>', - currentText: 'Šiandien', - monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis', - 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'], - monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir', - 'Lie','Rugp','Rugs','Spa','Lap','Gru'], - dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'], - dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'], - dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'], - weekHeader: 'Wk', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['lt']); -}); -/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* @author Arturas Paleicikas */ -jQuery(function($){ - $.datepicker.regional['lv'] = { - closeText: 'Aizvērt', - prevText: 'Iepr', - nextText: 'Nāka', - currentText: 'Šodien', - monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', - 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn', - 'Jūl','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], - dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], - dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], - weekHeader: 'Nav', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['lv']); -}); -/* Macedonian i18n for the jQuery UI date picker plugin. */ -/* Written by Stojce Slavkovski. */ -jQuery(function($){ - $.datepicker.regional['mk'] = { - closeText: 'Затвори', - prevText: '<', - nextText: '>', - currentText: 'Денес', - monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', - 'Јули','Август','Септември','Октомври','Ноември','Декември'], - monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', - 'Јул','Авг','Сеп','Окт','Ное','Дек'], - dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], - dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], - dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], - weekHeader: 'Сед', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['mk']); -}); - -/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Saji Nediyanchath (saji89@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['ml'] = { - closeText: 'ശരി', - prevText: 'മുന്നത്തെ', - nextText: 'അടുത്തത് ', - currentText: 'ഇന്ന്', - monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍', - 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്‍','ഒക്ടോബര്‍','നവംബര്‍','ഡിസംബര്‍'], - monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്‍', 'ഏപ്രി', 'മേയ്', 'ജൂണ്‍', - 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'], - dayNames: ['ഞായര്‍', 'തിങ്കള്‍', 'ചൊവ്വ', 'ബുധന്‍', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], - dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], - dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'], - weekHeader: 'ആ', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ml']); -}); - -/* Malaysian initialisation for the jQuery UI date picker plugin. */ -/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ -jQuery(function($){ - $.datepicker.regional['ms'] = { - closeText: 'Tutup', - prevText: '<Sebelum', - nextText: 'Selepas>', - currentText: 'hari ini', - monthNames: ['Januari','Februari','Mac','April','Mei','Jun', - 'Julai','Ogos','September','Oktober','November','Disember'], - monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun', - 'Jul','Ogo','Sep','Okt','Nov','Dis'], - dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'], - dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'], - dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'], - weekHeader: 'Mg', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ms']); -}); -/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ -/* David De Sloovere @DavidDeSloovere */ -jQuery(function($){ - $.datepicker.regional['nl-BE'] = { - closeText: 'Sluiten', - prevText: '←', - nextText: '→', - currentText: 'Vandaag', - monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', - 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], - monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', - 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], - dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], - dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], - dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['nl-BE']); -}); - -/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Mathias Bynens */ -jQuery(function($){ - $.datepicker.regional.nl = { - closeText: 'Sluiten', - prevText: '←', - nextText: '→', - currentText: 'Vandaag', - monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', - 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], - monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', - 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], - dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], - dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], - dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], - weekHeader: 'Wk', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional.nl); -}); -/* Norwegian initialisation for the jQuery UI date picker plugin. */ -/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ - -jQuery(function($){ - $.datepicker.regional['no'] = { - closeText: 'Lukk', - prevText: '«Forrige', - nextText: 'Neste»', - currentText: 'I dag', - monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], - monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], - dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], - dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], - dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], - weekHeader: 'Uke', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: '' - }; - $.datepicker.setDefaults($.datepicker.regional['no']); -}); - -/* Polish initialisation for the jQuery UI date picker plugin. */ -/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['pl'] = { - closeText: 'Zamknij', - prevText: '<Poprzedni', - nextText: 'Następny>', - currentText: 'Dziś', - monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', - 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], - monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze', - 'Lip','Sie','Wrz','Pa','Lis','Gru'], - dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'], - dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], - dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], - weekHeader: 'Tydz', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['pl']); -}); - -/* Brazilian initialisation for the jQuery UI date picker plugin. */ -/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['pt-BR'] = { - closeText: 'Fechar', - prevText: '<Anterior', - nextText: 'Próximo>', - currentText: 'Hoje', - monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', - 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], - monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', - 'Jul','Ago','Set','Out','Nov','Dez'], - dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], - dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['pt-BR']); -}); -/* Portuguese initialisation for the jQuery UI date picker plugin. */ -jQuery(function($){ - $.datepicker.regional['pt'] = { - closeText: 'Fechar', - prevText: '<Anterior', - nextText: 'Seguinte', - currentText: 'Hoje', - monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', - 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], - monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', - 'Jul','Ago','Set','Out','Nov','Dez'], - dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], - dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - weekHeader: 'Sem', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['pt']); -}); -/* Romansh initialisation for the jQuery UI date picker plugin. */ -/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ -jQuery(function($){ - $.datepicker.regional['rm'] = { - closeText: 'Serrar', - prevText: '<Suandant', - nextText: 'Precedent>', - currentText: 'Actual', - monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], - monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], - dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], - dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], - dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], - weekHeader: 'emna', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['rm']); -}); - -/* Romanian initialisation for the jQuery UI date picker plugin. - * - * Written by Edmond L. (ll_edmond@walla.com) - * and Ionut G. Stan (ionut.g.stan@gmail.com) - */ -jQuery(function($){ - $.datepicker.regional['ro'] = { - closeText: 'Închide', - prevText: '« Luna precedentă', - nextText: 'Luna următoare »', - currentText: 'Azi', - monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie', - 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'], - monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', - 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], - dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'], - dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'], - weekHeader: 'Săpt', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ro']); -}); - -/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Andrew Stromnov (stromnov@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['ru'] = { - closeText: 'Закрыть', - prevText: '<Пред', - nextText: 'След>', - currentText: 'Сегодня', - monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', - 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], - monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', - 'Июл','Авг','Сен','Окт','Ноя','Дек'], - dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], - dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], - dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], - weekHeader: 'Нед', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ru']); -}); -/* Slovak initialisation for the jQuery UI date picker plugin. */ -/* Written by Vojtech Rinik (vojto@hmm.sk). */ -jQuery(function($){ - $.datepicker.regional['sk'] = { - closeText: 'Zavrieť', - prevText: '<Predchádzajúci', - nextText: 'Nasledujúci>', - currentText: 'Dnes', - monthNames: ['Január','Február','Marec','Apríl','Máj','Jún', - 'Júl','August','September','Október','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', - 'Júl','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'], - dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], - dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], - weekHeader: 'Ty', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['sk']); -}); - -/* Slovenian initialisation for the jQuery UI date picker plugin. */ -/* Written by Jaka Jancar (jaka@kubje.org). */ -/* c = č, s = š z = ž C = Č S = Š Z = Ž */ -jQuery(function($){ - $.datepicker.regional['sl'] = { - closeText: 'Zapri', - prevText: '<Prejšnji', - nextText: 'Naslednji>', - currentText: 'Trenutni', - monthNames: ['Januar','Februar','Marec','April','Maj','Junij', - 'Julij','Avgust','September','Oktober','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Avg','Sep','Okt','Nov','Dec'], - dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'], - dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'], - dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'], - weekHeader: 'Teden', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['sl']); -}); - -/* Albanian initialisation for the jQuery UI date picker plugin. */ -/* Written by Flakron Bytyqi (flakron@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['sq'] = { - closeText: 'mbylle', - prevText: '<mbrapa', - nextText: 'Përpara>', - currentText: 'sot', - monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor', - 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'], - monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer', - 'Kor','Gus','Sht','Tet','Nën','Dhj'], - dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'], - dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'], - dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'], - weekHeader: 'Ja', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['sq']); -}); - -/* Serbian i18n for the jQuery UI date picker plugin. */ -/* Written by Dejan Dimić. */ -jQuery(function($){ - $.datepicker.regional['sr-SR'] = { - closeText: 'Zatvori', - prevText: '<', - nextText: '>', - currentText: 'Danas', - monthNames: ['Januar','Februar','Mart','April','Maj','Jun', - 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Avg','Sep','Okt','Nov','Dec'], - dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'], - dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'], - dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], - weekHeader: 'Sed', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['sr-SR']); -}); - -/* Serbian i18n for the jQuery UI date picker plugin. */ -/* Written by Dejan Dimić. */ -jQuery(function($){ - $.datepicker.regional['sr'] = { - closeText: 'Затвори', - prevText: '<', - nextText: '>', - currentText: 'Данас', - monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун', - 'Јул','Август','Септембар','Октобар','Новембар','Децембар'], - monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', - 'Јул','Авг','Сеп','Окт','Нов','Дец'], - dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'], - dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'], - dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'], - weekHeader: 'Сед', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['sr']); -}); - -/* Swedish initialisation for the jQuery UI date picker plugin. */ -/* Written by Anders Ekdahl ( anders@nomadiz.se). */ -jQuery(function($){ - $.datepicker.regional['sv'] = { - closeText: 'Stäng', - prevText: '«Förra', - nextText: 'Nästa»', - currentText: 'Idag', - monthNames: ['Januari','Februari','Mars','April','Maj','Juni', - 'Juli','Augusti','September','Oktober','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dec'], - dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'], - dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'], - dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], - weekHeader: 'Ve', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['sv']); -}); - -/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by S A Sureshkumar (saskumar@live.com). */ -jQuery(function($){ - $.datepicker.regional['ta'] = { - closeText: 'மூடு', - prevText: 'முன்னையது', - nextText: 'அடுத்தது', - currentText: 'இன்று', - monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி', - 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'], - monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி', - 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'], - dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'], - dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'], - dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'], - weekHeader: 'Не', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ta']); -}); - -/* Thai initialisation for the jQuery UI date picker plugin. */ -/* Written by pipo (pipo@sixhead.com). */ -jQuery(function($){ - $.datepicker.regional['th'] = { - closeText: 'ปิด', - prevText: '« ย้อน', - nextText: 'ถัดไป »', - currentText: 'วันนี้', - monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', - 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], - monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', - 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], - dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], - dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], - dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['th']); -}); -/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['tj'] = { - closeText: 'Идома', - prevText: '<Қафо', - nextText: 'Пеш>', - currentText: 'Имрӯз', - monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн', - 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'], - monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', - 'Июл','Авг','Сен','Окт','Ноя','Дек'], - dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'], - dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'], - dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'], - weekHeader: 'Хф', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['tj']); -}); -/* Turkish initialisation for the jQuery UI date picker plugin. */ -/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ -jQuery(function($){ - $.datepicker.regional['tr'] = { - closeText: 'kapat', - prevText: '<geri', - nextText: 'ileri>', - currentText: 'bugün', - monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', - 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'], - monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz', - 'Tem','Ağu','Eyl','Eki','Kas','Ara'], - dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'], - dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], - dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], - weekHeader: 'Hf', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['tr']); -}); -/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ -/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['uk'] = { - closeText: 'Закрити', - prevText: '<', - nextText: '>', - currentText: 'Сьогодні', - monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень', - 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'], - monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер', - 'Лип','Сер','Вер','Жов','Лис','Гру'], - dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'], - dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'], - dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'], - weekHeader: 'Тиж', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['uk']); -}); -/* Vietnamese initialisation for the jQuery UI date picker plugin. */ -/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ -jQuery(function($){ - $.datepicker.regional['vi'] = { - closeText: 'Đóng', - prevText: '<Trước', - nextText: 'Tiếp>', - currentText: 'Hôm nay', - monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', - 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'], - monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', - 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'], - dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'], - dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], - dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], - weekHeader: 'Tu', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['vi']); -}); - -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by Cloudream (cloudream@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['zh'] = { - closeText: '关闭', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一','二','三','四','五','六', - '七','八','九','十','十一','十二'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - $.datepicker.setDefaults($.datepicker.regional['zh-CN']); -}); - -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by Cloudream (cloudream@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['zh-CN'] = { - closeText: '关闭', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一','二','三','四','五','六', - '七','八','九','十','十一','十二'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - $.datepicker.setDefaults($.datepicker.regional['zh-CN']); -}); - -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by SCCY (samuelcychan@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['zh-HK'] = { - closeText: '關閉', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一','二','三','四','五','六', - '七','八','九','十','十一','十二'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'dd-mm-yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - $.datepicker.setDefaults($.datepicker.regional['zh-HK']); -}); - -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by Ressol (ressol@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['zh-TW'] = { - closeText: '關閉', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一','二','三','四','五','六', - '七','八','九','十','十一','十二'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'yy/mm/dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - $.datepicker.setDefaults($.datepicker.regional['zh-TW']); -}); diff --git a/frontend/express/public/javascripts/dom/jqueryui/jquery-ui.js b/frontend/express/public/javascripts/dom/jqueryui/jquery-ui.js deleted file mode 100644 index 69e60c47ed6..00000000000 --- a/frontend/express/public/javascripts/dom/jqueryui/jquery-ui.js +++ /dev/null @@ -1,19062 +0,0 @@ -/*! jQuery UI - v1.13.2 - 2022-12-10 -* http://jqueryui.com -* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } -} )( function( $ ) { -"use strict"; - -$.ui = $.ui || {}; - -var version = $.ui.version = "1.13.2"; - - -/*! - * jQuery UI Widget 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Widget -//>>group: Core -//>>description: Provides a factory for creating stateful widgets with a common API. -//>>docs: http://api.jqueryui.com/jQuery.widget/ -//>>demos: http://jqueryui.com/widget/ - - -var widgetUuid = 0; -var widgetHasOwnProperty = Array.prototype.hasOwnProperty; -var widgetSlice = Array.prototype.slice; - -$.cleanData = ( function( orig ) { - return function( elems ) { - var events, elem, i; - for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { - - // Only trigger remove when necessary to save time - events = $._data( elem, "events" ); - if ( events && events.remove ) { - $( elem ).triggerHandler( "remove" ); - } - } - orig( elems ); - }; -} )( $.cleanData ); - -$.widget = function( name, base, prototype ) { - var existingConstructor, constructor, basePrototype; - - // ProxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - var proxiedPrototype = {}; - - var namespace = name.split( "." )[ 0 ]; - name = name.split( "." )[ 1 ]; - var fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - if ( Array.isArray( prototype ) ) { - prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); - } - - // Create selector for plugin - $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - - // Allow instantiation without "new" keyword - if ( !this || !this._createWidget ) { - return new constructor( options, element ); - } - - // Allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - - // Extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - - // Copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - - // Track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - } ); - - basePrototype = new base(); - - // We need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( typeof value !== "function" ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = ( function() { - function _super() { - return base.prototype[ prop ].apply( this, arguments ); - } - - function _superApply( args ) { - return base.prototype[ prop ].apply( this, args ); - } - - return function() { - var __super = this._super; - var __superApply = this._superApply; - var returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - } )(); - } ); - constructor.prototype = $.widget.extend( basePrototype, { - - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - } ); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // Redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, - child._proto ); - } ); - - // Remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); - - return constructor; -}; - -$.widget.extend = function( target ) { - var input = widgetSlice.call( arguments, 1 ); - var inputIndex = 0; - var inputLength = input.length; - var key; - var value; - - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { - - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string"; - var args = widgetSlice.call( arguments, 1 ); - var returnValue = this; - - if ( isMethodCall ) { - - // If this is an empty collection, we need to have the instance method - // return undefined instead of the jQuery instance - if ( !this.length && options === "instance" ) { - returnValue = undefined; - } else { - this.each( function() { - var methodValue; - var instance = $.data( this, fullName ); - - if ( options === "instance" ) { - returnValue = instance; - return false; - } - - if ( !instance ) { - return $.error( "cannot call methods on " + name + - " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - - if ( typeof instance[ options ] !== "function" || - options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + - " widget instance" ); - } - - methodValue = instance[ options ].apply( instance, args ); - - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - } ); - } - } else { - - // Allow multiple hashes to be passed on init - if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat( args ) ); - } - - this.each( function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - $.data( this, fullName, new object( options, this ) ); - } - } ); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
      ", - - options: { - classes: {}, - disabled: false, - - // Callbacks - create: null - }, - - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = widgetUuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - this.classesElementLookup = {}; - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - } ); - this.document = $( element.style ? - - // Element within the document - element.ownerDocument : - - // Element is window or document - element.document || element ); - this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); - } - - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this._create(); - - if ( this.options.disabled ) { - this._setOptionDisabled( this.options.disabled ); - } - - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - - _getCreateOptions: function() { - return {}; - }, - - _getCreateEventData: $.noop, - - _create: $.noop, - - _init: $.noop, - - destroy: function() { - var that = this; - - this._destroy(); - $.each( this.classesElementLookup, function( key, value ) { - that._removeClass( value, key ); - } ); - - // We can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .off( this.eventNamespace ) - .removeData( this.widgetFullName ); - this.widget() - .off( this.eventNamespace ) - .removeAttr( "aria-disabled" ); - - // Clean up events and states - this.bindings.off( this.eventNamespace ); - }, - - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key; - var parts; - var curOption; - var i; - - if ( arguments.length === 0 ) { - - // Don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - - // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - - _setOption: function( key, value ) { - if ( key === "classes" ) { - this._setOptionClasses( value ); - } - - this.options[ key ] = value; - - if ( key === "disabled" ) { - this._setOptionDisabled( value ); - } - - return this; - }, - - _setOptionClasses: function( value ) { - var classKey, elements, currentElements; - - for ( classKey in value ) { - currentElements = this.classesElementLookup[ classKey ]; - if ( value[ classKey ] === this.options.classes[ classKey ] || - !currentElements || - !currentElements.length ) { - continue; - } - - // We are doing this to create a new jQuery object because the _removeClass() call - // on the next line is going to destroy the reference to the current elements being - // tracked. We need to save a copy of this collection so that we can add the new classes - // below. - elements = $( currentElements.get() ); - this._removeClass( currentElements, classKey ); - - // We don't use _addClass() here, because that uses this.options.classes - // for generating the string of classes. We want to use the value passed in from - // _setOption(), this is the new value of the classes option which was passed to - // _setOption(). We pass this value directly to _classes(). - elements.addClass( this._classes( { - element: elements, - keys: classKey, - classes: value, - add: true - } ) ); - } - }, - - _setOptionDisabled: function( value ) { - this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); - - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this._removeClass( this.hoverable, null, "ui-state-hover" ); - this._removeClass( this.focusable, null, "ui-state-focus" ); - } - }, - - enable: function() { - return this._setOptions( { disabled: false } ); - }, - - disable: function() { - return this._setOptions( { disabled: true } ); - }, - - _classes: function( options ) { - var full = []; - var that = this; - - options = $.extend( { - element: this.element, - classes: this.options.classes || {} - }, options ); - - function bindRemoveEvent() { - var nodesToBind = []; - - options.element.each( function( _, element ) { - var isTracked = $.map( that.classesElementLookup, function( elements ) { - return elements; - } ) - .some( function( elements ) { - return elements.is( element ); - } ); - - if ( !isTracked ) { - nodesToBind.push( element ); - } - } ); - - that._on( $( nodesToBind ), { - remove: "_untrackClassesElement" - } ); - } - - function processClassString( classes, checkOption ) { - var current, i; - for ( i = 0; i < classes.length; i++ ) { - current = that.classesElementLookup[ classes[ i ] ] || $(); - if ( options.add ) { - bindRemoveEvent(); - current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); - } else { - current = $( current.not( options.element ).get() ); - } - that.classesElementLookup[ classes[ i ] ] = current; - full.push( classes[ i ] ); - if ( checkOption && options.classes[ classes[ i ] ] ) { - full.push( options.classes[ classes[ i ] ] ); - } - } - } - - if ( options.keys ) { - processClassString( options.keys.match( /\S+/g ) || [], true ); - } - if ( options.extra ) { - processClassString( options.extra.match( /\S+/g ) || [] ); - } - - return full.join( " " ); - }, - - _untrackClassesElement: function( event ) { - var that = this; - $.each( that.classesElementLookup, function( key, value ) { - if ( $.inArray( event.target, value ) !== -1 ) { - that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); - } - } ); - - this._off( $( event.target ) ); - }, - - _removeClass: function( element, keys, extra ) { - return this._toggleClass( element, keys, extra, false ); - }, - - _addClass: function( element, keys, extra ) { - return this._toggleClass( element, keys, extra, true ); - }, - - _toggleClass: function( element, keys, extra, add ) { - add = ( typeof add === "boolean" ) ? add : extra; - var shift = ( typeof element === "string" || element === null ), - options = { - extra: shift ? keys : extra, - keys: shift ? element : keys, - element: shift ? this.element : element, - add: add - }; - options.element.toggleClass( this._classes( options ), add ); - return this; - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement; - var instance = this; - - // No suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // No element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - - // Allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // Copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^([\w:-]*)\s*(.*)$/ ); - var eventName = match[ 1 ] + instance.eventNamespace; - var selector = match[ 2 ]; - - if ( selector ) { - delegateElement.on( eventName, selector, handlerProxy ); - } else { - element.on( eventName, handlerProxy ); - } - } ); - }, - - _off: function( element, eventName ) { - eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + - this.eventNamespace; - element.off( eventName ); - - // Clear the stack to avoid memory leaks (#10056) - this.bindings = $( this.bindings.not( element ).get() ); - this.focusable = $( this.focusable.not( element ).get() ); - this.hoverable = $( this.hoverable.not( element ).get() ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); - }, - mouseleave: function( event ) { - this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); - } - } ); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); - }, - focusout: function( event ) { - this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); - } - } ); - }, - - _trigger: function( type, event, data ) { - var prop, orig; - var callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - - // The original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // Copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( typeof callback === "function" && - callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - - var hasOptions; - var effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } else if ( options === true ) { - options = {}; - } - - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - - if ( options.delay ) { - element.delay( options.delay ); - } - - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue( function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - } ); - } - }; -} ); - -var widget = $.widget; - - -/*! - * jQuery UI Position 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/position/ - */ - -//>>label: Position -//>>group: Core -//>>description: Positions elements relative to other elements. -//>>docs: http://api.jqueryui.com/position/ -//>>demos: http://jqueryui.com/position/ - - -( function() { -var cachedScrollbarWidth, - max = Math.max, - abs = Math.abs, - rhorizontal = /left|center|right/, - rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+(\.[\d]+)?%?/, - rposition = /^\w+/, - rpercent = /%$/, - _position = $.fn.position; - -function getOffsets( offsets, width, height ) { - return [ - parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) - ]; -} - -function parseCss( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; -} - -function isWindow( obj ) { - return obj != null && obj === obj.window; -} - -function getDimensions( elem ) { - var raw = elem[ 0 ]; - if ( raw.nodeType === 9 ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: 0, left: 0 } - }; - } - if ( isWindow( raw ) ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: elem.scrollTop(), left: elem.scrollLeft() } - }; - } - if ( raw.preventDefault ) { - return { - width: 0, - height: 0, - offset: { top: raw.pageY, left: raw.pageX } - }; - } - return { - width: elem.outerWidth(), - height: elem.outerHeight(), - offset: elem.offset() - }; -} - -$.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { - return cachedScrollbarWidth; - } - var w1, w2, - div = $( "
      " + - "
      " ), - innerDiv = div.children()[ 0 ]; - - $( "body" ).append( div ); - w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); - - w2 = innerDiv.offsetWidth; - - if ( w1 === w2 ) { - w2 = div[ 0 ].clientWidth; - } - - div.remove(); - - return ( cachedScrollbarWidth = w1 - w2 ); - }, - getScrollInfo: function( within ) { - var overflowX = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-x" ), - overflowY = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-y" ), - hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), - hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); - return { - width: hasOverflowY ? $.position.scrollbarWidth() : 0, - height: hasOverflowX ? $.position.scrollbarWidth() : 0 - }; - }, - getWithinInfo: function( element ) { - var withinElement = $( element || window ), - isElemWindow = isWindow( withinElement[ 0 ] ), - isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, - hasOffset = !isElemWindow && !isDocument; - return { - element: withinElement, - isWindow: isElemWindow, - isDocument: isDocument, - offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, - scrollLeft: withinElement.scrollLeft(), - scrollTop: withinElement.scrollTop(), - width: withinElement.outerWidth(), - height: withinElement.outerHeight() - }; - } -}; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // Make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, - - // Make sure string options are treated as CSS selectors - target = typeof options.of === "string" ? - $( document ).find( options.of ) : - $( options.of ), - - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - collision = ( options.collision || "flip" ).split( " " ), - offsets = {}; - - dimensions = getDimensions( target ); - if ( target[ 0 ].preventDefault ) { - - // Force left top to allow flipping - options.at = "left top"; - } - targetWidth = dimensions.width; - targetHeight = dimensions.height; - targetOffset = dimensions.offset; - - // Clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); - - // Force my and at to have valid horizontal and vertical positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[ this ] || "" ).split( " " ), - horizontalOffset, - verticalOffset; - - if ( pos.length === 1 ) { - pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ "center" ] ) : - rvertical.test( pos[ 0 ] ) ? - [ "center" ].concat( pos ) : - [ "center", "center" ]; - } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - - // Calculate offsets - horizontalOffset = roffset.exec( pos[ 0 ] ); - verticalOffset = roffset.exec( pos[ 1 ] ); - offsets[ this ] = [ - horizontalOffset ? horizontalOffset[ 0 ] : 0, - verticalOffset ? verticalOffset[ 0 ] : 0 - ]; - - // Reduce to just the positions without the offsets - options[ this ] = [ - rposition.exec( pos[ 0 ] )[ 0 ], - rposition.exec( pos[ 1 ] )[ 0 ] - ]; - } ); - - // Normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - if ( options.at[ 0 ] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[ 1 ] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { - basePosition.top += targetHeight / 2; - } - - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; - - return this.each( function() { - var collisionPosition, using, - elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseCss( this, "marginLeft" ), - marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + - scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + - scrollInfo.height, - position = $.extend( {}, basePosition ), - myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); - - if ( options.my[ 0 ] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[ 0 ] === "center" ) { - position.left -= elemWidth / 2; - } - - if ( options.my[ 1 ] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { - position.top -= elemHeight / 2; - } - - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; - - collisionPosition = { - marginLeft: marginLeft, - marginTop: marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], - my: options.my, - at: options.at, - within: within, - elem: elem - } ); - } - } ); - - if ( options.using ) { - - // Adds feedback as second argument to using callback, if present - using = function( props ) { - var left = targetOffset.left - position.left, - right = left + targetWidth - elemWidth, - top = targetOffset.top - position.top, - bottom = top + targetHeight - elemHeight, - feedback = { - target: { - element: target, - left: targetOffset.left, - top: targetOffset.top, - width: targetWidth, - height: targetHeight - }, - element: { - element: elem, - left: position.left, - top: position.top, - width: elemWidth, - height: elemHeight - }, - horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { - feedback.horizontal = "center"; - } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { - feedback.vertical = "middle"; - } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { - feedback.important = "horizontal"; - } else { - feedback.important = "vertical"; - } - options.using.call( this, props, feedback ); - }; - } - - elem.offset( $.extend( position, { using: using } ) ); - } ); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, - outerWidth = within.width, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = withinOffset - collisionPosLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, - newOverRight; - - // Element is wider than within - if ( data.collisionWidth > outerWidth ) { - - // Element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - - withinOffset; - position.left += overLeft - newOverRight; - - // Element is initially over right side of within - } else if ( overRight > 0 && overLeft <= 0 ) { - position.left = withinOffset; - - // Element is initially over both left and right sides of within - } else { - if ( overLeft > overRight ) { - position.left = withinOffset + outerWidth - data.collisionWidth; - } else { - position.left = withinOffset; - } - } - - // Too far left -> align with left edge - } else if ( overLeft > 0 ) { - position.left += overLeft; - - // Too far right -> align with right edge - } else if ( overRight > 0 ) { - position.left -= overRight; - - // Adjust based on position and margin - } else { - position.left = max( position.left - collisionPosLeft, position.left ); - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollTop : within.offset.top, - outerHeight = data.within.height, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = withinOffset - collisionPosTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, - newOverBottom; - - // Element is taller than within - if ( data.collisionHeight > outerHeight ) { - - // Element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - - withinOffset; - position.top += overTop - newOverBottom; - - // Element is initially over bottom of within - } else if ( overBottom > 0 && overTop <= 0 ) { - position.top = withinOffset; - - // Element is initially over both top and bottom of within - } else { - if ( overTop > overBottom ) { - position.top = withinOffset + outerHeight - data.collisionHeight; - } else { - position.top = withinOffset; - } - } - - // Too far up -> align with top - } else if ( overTop > 0 ) { - position.top += overTop; - - // Too far down -> align with bottom edge - } else if ( overBottom > 0 ) { - position.top -= overBottom; - - // Adjust based on position and margin - } else { - position.top = max( position.top - collisionPosTop, position.top ); - } - } - }, - flip: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.offset.left + within.scrollLeft, - outerWidth = within.width, - offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = collisionPosLeft - offsetLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - data.at[ 0 ] === "right" ? - -data.targetWidth : - 0, - offset = -2 * data.offset[ 0 ], - newOverRight, - newOverLeft; - - if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { - position.left += myOffset + atOffset + offset; - } - } else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + - atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { - position.left += myOffset + atOffset + offset; - } - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.offset.top + within.scrollTop, - outerHeight = within.height, - offsetTop = within.isWindow ? within.scrollTop : within.offset.top, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = collisionPosTop - offsetTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", - myOffset = top ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - data.at[ 1 ] === "bottom" ? - -data.targetHeight : - 0, - offset = -2 * data.offset[ 1 ], - newOverTop, - newOverBottom; - if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - - outerHeight - withinOffset; - if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { - position.top += myOffset + atOffset + offset; - } - } else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + - offset - offsetTop; - if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { - position.top += myOffset + atOffset + offset; - } - } - } - }, - flipfit: { - left: function() { - $.ui.position.flip.left.apply( this, arguments ); - $.ui.position.fit.left.apply( this, arguments ); - }, - top: function() { - $.ui.position.flip.top.apply( this, arguments ); - $.ui.position.fit.top.apply( this, arguments ); - } - } -}; - -} )(); - -var position = $.ui.position; - - -/*! - * jQuery UI :data 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: :data Selector -//>>group: Core -//>>description: Selects elements which have data stored under the specified key. -//>>docs: http://api.jqueryui.com/data-selector/ - - -var data = $.extend( $.expr.pseudos, { - data: $.expr.createPseudo ? - $.expr.createPseudo( function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - } ) : - - // Support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - } -} ); - -/*! - * jQuery UI Disable Selection 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: disableSelection -//>>group: Core -//>>description: Disable selection of text content within the set of matched elements. -//>>docs: http://api.jqueryui.com/disableSelection/ - -// This file is deprecated - -var disableSelection = $.fn.extend( { - disableSelection: ( function() { - var eventType = "onselectstart" in document.createElement( "div" ) ? - "selectstart" : - "mousedown"; - - return function() { - return this.on( eventType + ".ui-disableSelection", function( event ) { - event.preventDefault(); - } ); - }; - } )(), - - enableSelection: function() { - return this.off( ".ui-disableSelection" ); - } -} ); - - -/*! - * jQuery UI Focusable 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: :focusable Selector -//>>group: Core -//>>description: Selects elements which can be focused. -//>>docs: http://api.jqueryui.com/focusable-selector/ - - -// Selectors -$.ui.focusable = function( element, hasTabindex ) { - var map, mapName, img, focusableIfVisible, fieldset, - nodeName = element.nodeName.toLowerCase(); - - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap='#" + mapName + "']" ); - return img.length > 0 && img.is( ":visible" ); - } - - if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { - focusableIfVisible = !element.disabled; - - if ( focusableIfVisible ) { - - // Form controls within a disabled fieldset are disabled. - // However, controls within the fieldset's legend do not get disabled. - // Since controls generally aren't placed inside legends, we skip - // this portion of the check. - fieldset = $( element ).closest( "fieldset" )[ 0 ]; - if ( fieldset ) { - focusableIfVisible = !fieldset.disabled; - } - } - } else if ( "a" === nodeName ) { - focusableIfVisible = element.href || hasTabindex; - } else { - focusableIfVisible = hasTabindex; - } - - return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); -}; - -// Support: IE 8 only -// IE 8 doesn't resolve inherit to visible/hidden for computed values -function visible( element ) { - var visibility = element.css( "visibility" ); - while ( visibility === "inherit" ) { - element = element.parent(); - visibility = element.css( "visibility" ); - } - return visibility === "visible"; -} - -$.extend( $.expr.pseudos, { - focusable: function( element ) { - return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); - } -} ); - -var focusable = $.ui.focusable; - - - -// Support: IE8 Only -// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop -// with a string, so we need to find the proper form. -var form = $.fn._form = function() { - return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); -}; - - -/*! - * jQuery UI Form Reset Mixin 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Form Reset Mixin -//>>group: Core -//>>description: Refresh input widgets when their form is reset -//>>docs: http://api.jqueryui.com/form-reset-mixin/ - - -var formResetMixin = $.ui.formResetMixin = { - _formResetHandler: function() { - var form = $( this ); - - // Wait for the form reset to actually happen before refreshing - setTimeout( function() { - var instances = form.data( "ui-form-reset-instances" ); - $.each( instances, function() { - this.refresh(); - } ); - } ); - }, - - _bindFormResetHandler: function() { - this.form = this.element._form(); - if ( !this.form.length ) { - return; - } - - var instances = this.form.data( "ui-form-reset-instances" ) || []; - if ( !instances.length ) { - - // We don't use _on() here because we use a single event handler per form - this.form.on( "reset.ui-form-reset", this._formResetHandler ); - } - instances.push( this ); - this.form.data( "ui-form-reset-instances", instances ); - }, - - _unbindFormResetHandler: function() { - if ( !this.form.length ) { - return; - } - - var instances = this.form.data( "ui-form-reset-instances" ); - instances.splice( $.inArray( this, instances ), 1 ); - if ( instances.length ) { - this.form.data( "ui-form-reset-instances", instances ); - } else { - this.form - .removeData( "ui-form-reset-instances" ) - .off( "reset.ui-form-reset" ); - } - } -}; - - -/*! - * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - */ - -//>>label: jQuery 1.8+ Support -//>>group: Core -//>>description: Support version 1.8.x and newer of jQuery core - - -// Support: jQuery 1.9.x or older -// $.expr[ ":" ] is deprecated. -if ( !$.expr.pseudos ) { - $.expr.pseudos = $.expr[ ":" ]; -} - -// Support: jQuery 1.11.x or older -// $.unique has been renamed to $.uniqueSort -if ( !$.uniqueSort ) { - $.uniqueSort = $.unique; -} - -// Support: jQuery 2.2.x or older. -// This method has been defined in jQuery 3.0.0. -// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js -if ( !$.escapeSelector ) { - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; - - var fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }; - - $.escapeSelector = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); - }; -} - -// Support: jQuery 3.4.x or older -// These methods have been defined in jQuery 3.5.0. -if ( !$.fn.even || !$.fn.odd ) { - $.fn.extend( { - even: function() { - return this.filter( function( i ) { - return i % 2 === 0; - } ); - }, - odd: function() { - return this.filter( function( i ) { - return i % 2 === 1; - } ); - } - } ); -} - -; -/*! - * jQuery UI Keycode 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Keycode -//>>group: Core -//>>description: Provide keycodes as keynames -//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ - - -var keycode = $.ui.keyCode = { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 -}; - - -/*! - * jQuery UI Labels 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: labels -//>>group: Core -//>>description: Find all the labels associated with a given input -//>>docs: http://api.jqueryui.com/labels/ - - -var labels = $.fn.labels = function() { - var ancestor, selector, id, labels, ancestors; - - if ( !this.length ) { - return this.pushStack( [] ); - } - - // Check control.labels first - if ( this[ 0 ].labels && this[ 0 ].labels.length ) { - return this.pushStack( this[ 0 ].labels ); - } - - // Support: IE <= 11, FF <= 37, Android <= 2.3 only - // Above browsers do not support control.labels. Everything below is to support them - // as well as document fragments. control.labels does not work on document fragments - labels = this.eq( 0 ).parents( "label" ); - - // Look for the label based on the id - id = this.attr( "id" ); - if ( id ) { - - // We don't search against the document in case the element - // is disconnected from the DOM - ancestor = this.eq( 0 ).parents().last(); - - // Get a full set of top level ancestors - ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); - - // Create a selector for the label based on the id - selector = "label[for='" + $.escapeSelector( id ) + "']"; - - labels = labels.add( ancestors.find( selector ).addBack( selector ) ); - - } - - // Return whatever we have found for labels - return this.pushStack( labels ); -}; - - -/*! - * jQuery UI Scroll Parent 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: scrollParent -//>>group: Core -//>>description: Get the closest ancestor element that is scrollable. -//>>docs: http://api.jqueryui.com/scrollParent/ - - -var scrollParent = $.fn.scrollParent = function( includeHidden ) { - var position = this.css( "position" ), - excludeStaticParent = position === "absolute", - overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, - scrollParent = this.parents().filter( function() { - var parent = $( this ); - if ( excludeStaticParent && parent.css( "position" ) === "static" ) { - return false; - } - return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + - parent.css( "overflow-x" ) ); - } ).eq( 0 ); - - return position === "fixed" || !scrollParent.length ? - $( this[ 0 ].ownerDocument || document ) : - scrollParent; -}; - - -/*! - * jQuery UI Tabbable 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: :tabbable Selector -//>>group: Core -//>>description: Selects elements which can be tabbed to. -//>>docs: http://api.jqueryui.com/tabbable-selector/ - - -var tabbable = $.extend( $.expr.pseudos, { - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - hasTabindex = tabIndex != null; - return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); - } -} ); - - -/*! - * jQuery UI Unique ID 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: uniqueId -//>>group: Core -//>>description: Functions to generate and remove uniqueId's -//>>docs: http://api.jqueryui.com/uniqueId/ - - -var uniqueId = $.fn.extend( { - uniqueId: ( function() { - var uuid = 0; - - return function() { - return this.each( function() { - if ( !this.id ) { - this.id = "ui-id-" + ( ++uuid ); - } - } ); - }; - } )(), - - removeUniqueId: function() { - return this.each( function() { - if ( /^ui-id-\d+$/.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - } ); - } -} ); - - - -// This file is deprecated -var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - -/*! - * jQuery UI Mouse 1.13.2 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Mouse -//>>group: Widgets -//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. -//>>docs: http://api.jqueryui.com/mouse/ - - -var mouseHandled = false; -$( document ).on( "mouseup", function() { - mouseHandled = false; -} ); - -var widgetsMouse = $.widget( "ui.mouse", { - version: "1.13.2", - options: { - cancel: "input, textarea, button, select, option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .on( "mousedown." + this.widgetName, function( event ) { - return that._mouseDown( event ); - } ) - .on( "click." + this.widgetName, function( event ) { - if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { - $.removeData( event.target, that.widgetName + ".preventClickEvent" ); - event.stopImmediatePropagation(); - return false; - } - } ); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.off( "." + this.widgetName ); - if ( this._mouseMoveDelegate ) { - this.document - .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); - } - }, - - _mouseDown: function( event ) { - - // don't let more than one widget handle mouseStart - if ( mouseHandled ) { - return; - } - - this._mouseMoved = false; - - // We may have missed mouseup (out of window) - if ( this._mouseStarted ) { - this._mouseUp( event ); - } - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = ( event.which === 1 ), - - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? - $( event.target ).closest( this.options.cancel ).length : false ); - if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if ( !this.mouseDelayMet ) { - this._mouseDelayTimer = setTimeout( function() { - that.mouseDelayMet = true; - }, this.options.delay ); - } - - if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { - this._mouseStarted = ( this._mouseStart( event ) !== false ); - if ( !this._mouseStarted ) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { - $.removeData( event.target, this.widgetName + ".preventClickEvent" ); - } - - // These delegates are required to keep context - this._mouseMoveDelegate = function( event ) { - return that._mouseMove( event ); - }; - this._mouseUpDelegate = function( event ) { - return that._mouseUp( event ); - }; - - this.document - .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function( event ) { - - // Only check for mouseups outside the document if you've moved inside the document - // at least once. This prevents the firing of mouseup in the case of IE<9, which will - // fire a mousemove event if content is placed under the cursor. See #7778 - // Support: IE <9 - if ( this._mouseMoved ) { - - // IE mouseup check - mouseup happened when mouse was out of window - if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && - !event.button ) { - return this._mouseUp( event ); - - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { - - // Support: Safari <=8 - 9 - // Safari sets which to 0 if you press any of the following keys - // during a drag (#14461) - if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || - event.originalEvent.metaKey || event.originalEvent.shiftKey ) { - this.ignoreMissingWhich = true; - } else if ( !this.ignoreMissingWhich ) { - return this._mouseUp( event ); - } - } - } - - if ( event.which || event.button ) { - this._mouseMoved = true; - } - - if ( this._mouseStarted ) { - this._mouseDrag( event ); - return event.preventDefault(); - } - - if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { - this._mouseStarted = - ( this._mouseStart( this._mouseDownEvent, event ) !== false ); - if ( this._mouseStarted ) { - this._mouseDrag( event ); - } else { - this._mouseUp( event ); - } - } - - return !this._mouseStarted; - }, - - _mouseUp: function( event ) { - this.document - .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - if ( this._mouseStarted ) { - this._mouseStarted = false; - - if ( event.target === this._mouseDownEvent.target ) { - $.data( event.target, this.widgetName + ".preventClickEvent", true ); - } - - this._mouseStop( event ); - } - - if ( this._mouseDelayTimer ) { - clearTimeout( this._mouseDelayTimer ); - delete this._mouseDelayTimer; - } - - this.ignoreMissingWhich = false; - mouseHandled = false; - event.preventDefault(); - }, - - _mouseDistanceMet: function( event ) { - return ( Math.max( - Math.abs( this._mouseDownEvent.pageX - event.pageX ), - Math.abs( this._mouseDownEvent.pageY - event.pageY ) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function( /* event */ ) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function( /* event */ ) {}, - _mouseDrag: function( /* event */ ) {}, - _mouseStop: function( /* event */ ) {}, - _mouseCapture: function( /* event */ ) { - return true; - } -} ); - - - -// $.ui.plugin is deprecated. Use $.widget() extensions instead. -var plugin = $.ui.plugin = { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args, allowDisconnected ) { - var i, - set = instance.plugins[ name ]; - - if ( !set ) { - return; - } - - if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || - instance.element[ 0 ].parentNode.nodeType === 11 ) ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } -}; - - - -var safeActiveElement = $.ui.safeActiveElement = function( document ) { - var activeElement; - - // Support: IE 9 only - // IE9 throws an "Unspecified error" accessing document.activeElement from an '),l},simpleUpload.dequeueIframe=function(e){e in simpleUpload.iframes&&($("iframe[name=simpleUpload_iframe_"+e+"]").remove(),delete simpleUpload.iframes[e],simpleUpload.iframeCount--)},simpleUpload.convertDataType=function(e,l,n){var t="auto";if("auto"==e){if("string"==typeof l&&""!=l){var a=l.toLowerCase(),o=["json","xml","html","script","text"];for(var r in o)if(o[r]==a){t=a;break}}}else t=e;if("auto"==t)return void 0===n?"":"object"==typeof n?n:String(n);if("json"==t){if(null==n)return null;if("object"==typeof n)return n;if("string"==typeof n)try{return $.parseJSON(n)}catch(e){return!1}return!1}if("xml"==t){if(null==n)return null;if("string"==typeof n)try{return $.parseXML(n)}catch(e){return!1}return!1}if("script"==t){if(void 0===n)return"";if("string"==typeof n)try{return $.globalEval(n),n}catch(e){return!1}return!1}return void 0===n?"":String(n)},simpleUpload.iframeCallback=function(e){if("object"==typeof e&&null!==e){var l=e.id;if(l in simpleUpload.iframes){var n=simpleUpload.convertDataType(simpleUpload.iframes[l].expect,e.type,e.data);!1!==n?simpleUpload.iframes[l].complete(n):simpleUpload.iframes[l].error("Upload failed")}}},simpleUpload.postMessageCallback=function(e){try{var l=e[e.message?"message":"data"];if("string"==typeof l&&""!=l&&"object"==typeof(l=$.parseJSON(l))&&null!==l&&"string"==typeof l.namespace&&"simpleUpload"==l.namespace){var n=l.id;if(n in simpleUpload.iframes&&e.origin===simpleUpload.iframes[n].origin){var t=simpleUpload.convertDataType(simpleUpload.iframes[n].expect,l.type,l.data);!1!==t?simpleUpload.iframes[n].complete(t):simpleUpload.iframes[n].error("Upload failed")}}}catch(e){}},window.addEventListener?window.addEventListener("message",simpleUpload.postMessageCallback,!1):window.attachEvent("onmessage",simpleUpload.postMessageCallback),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):e(jQuery)}(function(e){e.fn.simpleUpload=function(l,n){return 0==e(this).length&&"object"==typeof n&&null!==n&&"object"==typeof n.files&&null!==n.files?(new simpleUpload(l,null,n),this):this.each(function(){new simpleUpload(l,this,n)})},e.fn.simpleUpload.maxSimultaneousUploads=function(e){return void 0===e?simpleUpload.maxUploads:"number"==typeof e&&e>0?(simpleUpload.maxUploads=e,this):void 0}}); \ No newline at end of file diff --git a/frontend/express/public/javascripts/utils/textcounter.min.js b/frontend/express/public/javascripts/utils/textcounter.min.js deleted file mode 100644 index 3533ff5c7b3..00000000000 --- a/frontend/express/public/javascripts/utils/textcounter.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! -* jQuery Text Counter Plugin v0.2.1 -* https://github.com/ractoon/jQuery-Text-Counter -* -* Copyright 2014 ractoon -* Released under the MIT license -*/ -;(function(a){a.textcounter=function(c,b){var d=this;d.$el=a(c);d.el=c;d.$el.data("textcounter",d);d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,b);var f=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0;d.$el.after("<"+d.options.countContainerElement+' class="'+d.options.countContainerClass+'">'+f+''+e+"");d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter")};d.checkLimits=function(o){var p=d.$el,t=p.next("."+d.options.countContainerClass),r=p.val(),h=0,u=0,s=o.originalEvent===undefined?false:true;if(d.options.type=="word"){h=r.replace(/\s+/g," ").split(" ").length;if(p.val()===""){h=0}}else{if(d.options.countSpaces){h=r.replace(/\n/g,"\r\n").length}else{h=r.replace(/\s/g,"").length}if(d.options.countExtendedCharacters){var l=r.match(/[^\x00-\xff]/gi);if(l==null){h=r.length}else{h=r.length+l.length}}}if(d.options.max=="auto"){var q=d.$el.attr("maxlength");if(typeof q!=="undefined"&&q!==false){d.options.max=q}else{d.$el.next("."+d.options.countContainerClass).text("error: [maxlength] attribute not set")}}u=d.options.countDown?d.options.max-h:h;d.setCount(u);if(d.options.min>0&&s){if(h=d.options.min){d.clearErrors("min")}}}if(d.options.max!==-1){if(h>d.options.max&&d.options.max!=0){if(d.options.stopInputAtMaximum){var k="";if(d.options.type=="word"){var m=r.split(/[\s\.\?]+/);for(var j=0;j'+errorText+"")}}};d.clearErrors=function(e){var g=d.$el,f=g.next("."+d.options.countContainerClass);f.children(".error-text-"+e).remove();if(f.children(".error-text").length==0){g.removeClass(d.options.inputErrorClass);f.removeClass(d.options.counterErrorClass)}};d.init()};a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: ",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:true,stopInputAtMaximum:true,countSpaces:false,countDown:false,countDownText:"Remaining: ",countExtendedCharacters:false};a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}})(jQuery); \ No newline at end of file diff --git a/frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.css b/frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.css deleted file mode 100755 index 50319a31fd2..00000000000 --- a/frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.css +++ /dev/null @@ -1,406 +0,0 @@ -/* This is the core CSS of Tooltipster */ - -/* GENERAL STRUCTURE RULES (do not edit this section) */ - -.tooltipster-base { - /* this ensures that a constrained height set by functionPosition, - if greater that the natural height of the tooltip, will be enforced - in browsers that support display:flex */ - display: flex; - pointer-events: none; - /* this may be overriden in JS for fixed position origins */ - position: absolute; -} - -.tooltipster-box { - /* see .tooltipster-base. flex-shrink 1 is only necessary for IE10- - and flex-basis auto for IE11- (at least) */ - flex: 1 1 auto; -} - -.tooltipster-content { - /* prevents an overflow if the user adds padding to the div */ - box-sizing: border-box; - /* these make sure we'll be able to detect any overflow */ - max-height: 100%; - max-width: 100%; - overflow: auto; -} - -.tooltipster-ruler { - /* these let us test the size of the tooltip without overflowing the window */ - bottom: 0; - left: 0; - overflow: hidden; - position: fixed; - right: 0; - top: 0; - visibility: hidden; -} - -/* ANIMATIONS */ - -/* Open/close animations */ - -/* fade */ - -.tooltipster-fade { - opacity: 0; - -webkit-transition-property: opacity; - -moz-transition-property: opacity; - -o-transition-property: opacity; - -ms-transition-property: opacity; - transition-property: opacity; -} -.tooltipster-fade.tooltipster-show { - opacity: 1; -} - -/* grow */ - -.tooltipster-grow { - -webkit-transform: scale(0,0); - -moz-transform: scale(0,0); - -o-transform: scale(0,0); - -ms-transform: scale(0,0); - transform: scale(0,0); - -webkit-transition-property: -webkit-transform; - -moz-transition-property: -moz-transform; - -o-transition-property: -o-transform; - -ms-transition-property: -ms-transform; - transition-property: transform; - -webkit-backface-visibility: hidden; -} -.tooltipster-grow.tooltipster-show { - -webkit-transform: scale(1,1); - -moz-transform: scale(1,1); - -o-transform: scale(1,1); - -ms-transform: scale(1,1); - transform: scale(1,1); - -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -} - -/* swing */ - -.tooltipster-swing { - opacity: 0; - -webkit-transform: rotateZ(4deg); - -moz-transform: rotateZ(4deg); - -o-transform: rotateZ(4deg); - -ms-transform: rotateZ(4deg); - transform: rotateZ(4deg); - -webkit-transition-property: -webkit-transform, opacity; - -moz-transition-property: -moz-transform; - -o-transition-property: -o-transform; - -ms-transition-property: -ms-transform; - transition-property: transform; -} -.tooltipster-swing.tooltipster-show { - opacity: 1; - -webkit-transform: rotateZ(0deg); - -moz-transform: rotateZ(0deg); - -o-transform: rotateZ(0deg); - -ms-transform: rotateZ(0deg); - transform: rotateZ(0deg); - -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 1); - -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); - -moz-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); - -ms-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); - -o-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); - transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); -} - -/* fall */ - -.tooltipster-fall { - -webkit-transition-property: top; - -moz-transition-property: top; - -o-transition-property: top; - -ms-transition-property: top; - transition-property: top; - -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -} -.tooltipster-fall.tooltipster-initial { - top: 0 !important; -} -.tooltipster-fall.tooltipster-show { -} -.tooltipster-fall.tooltipster-dying { - -webkit-transition-property: all; - -moz-transition-property: all; - -o-transition-property: all; - -ms-transition-property: all; - transition-property: all; - top: 0 !important; - opacity: 0; -} - -/* slide */ - -.tooltipster-slide { - -webkit-transition-property: left; - -moz-transition-property: left; - -o-transition-property: left; - -ms-transition-property: left; - transition-property: left; - -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); - transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -} -.tooltipster-slide.tooltipster-initial { - left: -40px !important; -} -.tooltipster-slide.tooltipster-show { -} -.tooltipster-slide.tooltipster-dying { - -webkit-transition-property: all; - -moz-transition-property: all; - -o-transition-property: all; - -ms-transition-property: all; - transition-property: all; - left: 0 !important; - opacity: 0; -} - -/* Update animations */ - -/* We use animations rather than transitions here because - transition durations may be specified in the style tag due to - animationDuration, and we try to avoid collisions and the use - of !important */ - -/* fade */ - -@keyframes tooltipster-fading { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -.tooltipster-update-fade { - animation: tooltipster-fading 400ms; -} - -/* rotate */ - -@keyframes tooltipster-rotating { - 25% { - transform: rotate(-2deg); - } - 75% { - transform: rotate(2deg); - } - 100% { - transform: rotate(0); - } -} - -.tooltipster-update-rotate { - animation: tooltipster-rotating 600ms; -} - -/* scale */ - -@keyframes tooltipster-scaling { - 50% { - transform: scale(1.1); - } - 100% { - transform: scale(1); - } -} - -.tooltipster-update-scale { - animation: tooltipster-scaling 600ms; -} - -/** - * DEFAULT STYLE OF THE SIDETIP PLUGIN - * - * All styles are "namespaced" with .tooltipster-sidetip to prevent - * conflicts between plugins. - */ - -/* .tooltipster-box */ - -.tooltipster-sidetip .tooltipster-box { - background: #565656; - border: 2px solid black; - border-radius: 4px; -} - -.tooltipster-sidetip.tooltipster-bottom .tooltipster-box { - margin-top: 8px; -} - -.tooltipster-sidetip.tooltipster-left .tooltipster-box { - margin-right: 8px; -} - -.tooltipster-sidetip.tooltipster-right .tooltipster-box { - margin-left: 8px; -} - -.tooltipster-sidetip.tooltipster-top .tooltipster-box { - margin-bottom: 8px; -} - -/* .tooltipster-content */ - -.tooltipster-sidetip .tooltipster-content { - color: white; - line-height: 18px; - padding: 6px 14px; -} - -/* .tooltipster-arrow : will keep only the zone of .tooltipster-arrow-uncropped that -corresponds to the arrow we want to display */ - -.tooltipster-sidetip .tooltipster-arrow { - overflow: hidden; - position: absolute; -} - -.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow { - height: 10px; - /* half the width, for centering */ - margin-left: -10px; - top: 0; - width: 20px; -} - -.tooltipster-sidetip.tooltipster-left .tooltipster-arrow { - height: 20px; - margin-top: -10px; - right: 0; - /* top 0 to keep the arrow from overflowing .tooltipster-base when it has not - been positioned yet */ - top: 0; - width: 10px; -} - -.tooltipster-sidetip.tooltipster-right .tooltipster-arrow { - height: 20px; - margin-top: -10px; - left: 0; - /* same as .tooltipster-left .tooltipster-arrow */ - top: 0; - width: 10px; -} - -.tooltipster-sidetip.tooltipster-top .tooltipster-arrow { - bottom: 0; - height: 10px; - margin-left: -10px; - width: 20px; -} - -/* common rules between .tooltipster-arrow-background and .tooltipster-arrow-border */ - -.tooltipster-sidetip .tooltipster-arrow-background, .tooltipster-sidetip .tooltipster-arrow-border { - height: 0; - position: absolute; - width: 0; -} - -/* .tooltipster-arrow-background */ - -.tooltipster-sidetip .tooltipster-arrow-background { - border: 10px solid transparent; -} - -.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-background { - border-bottom-color: #565656; - left: 0px; - top: 3px; -} - -.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-background { - border-left-color: #565656; - left: -3px; - top: 0px; -} - -.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-background { - border-right-color: #565656; - left: 3px; - top: 0px; -} - -.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-background { - border-top-color: #565656; - left: 0px; - top: -3px; -} - -/* .tooltipster-arrow-border */ - -.tooltipster-sidetip .tooltipster-arrow-border { - border: 10px solid transparent; - left: 0; - top: 0; -} - -.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border { - border-bottom-color: black; -} - -.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border { - border-left-color: black; -} - -.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border { - border-right-color: black; -} - -.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border { - border-top-color: black; -} - -/* tooltipster-arrow-uncropped */ - -.tooltipster-sidetip .tooltipster-arrow-uncropped { - position: relative; -} - -.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped { - top: -10px; -} - -.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped { - left: -10px; -} - -/* BORDERLESS THEME */ -.tooltipster-sidetip.tooltipster-borderless .tooltipster-box{border:none;background:rgba(10,10,10,.8)} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-bottom .tooltipster-box{margin-top:8px} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-left .tooltipster-box{margin-right:8px} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-box{margin-left:8px} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-top .tooltipster-box{margin-bottom:8px} -.tooltipster-sidetip.tooltipster-borderless .tooltipster-arrow{height:8px;margin-left:-8px;width:16px} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-arrow{height:16px;margin-left:0;margin-top:-8px;width:8px} -.tooltipster-sidetip.tooltipster-borderless .tooltipster-arrow-background{display:none} -.tooltipster-sidetip.tooltipster-borderless .tooltipster-arrow-border{border:8px solid transparent} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:rgba(10,10,10,.8)} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-left .tooltipster-arrow-border{border-left-color:rgba(10,10,10,.8)} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-arrow-border{border-right-color:rgba(10,10,10,.8)} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-top .tooltipster-arrow-border{border-top-color:rgba(10,10,10,.8)} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-bottom .tooltipster-arrow-uncropped{top:-8px} -.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-arrow-uncropped{left:-8px} - \ No newline at end of file diff --git a/frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.js b/frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.js deleted file mode 100755 index 87cbf09ce77..00000000000 --- a/frontend/express/public/javascripts/utils/tooltipster/tooltipster.bundle.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! tooltipster v4.1.6 */!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){function b(a){this.$container,this.constraints=null,this.__$tooltip,this.__init(a)}function c(b,c){var d=!0;return a.each(b,function(a,e){return void 0===c[a]||b[a]!==c[a]?(d=!1,!1):void 0}),d}function d(b){var c=b.attr("id"),d=c?h.window.document.getElementById(c):null;return d?d===b[0]:a.contains(h.window.document.body,b[0])}function e(){if(!g)return!1;var a=g.document.body||g.document.documentElement,b=a.style,c="transition",d=["Moz","Webkit","Khtml","O","ms"];if("string"==typeof b[c])return!0;c=c.charAt(0).toUpperCase()+c.substr(1);for(var e=0;e0?e=c.__plugins[d]:a.each(c.__plugins,function(a,b){return b.name.substring(b.name.length-d.length-1)=="."+d?(e=b,!1):void 0}),e}if(b.name.indexOf(".")<0)throw new Error("Plugins must be namespaced");return c.__plugins[b.name]=b,b.core&&c.__bridge(b.core,c,b.name),this},_trigger:function(){var a=Array.prototype.slice.apply(arguments);return"string"==typeof a[0]&&(a[0]={type:a[0]}),this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,a),this.__$emitterPublic.trigger.apply(this.__$emitterPublic,a),this},instances:function(b){var c=[],d=b||".tooltipstered";return a(d).each(function(){var b=a(this),d=b.data("tooltipster-ns");d&&a.each(d,function(a,d){c.push(b.data(d))})}),c},instancesLatest:function(){return this.__instancesLatestArr},off:function(){return this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},on:function(){return this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},one:function(){return this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},origins:function(b){var c=b?b+" ":"";return a(c+".tooltipstered").toArray()},setDefaults:function(b){return a.extend(f,b),this},triggerHandler:function(){return this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this}},a.tooltipster=new i,a.Tooltipster=function(b,c){this.__callbacks={close:[],open:[]},this.__closingTime,this.__Content,this.__contentBcr,this.__destroyed=!1,this.__destroying=!1,this.__$emitterPrivate=a({}),this.__$emitterPublic=a({}),this.__enabled=!0,this.__garbageCollector,this.__Geometry,this.__lastPosition,this.__namespace="tooltipster-"+Math.round(1e6*Math.random()),this.__options,this.__$originParents,this.__pointerIsOverOrigin=!1,this.__previousThemes=[],this.__state="closed",this.__timeouts={close:[],open:null},this.__touchEvents=[],this.__tracker=null,this._$origin,this._$tooltip,this.__init(b,c)},a.Tooltipster.prototype={__init:function(b,c){var d=this;if(d._$origin=a(b),d.__options=a.extend(!0,{},f,c),d.__optionsFormat(),!h.IE||h.IE>=d.__options.IEmin){var e=null;if(void 0===d._$origin.data("tooltipster-initialTitle")&&(e=d._$origin.attr("title"),void 0===e&&(e=null),d._$origin.data("tooltipster-initialTitle",e)),null!==d.__options.content)d.__contentSet(d.__options.content);else{var g,i=d._$origin.attr("data-tooltip-content");i&&(g=a(i)),g&&g[0]?d.__contentSet(g.first()):d.__contentSet(e)}d._$origin.removeAttr("title").addClass("tooltipstered"),d.__prepareOrigin(),d.__prepareGC(),a.each(d.__options.plugins,function(a,b){d._plug(b)}),h.hasTouchCapability&&a("body").on("touchmove."+d.__namespace+"-triggerOpen",function(a){d._touchRecordEvent(a)}),d._on("created",function(){d.__prepareTooltip()})._on("repositioned",function(a){d.__lastPosition=a.position})}else d.__options.disabled=!0},__contentInsert:function(){var a=this,b=a._$tooltip.find(".tooltipster-content"),c=a.__Content,d=function(a){c=a};return a._trigger({type:"format",content:a.__Content,format:d}),a.__options.functionFormat&&(c=a.__options.functionFormat.call(a,a,{origin:a._$origin[0]},a.__Content)),"string"!=typeof c||a.__options.contentAsHTML?b.empty().append(c):b.text(c),a},__contentSet:function(b){return b instanceof a&&this.__options.contentCloning&&(b=b.clone(!0)),this.__Content=b,this._trigger({type:"updated",content:b}),this},__destroyError:function(){throw new Error("This tooltip has been destroyed and cannot execute your method call.")},__geometry:function(){var b=this,c=b._$origin,d=b._$origin.is("area");if(d){var e=b._$origin.parent().attr("name");c=a('img[usemap="#'+e+'"]')}var f=c[0].getBoundingClientRect(),g=a(h.window.document),i=a(h.window),j=c,k={available:{document:null,window:null},document:{size:{height:g.height(),width:g.width()}},window:{scroll:{left:h.window.scrollX||h.window.document.documentElement.scrollLeft,top:h.window.scrollY||h.window.document.documentElement.scrollTop},size:{height:i.height(),width:i.width()}},origin:{fixedLineage:!1,offset:{},size:{height:f.bottom-f.top,width:f.right-f.left},usemapImage:d?c[0]:null,windowOffset:{bottom:f.bottom,left:f.left,right:f.right,top:f.top}}};if(d){var l=b._$origin.attr("shape"),m=b._$origin.attr("coords");if(m&&(m=m.split(","),a.map(m,function(a,b){m[b]=parseInt(a)})),"default"!=l)switch(l){case"circle":var n=m[0],o=m[1],p=m[2],q=o-p,r=n-p;k.origin.size.height=2*p,k.origin.size.width=k.origin.size.height,k.origin.windowOffset.left+=r,k.origin.windowOffset.top+=q;break;case"rect":var s=m[0],t=m[1],u=m[2],v=m[3];k.origin.size.height=v-t,k.origin.size.width=u-s,k.origin.windowOffset.left+=s,k.origin.windowOffset.top+=t;break;case"poly":for(var w=0,x=0,y=0,z=0,A="even",B=0;By&&(y=C,0===B&&(w=y)),w>C&&(w=C),A="odd"):(C>z&&(z=C,1==B&&(x=z)),x>C&&(x=C),A="even")}k.origin.size.height=z-x,k.origin.size.width=y-w,k.origin.windowOffset.left+=w,k.origin.windowOffset.top+=x}}var D=function(a){k.origin.size.height=a.height,k.origin.windowOffset.left=a.left,k.origin.windowOffset.top=a.top,k.origin.size.width=a.width};for(b._trigger({type:"geometry",edit:D,geometry:{height:k.origin.size.height,left:k.origin.windowOffset.left,top:k.origin.windowOffset.top,width:k.origin.size.width}}),k.origin.windowOffset.right=k.origin.windowOffset.left+k.origin.size.width,k.origin.windowOffset.bottom=k.origin.windowOffset.top+k.origin.size.height,k.origin.offset.left=k.origin.windowOffset.left+k.window.scroll.left,k.origin.offset.top=k.origin.windowOffset.top+k.window.scroll.top,k.origin.offset.bottom=k.origin.offset.top+k.origin.size.height,k.origin.offset.right=k.origin.offset.left+k.origin.size.width,k.available.document={bottom:{height:k.document.size.height-k.origin.offset.bottom,width:k.document.size.width},left:{height:k.document.size.height,width:k.origin.offset.left},right:{height:k.document.size.height,width:k.document.size.width-k.origin.offset.right},top:{height:k.origin.offset.top,width:k.document.size.width}},k.available.window={bottom:{height:Math.max(k.window.size.height-Math.max(k.origin.windowOffset.bottom,0),0),width:k.window.size.width},left:{height:k.window.size.height,width:Math.max(k.origin.windowOffset.left,0)},right:{height:k.window.size.height,width:Math.max(k.window.size.width-Math.max(k.origin.windowOffset.right,0),0)},top:{height:Math.max(k.origin.windowOffset.top,0),width:k.window.size.width}};"html"!=j[0].tagName.toLowerCase();){if("fixed"==j.css("position")){k.origin.fixedLineage=!0;break}j=j.parent()}return k},__optionsFormat:function(){return"number"==typeof this.__options.animationDuration&&(this.__options.animationDuration=[this.__options.animationDuration,this.__options.animationDuration]),"number"==typeof this.__options.delay&&(this.__options.delay=[this.__options.delay,this.__options.delay]),"number"==typeof this.__options.delayTouch&&(this.__options.delayTouch=[this.__options.delayTouch,this.__options.delayTouch]),"string"==typeof this.__options.theme&&(this.__options.theme=[this.__options.theme]),"string"==typeof this.__options.parent&&(this.__options.parent=a(this.__options.parent)),"hover"==this.__options.trigger?(this.__options.triggerOpen={mouseenter:!0,touchstart:!0},this.__options.triggerClose={mouseleave:!0,originClick:!0,touchleave:!0}):"click"==this.__options.trigger&&(this.__options.triggerOpen={click:!0,tap:!0},this.__options.triggerClose={click:!0,tap:!0}),this._trigger("options"),this},__prepareGC:function(){var b=this;return b.__options.selfDestruction?b.__garbageCollector=setInterval(function(){var c=(new Date).getTime();b.__touchEvents=a.grep(b.__touchEvents,function(a,b){return c-a.time>6e4}),d(b._$origin)||b.destroy()},2e4):clearInterval(b.__garbageCollector),b},__prepareOrigin:function(){var a=this;if(a._$origin.off("."+a.__namespace+"-triggerOpen"),h.hasTouchCapability&&a._$origin.on("touchstart."+a.__namespace+"-triggerOpen touchend."+a.__namespace+"-triggerOpen touchcancel."+a.__namespace+"-triggerOpen",function(b){a._touchRecordEvent(b)}),a.__options.triggerOpen.click||a.__options.triggerOpen.tap&&h.hasTouchCapability){var b="";a.__options.triggerOpen.click&&(b+="click."+a.__namespace+"-triggerOpen "),a.__options.triggerOpen.tap&&h.hasTouchCapability&&(b+="touchend."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){a._touchIsMeaningfulEvent(b)&&a._open(b)})}if(a.__options.triggerOpen.mouseenter||a.__options.triggerOpen.touchstart&&h.hasTouchCapability){var b="";a.__options.triggerOpen.mouseenter&&(b+="mouseenter."+a.__namespace+"-triggerOpen "),a.__options.triggerOpen.touchstart&&h.hasTouchCapability&&(b+="touchstart."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){!a._touchIsTouchEvent(b)&&a._touchIsEmulatedEvent(b)||(a.__pointerIsOverOrigin=!0,a._openShortly(b))})}if(a.__options.triggerClose.mouseleave||a.__options.triggerClose.touchleave&&h.hasTouchCapability){var b="";a.__options.triggerClose.mouseleave&&(b+="mouseleave."+a.__namespace+"-triggerOpen "),a.__options.triggerClose.touchleave&&h.hasTouchCapability&&(b+="touchend."+a.__namespace+"-triggerOpen touchcancel."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){a._touchIsMeaningfulEvent(b)&&(a.__pointerIsOverOrigin=!1)})}return a},__prepareTooltip:function(){var b=this,c=b.__options.interactive?"auto":"";return b._$tooltip.attr("id",b.__namespace).css({"pointer-events":c,zIndex:b.__options.zIndex}),a.each(b.__previousThemes,function(a,c){b._$tooltip.removeClass(c)}),a.each(b.__options.theme,function(a,c){b._$tooltip.addClass(c)}),b.__previousThemes=a.merge([],b.__options.theme),b},__scrollHandler:function(b){var c=this;if(c.__options.triggerClose.scroll)c._close(b);else{if(b.target===h.window.document)c.__Geometry.origin.fixedLineage||c.__options.repositionOnScroll&&c.reposition(b);else{var d=c.__geometry(),e=!1;if("fixed"!=c._$origin.css("position")&&c.__$originParents.each(function(b,c){var f=a(c),g=f.css("overflow-x"),h=f.css("overflow-y");if("visible"!=g||"visible"!=h){var i=c.getBoundingClientRect();if("visible"!=g&&(d.origin.windowOffset.lefti.right))return e=!0,!1;if("visible"!=h&&(d.origin.windowOffset.topi.bottom))return e=!0,!1}return"fixed"==f.css("position")?!1:void 0}),e)c._$tooltip.css("visibility","hidden");else if(c._$tooltip.css("visibility","visible"),c.__options.repositionOnScroll)c.reposition(b);else{var f=d.origin.offset.left-c.__Geometry.origin.offset.left,g=d.origin.offset.top-c.__Geometry.origin.offset.top;c._$tooltip.css({left:c.__lastPosition.coord.left+f,top:c.__lastPosition.coord.top+g})}}c._trigger({type:"scroll",event:b})}return c},__stateSet:function(a){return this.__state=a,this._trigger({type:"state",state:a}),this},__timeoutsClear:function(){return clearTimeout(this.__timeouts.open),this.__timeouts.open=null,a.each(this.__timeouts.close,function(a,b){clearTimeout(b)}),this.__timeouts.close=[],this},__trackerStart:function(){var a=this,b=a._$tooltip.find(".tooltipster-content");return a.__options.trackTooltip&&(a.__contentBcr=b[0].getBoundingClientRect()),a.__tracker=setInterval(function(){if(d(a._$origin)&&d(a._$tooltip)){if(a.__options.trackOrigin){var e=a.__geometry(),f=!1;c(e.origin.size,a.__Geometry.origin.size)&&(a.__Geometry.origin.fixedLineage?c(e.origin.windowOffset,a.__Geometry.origin.windowOffset)&&(f=!0):c(e.origin.offset,a.__Geometry.origin.offset)&&(f=!0)),f||(a.__options.triggerClose.mouseleave?a._close():a.reposition())}if(a.__options.trackTooltip){var g=b[0].getBoundingClientRect();g.height===a.__contentBcr.height&&g.width===a.__contentBcr.width||(a.reposition(),a.__contentBcr=g)}}else a._close()},a.__options.trackerInterval),a},_close:function(b,c){var d=this,e=!0;if(d._trigger({type:"close",event:b,stop:function(){e=!1}}),e||d.__destroying){c&&d.__callbacks.close.push(c),d.__callbacks.open=[],d.__timeoutsClear();var f=function(){a.each(d.__callbacks.close,function(a,c){c.call(d,d,{event:b,origin:d._$origin[0]})}),d.__callbacks.close=[]};if("closed"!=d.__state){var g=!0,i=new Date,j=i.getTime(),k=j+d.__options.animationDuration[1];if("disappearing"==d.__state&&k>d.__closingTime&&(g=!1),g){d.__closingTime=k,"disappearing"!=d.__state&&d.__stateSet("disappearing");var l=function(){clearInterval(d.__tracker),d._trigger({type:"closing",event:b}),d._$tooltip.off("."+d.__namespace+"-triggerClose").removeClass("tooltipster-dying"),a(h.window).off("."+d.__namespace+"-triggerClose"),d.__$originParents.each(function(b,c){a(c).off("scroll."+d.__namespace+"-triggerClose")}),d.__$originParents=null,a("body").off("."+d.__namespace+"-triggerClose"),d._$origin.off("."+d.__namespace+"-triggerClose"),d._off("dismissable"),d.__stateSet("closed"),d._trigger({type:"after",event:b}),d.__options.functionAfter&&d.__options.functionAfter.call(d,d,{event:b,origin:d._$origin[0]}),f()};h.hasTransitions?(d._$tooltip.css({"-moz-animation-duration":d.__options.animationDuration[1]+"ms","-ms-animation-duration":d.__options.animationDuration[1]+"ms","-o-animation-duration":d.__options.animationDuration[1]+"ms","-webkit-animation-duration":d.__options.animationDuration[1]+"ms","animation-duration":d.__options.animationDuration[1]+"ms","transition-duration":d.__options.animationDuration[1]+"ms"}),d._$tooltip.clearQueue().removeClass("tooltipster-show").addClass("tooltipster-dying"),d.__options.animationDuration[1]>0&&d._$tooltip.delay(d.__options.animationDuration[1]),d._$tooltip.queue(l)):d._$tooltip.stop().fadeOut(d.__options.animationDuration[1],l)}}else f()}return d},_off:function(){return this.__$emitterPrivate.off.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_on:function(){return this.__$emitterPrivate.on.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_one:function(){return this.__$emitterPrivate.one.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_open:function(b,c){var e=this;if(!e.__destroying&&d(e._$origin)&&e.__enabled){var f=!0;if("closed"==e.__state&&(e._trigger({type:"before",event:b,stop:function(){f=!1}}),f&&e.__options.functionBefore&&(f=e.__options.functionBefore.call(e,e,{event:b,origin:e._$origin[0]}))),f!==!1&&null!==e.__Content){c&&e.__callbacks.open.push(c),e.__callbacks.close=[],e.__timeoutsClear();var g,i=function(){"stable"!=e.__state&&e.__stateSet("stable"),a.each(e.__callbacks.open,function(a,b){b.call(e,e,{origin:e._$origin[0],tooltip:e._$tooltip[0]})}),e.__callbacks.open=[]};if("closed"!==e.__state)g=0,"disappearing"===e.__state?(e.__stateSet("appearing"),h.hasTransitions?(e._$tooltip.clearQueue().removeClass("tooltipster-dying").addClass("tooltipster-show"),e.__options.animationDuration[0]>0&&e._$tooltip.delay(e.__options.animationDuration[0]),e._$tooltip.queue(i)):e._$tooltip.stop().fadeIn(i)):"stable"==e.__state&&i();else{if(e.__stateSet("appearing"),g=e.__options.animationDuration[0],e.__contentInsert(),e.reposition(b,!0),h.hasTransitions?(e._$tooltip.addClass("tooltipster-"+e.__options.animation).addClass("tooltipster-initial").css({"-moz-animation-duration":e.__options.animationDuration[0]+"ms","-ms-animation-duration":e.__options.animationDuration[0]+"ms","-o-animation-duration":e.__options.animationDuration[0]+"ms","-webkit-animation-duration":e.__options.animationDuration[0]+"ms","animation-duration":e.__options.animationDuration[0]+"ms","transition-duration":e.__options.animationDuration[0]+"ms"}),setTimeout(function(){"closed"!=e.__state&&(e._$tooltip.addClass("tooltipster-show").removeClass("tooltipster-initial"),e.__options.animationDuration[0]>0&&e._$tooltip.delay(e.__options.animationDuration[0]),e._$tooltip.queue(i))},0)):e._$tooltip.css("display","none").fadeIn(e.__options.animationDuration[0],i),e.__trackerStart(),a(h.window).on("resize."+e.__namespace+"-triggerClose",function(b){var c=a(document.activeElement);(c.is("input")||c.is("textarea"))&&a.contains(e._$tooltip[0],c[0])||e.reposition(b)}).on("scroll."+e.__namespace+"-triggerClose",function(a){e.__scrollHandler(a)}),e.__$originParents=e._$origin.parents(),e.__$originParents.each(function(b,c){a(c).on("scroll."+e.__namespace+"-triggerClose",function(a){e.__scrollHandler(a)})}),e.__options.triggerClose.mouseleave||e.__options.triggerClose.touchleave&&h.hasTouchCapability){e._on("dismissable",function(a){a.dismissable?a.delay?(m=setTimeout(function(){e._close(a.event)},a.delay),e.__timeouts.close.push(m)):e._close(a):clearTimeout(m)});var j=e._$origin,k="",l="",m=null;e.__options.interactive&&(j=j.add(e._$tooltip)),e.__options.triggerClose.mouseleave&&(k+="mouseenter."+e.__namespace+"-triggerClose ",l+="mouseleave."+e.__namespace+"-triggerClose "),e.__options.triggerClose.touchleave&&h.hasTouchCapability&&(k+="touchstart."+e.__namespace+"-triggerClose",l+="touchend."+e.__namespace+"-triggerClose touchcancel."+e.__namespace+"-triggerClose"),j.on(l,function(a){if(e._touchIsTouchEvent(a)||!e._touchIsEmulatedEvent(a)){var b="mouseleave"==a.type?e.__options.delay:e.__options.delayTouch;e._trigger({delay:b[1],dismissable:!0,event:a,type:"dismissable"})}}).on(k,function(a){!e._touchIsTouchEvent(a)&&e._touchIsEmulatedEvent(a)||e._trigger({dismissable:!1,event:a,type:"dismissable"})})}e.__options.triggerClose.originClick&&e._$origin.on("click."+e.__namespace+"-triggerClose",function(a){e._touchIsTouchEvent(a)||e._touchIsEmulatedEvent(a)||e._close(a)}),(e.__options.triggerClose.click||e.__options.triggerClose.tap&&h.hasTouchCapability)&&setTimeout(function(){if("closed"!=e.__state){var b="";e.__options.triggerClose.click&&(b+="click."+e.__namespace+"-triggerClose "),e.__options.triggerClose.tap&&h.hasTouchCapability&&(b+="touchend."+e.__namespace+"-triggerClose"),a("body").on(b,function(b){e._touchIsMeaningfulEvent(b)&&(e._touchRecordEvent(b),e.__options.interactive&&a.contains(e._$tooltip[0],b.target)||e._close(b))}),e.__options.triggerClose.tap&&h.hasTouchCapability&&a("body").on("touchstart."+e.__namespace+"-triggerClose",function(a){e._touchRecordEvent(a)})}},0),e._trigger("ready"),e.__options.functionReady&&e.__options.functionReady.call(e,e,{origin:e._$origin[0],tooltip:e._$tooltip[0]})}if(e.__options.timer>0){var m=setTimeout(function(){e._close()},e.__options.timer+g);e.__timeouts.close.push(m)}}}return e},_openShortly:function(a){var b=this,c=!0;if("stable"!=b.__state&&"appearing"!=b.__state&&!b.__timeouts.open&&(b._trigger({type:"start",event:a,stop:function(){c=!1}}),c)){var d=0==a.type.indexOf("touch")?b.__options.delayTouch:b.__options.delay;d[0]?b.__timeouts.open=setTimeout(function(){b.__timeouts.open=null,b.__pointerIsOverOrigin&&b._touchIsMeaningfulEvent(a)?(b._trigger("startend"),b._open(a)):b._trigger("startcancel")},d[0]):(b._trigger("startend"),b._open(a))}return b},_optionsExtract:function(b,c){var d=this,e=a.extend(!0,{},c),f=d.__options[b];return f||(f={},a.each(c,function(a,b){var c=d.__options[a];void 0!==c&&(f[a]=c)})),a.each(e,function(b,c){void 0!==f[b]&&("object"!=typeof c||c instanceof Array||null==c||"object"!=typeof f[b]||f[b]instanceof Array||null==f[b]?e[b]=f[b]:a.extend(e[b],f[b]))}),e},_plug:function(b){var c=a.tooltipster._plugin(b);if(!c)throw new Error('The "'+b+'" plugin is not defined');return c.instance&&a.tooltipster.__bridge(c.instance,this,c.name),this},_touchIsEmulatedEvent:function(a){for(var b=!1,c=(new Date).getTime(),d=this.__touchEvents.length-1;d>=0;d--){var e=this.__touchEvents[d];if(!(c-e.time<500))break;e.target===a.target&&(b=!0)}return b},_touchIsMeaningfulEvent:function(a){return this._touchIsTouchEvent(a)&&!this._touchSwiped(a.target)||!this._touchIsTouchEvent(a)&&!this._touchIsEmulatedEvent(a)},_touchIsTouchEvent:function(a){return 0==a.type.indexOf("touch")},_touchRecordEvent:function(a){return this._touchIsTouchEvent(a)&&(a.time=(new Date).getTime(),this.__touchEvents.push(a)),this},_touchSwiped:function(a){for(var b=!1,c=this.__touchEvents.length-1;c>=0;c--){var d=this.__touchEvents[c];if("touchmove"==d.type){b=!0;break}if("touchstart"==d.type&&a===d.target)break}return b},_trigger:function(){var b=Array.prototype.slice.apply(arguments);return"string"==typeof b[0]&&(b[0]={type:b[0]}),b[0].instance=this,b[0].origin=this._$origin?this._$origin[0]:null,b[0].tooltip=this._$tooltip?this._$tooltip[0]:null,this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,b),a.tooltipster._trigger.apply(a.tooltipster,b),this.__$emitterPublic.trigger.apply(this.__$emitterPublic,b),this},_unplug:function(b){var c=this;if(c[b]){var d=a.tooltipster._plugin(b);d.instance&&a.each(d.instance,function(a,d){c[a]&&c[a].bridged===c[b]&&delete c[a]}),c[b].__destroy&&c[b].__destroy(),delete c[b]}return c},close:function(a){return this.__destroyed?this.__destroyError():this._close(null,a),this},content:function(a){var b=this;if(void 0===a)return b.__Content;if(b.__destroyed)b.__destroyError();else if(b.__contentSet(a),null!==b.__Content){if("closed"!==b.__state&&(b.__contentInsert(),b.reposition(),b.__options.updateAnimation))if(h.hasTransitions){var c=b.__options.updateAnimation;b._$tooltip.addClass("tooltipster-update-"+c),setTimeout(function(){"closed"!=b.__state&&b._$tooltip.removeClass("tooltipster-update-"+c)},1e3)}else b._$tooltip.fadeTo(200,.5,function(){"closed"!=b.__state&&b._$tooltip.fadeTo(200,1)})}else b._close();return b},destroy:function(){var b=this;return b.__destroyed?b.__destroyError():b.__destroying||(b.__destroying=!0,b._close(null,function(){b._trigger("destroy"),b.__destroying=!1,b.__destroyed=!0,b._$origin.removeData(b.__namespace).off("."+b.__namespace+"-triggerOpen"),a("body").off("."+b.__namespace+"-triggerOpen");var c=b._$origin.data("tooltipster-ns");if(c)if(1===c.length){var d=null;"previous"==b.__options.restoration?d=b._$origin.data("tooltipster-initialTitle"):"current"==b.__options.restoration&&(d="string"==typeof b.__Content?b.__Content:a("
      ").append(b.__Content).html()),d&&b._$origin.attr("title",d),b._$origin.removeClass("tooltipstered"),b._$origin.removeData("tooltipster-ns").removeData("tooltipster-initialTitle")}else c=a.grep(c,function(a,c){return a!==b.__namespace}),b._$origin.data("tooltipster-ns",c);b._trigger("destroyed"),b._off(),b.off(),b.__Content=null,b.__$emitterPrivate=null,b.__$emitterPublic=null,b.__options.parent=null,b._$origin=null,b._$tooltip=null,a.tooltipster.__instancesLatestArr=a.grep(a.tooltipster.__instancesLatestArr,function(a,c){return b!==a}),clearInterval(b.__garbageCollector)})),b},disable:function(){return this.__destroyed?(this.__destroyError(),this):(this._close(),this.__enabled=!1,this)},elementOrigin:function(){return this.__destroyed?void this.__destroyError():this._$origin[0]},elementTooltip:function(){return this._$tooltip?this._$tooltip[0]:null},enable:function(){return this.__enabled=!0,this},hide:function(a){return this.close(a)},instance:function(){return this},off:function(){return this.__destroyed||this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},on:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},one:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},open:function(a){return this.__destroyed||this.__destroying?this.__destroyError():this._open(null,a),this},option:function(b,c){return void 0===c?this.__options[b]:(this.__destroyed?this.__destroyError():(this.__options[b]=c,this.__optionsFormat(),a.inArray(b,["trigger","triggerClose","triggerOpen"])>=0&&this.__prepareOrigin(),"selfDestruction"===b&&this.__prepareGC()),this)},reposition:function(a,b){var c=this;return c.__destroyed?c.__destroyError():"closed"!=c.__state&&d(c._$origin)&&(b||d(c._$tooltip))&&(b||c._$tooltip.detach(),c.__Geometry=c.__geometry(),c._trigger({type:"reposition",event:a,helper:{geo:c.__Geometry}})),c},show:function(a){return this.open(a)},status:function(){return{destroyed:this.__destroyed,destroying:this.__destroying,enabled:this.__enabled,open:"closed"!==this.__state,state:this.__state}},triggerHandler:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this}},a.fn.tooltipster=function(){var b=Array.prototype.slice.apply(arguments),c="You are using a single HTML element as content for several tooltips. You probably want to set the contentCloning option to TRUE.";if(0===this.length)return this;if("string"==typeof b[0]){var d="#*$~&";return this.each(function(){var e=a(this).data("tooltipster-ns"),f=e?a(this).data(e[0]):null;if(!f)throw new Error("You called Tooltipster's \""+b[0]+'" method on an uninitialized element');if("function"!=typeof f[b[0]])throw new Error('Unknown method "'+b[0]+'"');this.length>1&&"content"==b[0]&&(b[1]instanceof a||"object"==typeof b[1]&&null!=b[1]&&b[1].tagName)&&!f.__options.contentCloning&&f.__options.debug&&console.log(c);var g=f[b[0]](b[1],b[2]);return g!==f||"instance"===b[0]?(d=g,!1):void 0}),"#*$~&"!==d?d:this}a.tooltipster.__instancesLatestArr=[];var e=b[0]&&void 0!==b[0].multiple,g=e&&b[0].multiple||!e&&f.multiple,h=b[0]&&void 0!==b[0].content,i=h&&b[0].content||!h&&f.content,j=b[0]&&void 0!==b[0].contentCloning,k=j&&b[0].contentCloning||!j&&f.contentCloning,l=b[0]&&void 0!==b[0].debug,m=l&&b[0].debug||!l&&f.debug;return this.length>1&&(i instanceof a||"object"==typeof i&&null!=i&&i.tagName)&&!k&&m&&console.log(c),this.each(function(){var c=!1,d=a(this),e=d.data("tooltipster-ns"),f=null;e?g?c=!0:m&&(console.log("Tooltipster: one or more tooltips are already attached to the element below. Ignoring."),console.log(this)):c=!0,c&&(f=new a.Tooltipster(this,b[0]),e||(e=[]),e.push(f.__namespace),d.data("tooltipster-ns",e),d.data(f.__namespace,f),f.__options.functionInit&&f.__options.functionInit.call(f,f,{origin:this}),f._trigger("init")),a.tooltipster.__instancesLatestArr.push(f)}),this},b.prototype={__init:function(b){this.__$tooltip=b,this.__$tooltip.css({left:0,overflow:"hidden",position:"absolute",top:0}).find(".tooltipster-content").css("overflow","auto"),this.$container=a('
      ').append(this.__$tooltip).appendTo("body")},__forceRedraw:function(){var a=this.__$tooltip.parent();this.__$tooltip.detach(),this.__$tooltip.appendTo(a)},constrain:function(a,b){return this.constraints={width:a,height:b},this.__$tooltip.css({display:"block",height:"",overflow:"auto",width:a}),this},destroy:function(){this.__$tooltip.detach().find(".tooltipster-content").css({display:"",overflow:""}),this.$container.remove()},free:function(){return this.constraints=null,this.__$tooltip.css({display:"",height:"",overflow:"visible",width:""}),this},measure:function(){this.__forceRedraw();var a=this.__$tooltip[0].getBoundingClientRect(),b={size:{height:a.height||a.bottom,width:a.width||a.right}};if(this.constraints){var c=this.__$tooltip.find(".tooltipster-content"),d=this.__$tooltip.outerHeight(),e=c[0].getBoundingClientRect(),f={height:d<=this.constraints.height,width:a.width<=this.constraints.width&&e.width>=c[0].scrollWidth-1};b.fits=f.height&&f.width}return h.IE&&h.IE<=11&&b.size.width!==h.window.document.documentElement.clientWidth&&(b.size.width=Math.ceil(b.size.width)+1),b}};var j=navigator.userAgent.toLowerCase();-1!=j.indexOf("msie")?h.IE=parseInt(j.split("msie")[1]):-1!==j.toLowerCase().indexOf("trident")&&-1!==j.indexOf(" rv:11")?h.IE=11:-1!=j.toLowerCase().indexOf("edge/")&&(h.IE=parseInt(j.toLowerCase().split("edge/")[1]));var k="tooltipster.sideTip";return a.tooltipster._plugin({name:k,instance:{__defaults:function(){return{arrow:!0,distance:6,functionPosition:null,maxWidth:null,minIntersection:16,minWidth:0,position:null,side:"top",viewportAware:!0}},__init:function(a){var b=this;b.__instance=a,b.__namespace="tooltipster-sideTip-"+Math.round(1e6*Math.random()),b.__previousState="closed",b.__options,b.__optionsFormat(),b.__instance._on("state."+b.__namespace,function(a){"closed"==a.state?b.__close():"appearing"==a.state&&"closed"==b.__previousState&&b.__create(),b.__previousState=a.state}),b.__instance._on("options."+b.__namespace,function(){b.__optionsFormat()}),b.__instance._on("reposition."+b.__namespace,function(a){b.__reposition(a.event,a.helper)})},__close:function(){this.__instance.content()instanceof a&&this.__instance.content().detach(),this.__instance._$tooltip.remove(),this.__instance._$tooltip=null},__create:function(){var b=a('
      ');this.__options.arrow||b.find(".tooltipster-box").css("margin",0).end().find(".tooltipster-arrow").hide(),this.__options.minWidth&&b.css("min-width",this.__options.minWidth+"px"),this.__options.maxWidth&&b.css("max-width",this.__options.maxWidth+"px"),this.__instance._$tooltip=b,this.__instance._trigger("created")},__destroy:function(){this.__instance._off("."+self.__namespace)},__optionsFormat:function(){var b=this;if(b.__options=b.__instance._optionsExtract(k,b.__defaults()), -b.__options.position&&(b.__options.side=b.__options.position),"object"!=typeof b.__options.distance&&(b.__options.distance=[b.__options.distance]),b.__options.distance.length<4&&(void 0===b.__options.distance[1]&&(b.__options.distance[1]=b.__options.distance[0]),void 0===b.__options.distance[2]&&(b.__options.distance[2]=b.__options.distance[0]),void 0===b.__options.distance[3]&&(b.__options.distance[3]=b.__options.distance[1]),b.__options.distance={top:b.__options.distance[0],right:b.__options.distance[1],bottom:b.__options.distance[2],left:b.__options.distance[3]}),"string"==typeof b.__options.side){var c={top:"bottom",right:"left",bottom:"top",left:"right"};b.__options.side=[b.__options.side,c[b.__options.side]],"left"==b.__options.side[0]||"right"==b.__options.side[0]?b.__options.side.push("top","bottom"):b.__options.side.push("right","left")}6===a.tooltipster._env.IE&&b.__options.arrow!==!0&&(b.__options.arrow=!1)},__reposition:function(b,c){var d,e=this,f=e.__targetFind(c),g=[];e.__instance._$tooltip.detach();var h=e.__instance._$tooltip.clone(),i=a.tooltipster._getRuler(h),j=!1,k=e.__instance.option("animation");switch(k&&h.removeClass("tooltipster-"+k),a.each(["window","document"],function(d,k){var l=null;if(e.__instance._trigger({container:k,helper:c,satisfied:j,takeTest:function(a){l=a},results:g,type:"positionTest"}),1==l||0!=l&&0==j&&("window"!=k||e.__options.viewportAware))for(var d=0;d=h.outerSize.width&&c.geo.available[k][n].height>=h.outerSize.height?h.fits=!0:h.fits=!1:h.fits=p.fits,"window"==k&&(h.fits?"top"==n||"bottom"==n?h.whole=c.geo.origin.windowOffset.right>=e.__options.minIntersection&&c.geo.window.size.width-c.geo.origin.windowOffset.left>=e.__options.minIntersection:h.whole=c.geo.origin.windowOffset.bottom>=e.__options.minIntersection&&c.geo.window.size.height-c.geo.origin.windowOffset.top>=e.__options.minIntersection:h.whole=!1),g.push(h),h.whole)j=!0;else if("natural"==h.mode&&(h.fits||h.size.width<=c.geo.available[k][n].width))return!1}})}}),e.__instance._trigger({edit:function(a){g=a},event:b,helper:c,results:g,type:"positionTested"}),g.sort(function(a,b){if(a.whole&&!b.whole)return-1;if(!a.whole&&b.whole)return 1;if(a.whole&&b.whole){var c=e.__options.side.indexOf(a.side),d=e.__options.side.indexOf(b.side);return d>c?-1:c>d?1:"natural"==a.mode?-1:1}if(a.fits&&!b.fits)return-1;if(!a.fits&&b.fits)return 1;if(a.fits&&b.fits){var c=e.__options.side.indexOf(a.side),d=e.__options.side.indexOf(b.side);return d>c?-1:c>d?1:"natural"==a.mode?-1:1}return"document"==a.container&&"bottom"==a.side&&"natural"==a.mode?-1:1}),d=g[0],d.coord={},d.side){case"left":case"right":d.coord.top=Math.floor(d.target-d.size.height/2);break;case"bottom":case"top":d.coord.left=Math.floor(d.target-d.size.width/2)}switch(d.side){case"left":d.coord.left=c.geo.origin.windowOffset.left-d.outerSize.width;break;case"right":d.coord.left=c.geo.origin.windowOffset.right+d.distance.horizontal;break;case"top":d.coord.top=c.geo.origin.windowOffset.top-d.outerSize.height;break;case"bottom":d.coord.top=c.geo.origin.windowOffset.bottom+d.distance.vertical}"window"==d.container?"top"==d.side||"bottom"==d.side?d.coord.left<0?c.geo.origin.windowOffset.right-this.__options.minIntersection>=0?d.coord.left=0:d.coord.left=c.geo.origin.windowOffset.right-this.__options.minIntersection-1:d.coord.left>c.geo.window.size.width-d.size.width&&(c.geo.origin.windowOffset.left+this.__options.minIntersection<=c.geo.window.size.width?d.coord.left=c.geo.window.size.width-d.size.width:d.coord.left=c.geo.origin.windowOffset.left+this.__options.minIntersection+1-d.size.width):d.coord.top<0?c.geo.origin.windowOffset.bottom-this.__options.minIntersection>=0?d.coord.top=0:d.coord.top=c.geo.origin.windowOffset.bottom-this.__options.minIntersection-1:d.coord.top>c.geo.window.size.height-d.size.height&&(c.geo.origin.windowOffset.top+this.__options.minIntersection<=c.geo.window.size.height?d.coord.top=c.geo.window.size.height-d.size.height:d.coord.top=c.geo.origin.windowOffset.top+this.__options.minIntersection+1-d.size.height):(d.coord.left>c.geo.window.size.width-d.size.width&&(d.coord.left=c.geo.window.size.width-d.size.width),d.coord.left<0&&(d.coord.left=0)),e.__sideChange(h,d.side),c.tooltipClone=h[0],c.tooltipParent=e.__instance.option("parent").parent[0],c.mode=d.mode,c.whole=d.whole,c.origin=e.__instance._$origin[0],c.tooltip=e.__instance._$tooltip[0],delete d.container,delete d.fits,delete d.mode,delete d.outerSize,delete d.whole,d.distance=d.distance.horizontal||d.distance.vertical;var l=a.extend(!0,{},d);if(e.__instance._trigger({edit:function(a){d=a},event:b,helper:c,position:l,type:"position"}),e.__options.functionPosition){var m=e.__options.functionPosition.call(e,e.__instance,c,l);m&&(d=m)}i.destroy();var n,o;"top"==d.side||"bottom"==d.side?(n={prop:"left",val:d.target-d.coord.left},o=d.size.width-this.__options.minIntersection):(n={prop:"top",val:d.target-d.coord.top},o=d.size.height-this.__options.minIntersection),n.valo&&(n.val=o);var p;p=c.geo.origin.fixedLineage?c.geo.origin.windowOffset:{left:c.geo.origin.windowOffset.left+c.geo.window.scroll.left,top:c.geo.origin.windowOffset.top+c.geo.window.scroll.top},d.coord={left:p.left+(d.coord.left-c.geo.origin.windowOffset.left),top:p.top+(d.coord.top-c.geo.origin.windowOffset.top)},e.__sideChange(e.__instance._$tooltip,d.side),c.geo.origin.fixedLineage?e.__instance._$tooltip.css("position","fixed"):e.__instance._$tooltip.css("position",""),e.__instance._$tooltip.css({left:d.coord.left,top:d.coord.top,height:d.size.height,width:d.size.width}).find(".tooltipster-arrow").css({left:"",top:""}).css(n.prop,n.val),e.__instance._$tooltip.appendTo(e.__instance.option("parent")),e.__instance._trigger({type:"repositioned",event:b,position:d})},__sideChange:function(a,b){a.removeClass("tooltipster-bottom").removeClass("tooltipster-left").removeClass("tooltipster-right").removeClass("tooltipster-top").addClass("tooltipster-"+b)},__targetFind:function(a){var b={},c=this.__instance._$origin[0].getClientRects();if(c.length>1){var d=this.__instance._$origin.css("opacity");1==d&&(this.__instance._$origin.css("opacity",.99),c=this.__instance._$origin[0].getClientRects(),this.__instance._$origin.css("opacity",1))}if(c.length<2)b.top=Math.floor(a.geo.origin.windowOffset.left+a.geo.origin.size.width/2),b.bottom=b.top,b.left=Math.floor(a.geo.origin.windowOffset.top+a.geo.origin.size.height/2),b.right=b.left;else{var e=c[0];b.top=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil(c.length/2)-1]:c[0],b.right=Math.floor(e.top+(e.bottom-e.top)/2),e=c[c.length-1],b.bottom=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil((c.length+1)/2)-1]:c[c.length-1],b.left=Math.floor(e.top+(e.bottom-e.top)/2)}return b}}}),a}); \ No newline at end of file diff --git a/frontend/express/public/javascripts/utils/vue/vuedraggable.umd.min.js b/frontend/express/public/javascripts/utils/vue/vuedraggable.umd.min.js index dee16afe98a..1fd7f7cb592 100644 --- a/frontend/express/public/javascripts/utils/vue/vuedraggable.umd.min.js +++ b/frontend/express/public/javascripts/utils/vue/vuedraggable.umd.min.js @@ -1,2 +1,2 @@ (function(t,n){"object"===typeof exports&&"object"===typeof module?module.exports=n(require("sortablejs")):"function"===typeof define&&define.amd?define(["sortablejs"],n):"object"===typeof exports?exports["vuedraggable"]=n(require("sortablejs")):t["vuedraggable"]=n(t["Sortable"])})("undefined"!==typeof self?self:this,function(t){return function(t){var n={};function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:r})},e.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,n){if(1&n&&(t=e(t)),8&n)return t;if(4&n&&"object"===typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(e.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&n&&"string"!=typeof t)for(var o in t)e.d(r,o,function(n){return t[n]}.bind(null,o));return r},e.n=function(t){var n=t&&t.__esModule?function(){return t["default"]}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},e.p="",e(e.s="fb15")}({"02f4":function(t,n,e){var r=e("4588"),o=e("be13");t.exports=function(t){return function(n,e){var i,u,c=String(o(n)),a=r(e),f=c.length;return a<0||a>=f?t?"":void 0:(i=c.charCodeAt(a),i<55296||i>56319||a+1===f||(u=c.charCodeAt(a+1))<56320||u>57343?t?c.charAt(a):i:t?c.slice(a,a+2):u-56320+(i-55296<<10)+65536)}}},"0390":function(t,n,e){"use strict";var r=e("02f4")(!0);t.exports=function(t,n,e){return n+(e?r(t,n).length:1)}},"07e3":function(t,n){var e={}.hasOwnProperty;t.exports=function(t,n){return e.call(t,n)}},"0bfb":function(t,n,e){"use strict";var r=e("cb7c");t.exports=function(){var t=r(this),n="";return t.global&&(n+="g"),t.ignoreCase&&(n+="i"),t.multiline&&(n+="m"),t.unicode&&(n+="u"),t.sticky&&(n+="y"),n}},"0fc9":function(t,n,e){var r=e("3a38"),o=Math.max,i=Math.min;t.exports=function(t,n){return t=r(t),t<0?o(t+n,0):i(t,n)}},1654:function(t,n,e){"use strict";var r=e("71c1")(!0);e("30f1")(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,e=this._i;return e>=n.length?{value:void 0,done:!0}:(t=r(n,e),this._i+=t.length,{value:t,done:!1})})},1691:function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},"1af6":function(t,n,e){var r=e("63b6");r(r.S,"Array",{isArray:e("9003")})},"1bc3":function(t,n,e){var r=e("f772");t.exports=function(t,n){if(!r(t))return t;var e,o;if(n&&"function"==typeof(e=t.toString)&&!r(o=e.call(t)))return o;if("function"==typeof(e=t.valueOf)&&!r(o=e.call(t)))return o;if(!n&&"function"==typeof(e=t.toString)&&!r(o=e.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},"1ec9":function(t,n,e){var r=e("f772"),o=e("e53d").document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},"20fd":function(t,n,e){"use strict";var r=e("d9f6"),o=e("aebd");t.exports=function(t,n,e){n in t?r.f(t,n,o(0,e)):t[n]=e}},"214f":function(t,n,e){"use strict";e("b0c5");var r=e("2aba"),o=e("32e9"),i=e("79e5"),u=e("be13"),c=e("2b4c"),a=e("520a"),f=c("species"),s=!i(function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")}),l=function(){var t=/(?:)/,n=t.exec;t.exec=function(){return n.apply(this,arguments)};var e="ab".split(t);return 2===e.length&&"a"===e[0]&&"b"===e[1]}();t.exports=function(t,n,e){var p=c(t),d=!i(function(){var n={};return n[p]=function(){return 7},7!=""[t](n)}),v=d?!i(function(){var n=!1,e=/a/;return e.exec=function(){return n=!0,null},"split"===t&&(e.constructor={},e.constructor[f]=function(){return e}),e[p](""),!n}):void 0;if(!d||!v||"replace"===t&&!s||"split"===t&&!l){var h=/./[p],b=e(u,p,""[t],function(t,n,e,r,o){return n.exec===a?d&&!o?{done:!0,value:h.call(n,e,r)}:{done:!0,value:t.call(e,n,r)}:{done:!1}}),g=b[0],y=b[1];r(String.prototype,t,g),o(RegExp.prototype,p,2==n?function(t,n){return y.call(t,this,n)}:function(t){return y.call(t,this)})}}},"230e":function(t,n,e){var r=e("d3f4"),o=e("7726").document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},"23c6":function(t,n,e){var r=e("2d95"),o=e("2b4c")("toStringTag"),i="Arguments"==r(function(){return arguments}()),u=function(t,n){try{return t[n]}catch(e){}};t.exports=function(t){var n,e,c;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(e=u(n=Object(t),o))?e:i?r(n):"Object"==(c=r(n))&&"function"==typeof n.callee?"Arguments":c}},"241e":function(t,n,e){var r=e("25eb");t.exports=function(t){return Object(r(t))}},"25eb":function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},"294c":function(t,n){t.exports=function(t){try{return!!t()}catch(n){return!0}}},"2aba":function(t,n,e){var r=e("7726"),o=e("32e9"),i=e("69a8"),u=e("ca5a")("src"),c=e("fa5b"),a="toString",f=(""+c).split(a);e("8378").inspectSource=function(t){return c.call(t)},(t.exports=function(t,n,e,c){var a="function"==typeof e;a&&(i(e,"name")||o(e,"name",n)),t[n]!==e&&(a&&(i(e,u)||o(e,u,t[n]?""+t[n]:f.join(String(n)))),t===r?t[n]=e:c?t[n]?t[n]=e:o(t,n,e):(delete t[n],o(t,n,e)))})(Function.prototype,a,function(){return"function"==typeof this&&this[u]||c.call(this)})},"2b4c":function(t,n,e){var r=e("5537")("wks"),o=e("ca5a"),i=e("7726").Symbol,u="function"==typeof i,c=t.exports=function(t){return r[t]||(r[t]=u&&i[t]||(u?i:o)("Symbol."+t))};c.store=r},"2d00":function(t,n){t.exports=!1},"2d95":function(t,n){var e={}.toString;t.exports=function(t){return e.call(t).slice(8,-1)}},"2fdb":function(t,n,e){"use strict";var r=e("5ca1"),o=e("d2c8"),i="includes";r(r.P+r.F*e("5147")(i),"String",{includes:function(t){return!!~o(this,t,i).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},"30f1":function(t,n,e){"use strict";var r=e("b8e3"),o=e("63b6"),i=e("9138"),u=e("35e8"),c=e("481b"),a=e("8f60"),f=e("45f2"),s=e("53e2"),l=e("5168")("iterator"),p=!([].keys&&"next"in[].keys()),d="@@iterator",v="keys",h="values",b=function(){return this};t.exports=function(t,n,e,g,y,x,m){a(e,n,g);var w,O,S,j=function(t){if(!p&&t in C)return C[t];switch(t){case v:return function(){return new e(this,t)};case h:return function(){return new e(this,t)}}return function(){return new e(this,t)}},_=n+" Iterator",M=y==h,T=!1,C=t.prototype,E=C[l]||C[d]||y&&C[y],A=E||j(y),P=y?M?j("entries"):A:void 0,I="Array"==n&&C.entries||E;if(I&&(S=s(I.call(new t)),S!==Object.prototype&&S.next&&(f(S,_,!0),r||"function"==typeof S[l]||u(S,l,b))),M&&E&&E.name!==h&&(T=!0,A=function(){return E.call(this)}),r&&!m||!p&&!T&&C[l]||u(C,l,A),c[n]=A,c[_]=b,y)if(w={values:M?A:j(h),keys:x?A:j(v),entries:P},m)for(O in w)O in C||i(C,O,w[O]);else o(o.P+o.F*(p||T),n,w);return w}},"32a6":function(t,n,e){var r=e("241e"),o=e("c3a1");e("ce7e")("keys",function(){return function(t){return o(r(t))}})},"32e9":function(t,n,e){var r=e("86cc"),o=e("4630");t.exports=e("9e1e")?function(t,n,e){return r.f(t,n,o(1,e))}:function(t,n,e){return t[n]=e,t}},"32fc":function(t,n,e){var r=e("e53d").document;t.exports=r&&r.documentElement},"335c":function(t,n,e){var r=e("6b4c");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},"355d":function(t,n){n.f={}.propertyIsEnumerable},"35e8":function(t,n,e){var r=e("d9f6"),o=e("aebd");t.exports=e("8e60")?function(t,n,e){return r.f(t,n,o(1,e))}:function(t,n,e){return t[n]=e,t}},"36c3":function(t,n,e){var r=e("335c"),o=e("25eb");t.exports=function(t){return r(o(t))}},3702:function(t,n,e){var r=e("481b"),o=e("5168")("iterator"),i=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||i[o]===t)}},"3a38":function(t,n){var e=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:e)(t)}},"40c3":function(t,n,e){var r=e("6b4c"),o=e("5168")("toStringTag"),i="Arguments"==r(function(){return arguments}()),u=function(t,n){try{return t[n]}catch(e){}};t.exports=function(t){var n,e,c;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(e=u(n=Object(t),o))?e:i?r(n):"Object"==(c=r(n))&&"function"==typeof n.callee?"Arguments":c}},4588:function(t,n){var e=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:e)(t)}},"45f2":function(t,n,e){var r=e("d9f6").f,o=e("07e3"),i=e("5168")("toStringTag");t.exports=function(t,n,e){t&&!o(t=e?t:t.prototype,i)&&r(t,i,{configurable:!0,value:n})}},4630:function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},"469f":function(t,n,e){e("6c1c"),e("1654"),t.exports=e("7d7b")},"481b":function(t,n){t.exports={}},"4aa6":function(t,n,e){t.exports=e("dc62")},"4bf8":function(t,n,e){var r=e("be13");t.exports=function(t){return Object(r(t))}},"4ee1":function(t,n,e){var r=e("5168")("iterator"),o=!1;try{var i=[7][r]();i["return"]=function(){o=!0},Array.from(i,function(){throw 2})}catch(u){}t.exports=function(t,n){if(!n&&!o)return!1;var e=!1;try{var i=[7],c=i[r]();c.next=function(){return{done:e=!0}},i[r]=function(){return c},t(i)}catch(u){}return e}},"50ed":function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},5147:function(t,n,e){var r=e("2b4c")("match");t.exports=function(t){var n=/./;try{"/./"[t](n)}catch(e){try{return n[r]=!1,!"/./"[t](n)}catch(o){}}return!0}},5168:function(t,n,e){var r=e("dbdb")("wks"),o=e("62a0"),i=e("e53d").Symbol,u="function"==typeof i,c=t.exports=function(t){return r[t]||(r[t]=u&&i[t]||(u?i:o)("Symbol."+t))};c.store=r},5176:function(t,n,e){t.exports=e("51b6")},"51b6":function(t,n,e){e("a3c3"),t.exports=e("584a").Object.assign},"520a":function(t,n,e){"use strict";var r=e("0bfb"),o=RegExp.prototype.exec,i=String.prototype.replace,u=o,c="lastIndex",a=function(){var t=/a/,n=/b*/g;return o.call(t,"a"),o.call(n,"a"),0!==t[c]||0!==n[c]}(),f=void 0!==/()??/.exec("")[1],s=a||f;s&&(u=function(t){var n,e,u,s,l=this;return f&&(e=new RegExp("^"+l.source+"$(?!\\s)",r.call(l))),a&&(n=l[c]),u=o.call(l,t),a&&u&&(l[c]=l.global?u.index+u[0].length:n),f&&u&&u.length>1&&i.call(u[0],e,function(){for(s=1;s1?arguments[1]:void 0,b=void 0!==h,g=0,y=s(p);if(b&&(h=r(h,v>2?arguments[2]:void 0,2)),void 0==y||d==Array&&c(y))for(n=a(p.length),e=new d(n);n>g;g++)f(e,g,b?h(p[g],g):p[g]);else for(l=y.call(p),e=new d;!(o=l.next()).done;g++)f(e,g,b?u(l,h,[o.value,g],!0):o.value);return e.length=g,e}})},"54a1":function(t,n,e){e("6c1c"),e("1654"),t.exports=e("95d5")},5537:function(t,n,e){var r=e("8378"),o=e("7726"),i="__core-js_shared__",u=o[i]||(o[i]={});(t.exports=function(t,n){return u[t]||(u[t]=void 0!==n?n:{})})("versions",[]).push({version:r.version,mode:e("2d00")?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},5559:function(t,n,e){var r=e("dbdb")("keys"),o=e("62a0");t.exports=function(t){return r[t]||(r[t]=o(t))}},"584a":function(t,n){var e=t.exports={version:"2.6.5"};"number"==typeof __e&&(__e=e)},"5b4e":function(t,n,e){var r=e("36c3"),o=e("b447"),i=e("0fc9");t.exports=function(t){return function(n,e,u){var c,a=r(n),f=o(a.length),s=i(u,f);if(t&&e!=e){while(f>s)if(c=a[s++],c!=c)return!0}else for(;f>s;s++)if((t||s in a)&&a[s]===e)return t||s||0;return!t&&-1}}},"5ca1":function(t,n,e){var r=e("7726"),o=e("8378"),i=e("32e9"),u=e("2aba"),c=e("9b43"),a="prototype",f=function(t,n,e){var s,l,p,d,v=t&f.F,h=t&f.G,b=t&f.S,g=t&f.P,y=t&f.B,x=h?r:b?r[n]||(r[n]={}):(r[n]||{})[a],m=h?o:o[n]||(o[n]={}),w=m[a]||(m[a]={});for(s in h&&(e=n),e)l=!v&&x&&void 0!==x[s],p=(l?x:e)[s],d=y&&l?c(p,r):g&&"function"==typeof p?c(Function.call,p):p,x&&u(x,s,p,t&f.U),m[s]!=p&&i(m,s,d),g&&w[s]!=p&&(w[s]=p)};r.core=o,f.F=1,f.G=2,f.S=4,f.P=8,f.B=16,f.W=32,f.U=64,f.R=128,t.exports=f},"5d73":function(t,n,e){t.exports=e("469f")},"5f1b":function(t,n,e){"use strict";var r=e("23c6"),o=RegExp.prototype.exec;t.exports=function(t,n){var e=t.exec;if("function"===typeof e){var i=e.call(t,n);if("object"!==typeof i)throw new TypeError("RegExp exec method returned something other than an Object or null");return i}if("RegExp"!==r(t))throw new TypeError("RegExp#exec called on incompatible receiver");return o.call(t,n)}},"626a":function(t,n,e){var r=e("2d95");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},"62a0":function(t,n){var e=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++e+r).toString(36))}},"63b6":function(t,n,e){var r=e("e53d"),o=e("584a"),i=e("d864"),u=e("35e8"),c=e("07e3"),a="prototype",f=function(t,n,e){var s,l,p,d=t&f.F,v=t&f.G,h=t&f.S,b=t&f.P,g=t&f.B,y=t&f.W,x=v?o:o[n]||(o[n]={}),m=x[a],w=v?r:h?r[n]:(r[n]||{})[a];for(s in v&&(e=n),e)l=!d&&w&&void 0!==w[s],l&&c(x,s)||(p=l?w[s]:e[s],x[s]=v&&"function"!=typeof w[s]?e[s]:g&&l?i(p,r):y&&w[s]==p?function(t){var n=function(n,e,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(n);case 2:return new t(n,e)}return new t(n,e,r)}return t.apply(this,arguments)};return n[a]=t[a],n}(p):b&&"function"==typeof p?i(Function.call,p):p,b&&((x.virtual||(x.virtual={}))[s]=p,t&f.R&&m&&!m[s]&&u(m,s,p)))};f.F=1,f.G=2,f.S=4,f.P=8,f.B=16,f.W=32,f.U=64,f.R=128,t.exports=f},6762:function(t,n,e){"use strict";var r=e("5ca1"),o=e("c366")(!0);r(r.P,"Array",{includes:function(t){return o(this,t,arguments.length>1?arguments[1]:void 0)}}),e("9c6c")("includes")},6821:function(t,n,e){var r=e("626a"),o=e("be13");t.exports=function(t){return r(o(t))}},"69a8":function(t,n){var e={}.hasOwnProperty;t.exports=function(t,n){return e.call(t,n)}},"6a99":function(t,n,e){var r=e("d3f4");t.exports=function(t,n){if(!r(t))return t;var e,o;if(n&&"function"==typeof(e=t.toString)&&!r(o=e.call(t)))return o;if("function"==typeof(e=t.valueOf)&&!r(o=e.call(t)))return o;if(!n&&"function"==typeof(e=t.toString)&&!r(o=e.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},"6b4c":function(t,n){var e={}.toString;t.exports=function(t){return e.call(t).slice(8,-1)}},"6c1c":function(t,n,e){e("c367");for(var r=e("e53d"),o=e("35e8"),i=e("481b"),u=e("5168")("toStringTag"),c="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),a=0;a=f?t?"":void 0:(i=c.charCodeAt(a),i<55296||i>56319||a+1===f||(u=c.charCodeAt(a+1))<56320||u>57343?t?c.charAt(a):i:t?c.slice(a,a+2):u-56320+(i-55296<<10)+65536)}}},7726:function(t,n){var e=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)},"774e":function(t,n,e){t.exports=e("d2d5")},"77f1":function(t,n,e){var r=e("4588"),o=Math.max,i=Math.min;t.exports=function(t,n){return t=r(t),t<0?o(t+n,0):i(t,n)}},"794b":function(t,n,e){t.exports=!e("8e60")&&!e("294c")(function(){return 7!=Object.defineProperty(e("1ec9")("div"),"a",{get:function(){return 7}}).a})},"79aa":function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},"79e5":function(t,n){t.exports=function(t){try{return!!t()}catch(n){return!0}}},"7cd6":function(t,n,e){var r=e("40c3"),o=e("5168")("iterator"),i=e("481b");t.exports=e("584a").getIteratorMethod=function(t){if(void 0!=t)return t[o]||t["@@iterator"]||i[r(t)]}},"7d7b":function(t,n,e){var r=e("e4ae"),o=e("7cd6");t.exports=e("584a").getIterator=function(t){var n=o(t);if("function"!=typeof n)throw TypeError(t+" is not iterable!");return r(n.call(t))}},"7e90":function(t,n,e){var r=e("d9f6"),o=e("e4ae"),i=e("c3a1");t.exports=e("8e60")?Object.defineProperties:function(t,n){o(t);var e,u=i(n),c=u.length,a=0;while(c>a)r.f(t,e=u[a++],n[e]);return t}},8378:function(t,n){var e=t.exports={version:"2.6.5"};"number"==typeof __e&&(__e=e)},8436:function(t,n){t.exports=function(){}},"86cc":function(t,n,e){var r=e("cb7c"),o=e("c69a"),i=e("6a99"),u=Object.defineProperty;n.f=e("9e1e")?Object.defineProperty:function(t,n,e){if(r(t),n=i(n,!0),r(e),o)try{return u(t,n,e)}catch(c){}if("get"in e||"set"in e)throw TypeError("Accessors not supported!");return"value"in e&&(t[n]=e.value),t}},"8aae":function(t,n,e){e("32a6"),t.exports=e("584a").Object.keys},"8e60":function(t,n,e){t.exports=!e("294c")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},"8f60":function(t,n,e){"use strict";var r=e("a159"),o=e("aebd"),i=e("45f2"),u={};e("35e8")(u,e("5168")("iterator"),function(){return this}),t.exports=function(t,n,e){t.prototype=r(u,{next:o(1,e)}),i(t,n+" Iterator")}},9003:function(t,n,e){var r=e("6b4c");t.exports=Array.isArray||function(t){return"Array"==r(t)}},9138:function(t,n,e){t.exports=e("35e8")},9306:function(t,n,e){"use strict";var r=e("c3a1"),o=e("9aa9"),i=e("355d"),u=e("241e"),c=e("335c"),a=Object.assign;t.exports=!a||e("294c")(function(){var t={},n={},e=Symbol(),r="abcdefghijklmnopqrst";return t[e]=7,r.split("").forEach(function(t){n[t]=t}),7!=a({},t)[e]||Object.keys(a({},n)).join("")!=r})?function(t,n){var e=u(t),a=arguments.length,f=1,s=o.f,l=i.f;while(a>f){var p,d=c(arguments[f++]),v=s?r(d).concat(s(d)):r(d),h=v.length,b=0;while(h>b)l.call(d,p=v[b++])&&(e[p]=d[p])}return e}:a},9427:function(t,n,e){var r=e("63b6");r(r.S,"Object",{create:e("a159")})},"95d5":function(t,n,e){var r=e("40c3"),o=e("5168")("iterator"),i=e("481b");t.exports=e("584a").isIterable=function(t){var n=Object(t);return void 0!==n[o]||"@@iterator"in n||i.hasOwnProperty(r(n))}},"9aa9":function(t,n){n.f=Object.getOwnPropertySymbols},"9b43":function(t,n,e){var r=e("d8e8");t.exports=function(t,n,e){if(r(t),void 0===n)return t;switch(e){case 1:return function(e){return t.call(n,e)};case 2:return function(e,r){return t.call(n,e,r)};case 3:return function(e,r,o){return t.call(n,e,r,o)}}return function(){return t.apply(n,arguments)}}},"9c6c":function(t,n,e){var r=e("2b4c")("unscopables"),o=Array.prototype;void 0==o[r]&&e("32e9")(o,r,{}),t.exports=function(t){o[r][t]=!0}},"9def":function(t,n,e){var r=e("4588"),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},"9e1e":function(t,n,e){t.exports=!e("79e5")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},a159:function(t,n,e){var r=e("e4ae"),o=e("7e90"),i=e("1691"),u=e("5559")("IE_PROTO"),c=function(){},a="prototype",f=function(){var t,n=e("1ec9")("iframe"),r=i.length,o="<",u=">";n.style.display="none",e("32fc").appendChild(n),n.src="javascript:",t=n.contentWindow.document,t.open(),t.write(o+"script"+u+"document.F=Object"+o+"/script"+u),t.close(),f=t.F;while(r--)delete f[a][i[r]];return f()};t.exports=Object.create||function(t,n){var e;return null!==t?(c[a]=r(t),e=new c,c[a]=null,e[u]=t):e=f(),void 0===n?e:o(e,n)}},a352:function(n,e){n.exports=t},a3c3:function(t,n,e){var r=e("63b6");r(r.S+r.F,"Object",{assign:e("9306")})},a481:function(t,n,e){"use strict";var r=e("cb7c"),o=e("4bf8"),i=e("9def"),u=e("4588"),c=e("0390"),a=e("5f1b"),f=Math.max,s=Math.min,l=Math.floor,p=/\$([$&`']|\d\d?|<[^>]*>)/g,d=/\$([$&`']|\d\d?)/g,v=function(t){return void 0===t?t:String(t)};e("214f")("replace",2,function(t,n,e,h){return[function(r,o){var i=t(this),u=void 0==r?void 0:r[n];return void 0!==u?u.call(r,i,o):e.call(String(i),r,o)},function(t,n){var o=h(e,t,this,n);if(o.done)return o.value;var l=r(t),p=String(this),d="function"===typeof n;d||(n=String(n));var g=l.global;if(g){var y=l.unicode;l.lastIndex=0}var x=[];while(1){var m=a(l,p);if(null===m)break;if(x.push(m),!g)break;var w=String(m[0]);""===w&&(l.lastIndex=c(p,i(l.lastIndex),y))}for(var O="",S=0,j=0;j=S&&(O+=p.slice(S,M)+P,S=M+_.length)}return O+p.slice(S)}];function b(t,n,r,i,u,c){var a=r+t.length,f=i.length,s=d;return void 0!==u&&(u=o(u),s=p),e.call(c,s,function(e,o){var c;switch(o.charAt(0)){case"$":return"$";case"&":return t;case"`":return n.slice(0,r);case"'":return n.slice(a);case"<":c=u[o.slice(1,-1)];break;default:var s=+o;if(0===s)return e;if(s>f){var p=l(s/10);return 0===p?e:p<=f?void 0===i[p-1]?o.charAt(1):i[p-1]+o.charAt(1):e}c=i[s-1]}return void 0===c?"":c})}})},a4bb:function(t,n,e){t.exports=e("8aae")},a745:function(t,n,e){t.exports=e("f410")},aae3:function(t,n,e){var r=e("d3f4"),o=e("2d95"),i=e("2b4c")("match");t.exports=function(t){var n;return r(t)&&(void 0!==(n=t[i])?!!n:"RegExp"==o(t))}},aebd:function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},b0c5:function(t,n,e){"use strict";var r=e("520a");e("5ca1")({target:"RegExp",proto:!0,forced:r!==/./.exec},{exec:r})},b0dc:function(t,n,e){var r=e("e4ae");t.exports=function(t,n,e,o){try{return o?n(r(e)[0],e[1]):n(e)}catch(u){var i=t["return"];throw void 0!==i&&r(i.call(t)),u}}},b447:function(t,n,e){var r=e("3a38"),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},b8e3:function(t,n){t.exports=!0},be13:function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},c366:function(t,n,e){var r=e("6821"),o=e("9def"),i=e("77f1");t.exports=function(t){return function(n,e,u){var c,a=r(n),f=o(a.length),s=i(u,f);if(t&&e!=e){while(f>s)if(c=a[s++],c!=c)return!0}else for(;f>s;s++)if((t||s in a)&&a[s]===e)return t||s||0;return!t&&-1}}},c367:function(t,n,e){"use strict";var r=e("8436"),o=e("50ed"),i=e("481b"),u=e("36c3");t.exports=e("30f1")(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,e=this._i++;return!t||e>=t.length?(this._t=void 0,o(1)):o(0,"keys"==n?e:"values"==n?t[e]:[e,t[e]])},"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},c3a1:function(t,n,e){var r=e("e6f3"),o=e("1691");t.exports=Object.keys||function(t){return r(t,o)}},c649:function(t,n,e){"use strict";(function(t){e.d(n,"c",function(){return l}),e.d(n,"a",function(){return f}),e.d(n,"b",function(){return u}),e.d(n,"d",function(){return s});e("a481");var r=e("4aa6"),o=e.n(r);function i(){return"undefined"!==typeof window?window.console:t.console}var u=i();function c(t){var n=o()(null);return function(e){var r=n[e];return r||(n[e]=t(e))}}var a=/-(\w)/g,f=c(function(t){return t.replace(a,function(t,n){return n?n.toUpperCase():""})});function s(t){null!==t.parentElement&&t.parentElement.removeChild(t)}function l(t,n,e){var r=0===e?t.children[0]:t.children[e-1].nextSibling;t.insertBefore(n,r)}}).call(this,e("c8ba"))},c69a:function(t,n,e){t.exports=!e("9e1e")&&!e("79e5")(function(){return 7!=Object.defineProperty(e("230e")("div"),"a",{get:function(){return 7}}).a})},c8ba:function(t,n){var e;e=function(){return this}();try{e=e||new Function("return this")()}catch(r){"object"===typeof window&&(e=window)}t.exports=e},c8bb:function(t,n,e){t.exports=e("54a1")},ca5a:function(t,n){var e=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++e+r).toString(36))}},cb7c:function(t,n,e){var r=e("d3f4");t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},ce7e:function(t,n,e){var r=e("63b6"),o=e("584a"),i=e("294c");t.exports=function(t,n){var e=(o.Object||{})[t]||Object[t],u={};u[t]=n(e),r(r.S+r.F*i(function(){e(1)}),"Object",u)}},d2c8:function(t,n,e){var r=e("aae3"),o=e("be13");t.exports=function(t,n,e){if(r(n))throw TypeError("String#"+e+" doesn't accept regex!");return String(o(t))}},d2d5:function(t,n,e){e("1654"),e("549b"),t.exports=e("584a").Array.from},d3f4:function(t,n){t.exports=function(t){return"object"===typeof t?null!==t:"function"===typeof t}},d864:function(t,n,e){var r=e("79aa");t.exports=function(t,n,e){if(r(t),void 0===n)return t;switch(e){case 1:return function(e){return t.call(n,e)};case 2:return function(e,r){return t.call(n,e,r)};case 3:return function(e,r,o){return t.call(n,e,r,o)}}return function(){return t.apply(n,arguments)}}},d8e8:function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},d9f6:function(t,n,e){var r=e("e4ae"),o=e("794b"),i=e("1bc3"),u=Object.defineProperty;n.f=e("8e60")?Object.defineProperty:function(t,n,e){if(r(t),n=i(n,!0),r(e),o)try{return u(t,n,e)}catch(c){}if("get"in e||"set"in e)throw TypeError("Accessors not supported!");return"value"in e&&(t[n]=e.value),t}},dbdb:function(t,n,e){var r=e("584a"),o=e("e53d"),i="__core-js_shared__",u=o[i]||(o[i]={});(t.exports=function(t,n){return u[t]||(u[t]=void 0!==n?n:{})})("versions",[]).push({version:r.version,mode:e("b8e3")?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},dc62:function(t,n,e){e("9427");var r=e("584a").Object;t.exports=function(t,n){return r.create(t,n)}},e4ae:function(t,n,e){var r=e("f772");t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},e53d:function(t,n){var e=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)},e6f3:function(t,n,e){var r=e("07e3"),o=e("36c3"),i=e("5b4e")(!1),u=e("5559")("IE_PROTO");t.exports=function(t,n){var e,c=o(t),a=0,f=[];for(e in c)e!=u&&r(c,e)&&f.push(e);while(n.length>a)r(c,e=n[a++])&&(~i(f,e)||f.push(e));return f}},f410:function(t,n,e){e("1af6"),t.exports=e("584a").Array.isArray},f559:function(t,n,e){"use strict";var r=e("5ca1"),o=e("9def"),i=e("d2c8"),u="startsWith",c=""[u];r(r.P+r.F*e("5147")(u),"String",{startsWith:function(t){var n=i(this,t,u),e=o(Math.min(arguments.length>1?arguments[1]:void 0,n.length)),r=String(t);return c?c.call(n,r,e):n.slice(e,e+r.length)===r}})},f772:function(t,n){t.exports=function(t){return"object"===typeof t?null!==t:"function"===typeof t}},fa5b:function(t,n,e){t.exports=e("5537")("native-function-to-string",Function.toString)},fb15:function(t,n,e){"use strict";var r;(e.r(n),"undefined"!==typeof window)&&((r=window.document.currentScript)&&(r=r.src.match(/(.+\/)[^\/]+\.js(\?.*)?$/))&&(e.p=r[1]));var o=e("5176"),i=e.n(o),u=(e("f559"),e("a4bb")),c=e.n(u),a=(e("6762"),e("2fdb"),e("a745")),f=e.n(a);function s(t){if(f()(t))return t}var l=e("5d73"),p=e.n(l);function d(t,n){var e=[],r=!0,o=!1,i=void 0;try{for(var u,c=p()(t);!(r=(u=c.next()).done);r=!0)if(e.push(u.value),n&&e.length===n)break}catch(a){o=!0,i=a}finally{try{r||null==c["return"]||c["return"]()}finally{if(o)throw i}}return e}function v(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function h(t,n){return s(t)||d(t,n)||v()}function b(t){if(f()(t)){for(var n=0,e=new Array(t.length);n=i?o.length:o.indexOf(t)});return e?u.filter(function(t){return-1!==t}):u}function A(t,n){var e=this;this.$nextTick(function(){return e.$emit(t.toLowerCase(),n)})}function P(t){var n=this;return function(e){null!==n.realList&&n["onDrag"+t](e),A.call(n,t,e)}}function I(t){if(!t||1!==t.length)return!1;var n=h(t,1),e=n[0].componentOptions;return!!e&&["transition-group","TransitionGroup"].includes(e.tag)}function L(t,n){var e=n.header,r=n.footer,o=0,i=0;return e&&(o=e.length,t=t?[].concat(S(e),S(t)):S(e)),r&&(i=r.length,t=t?[].concat(S(t),S(r)):S(r)),{children:t,headerOffset:o,footerOffset:i}}function F(t,n){var e=null,r=function(t,n){e=T(e,t,n)},o=c()(t).filter(function(t){return"id"===t||t.startsWith("data-")}).reduce(function(n,e){return n[e]=t[e],n},{});if(r("attrs",o),!n)return e;var u=n.on,a=n.props,f=n.attrs;return r("on",u),r("props",a),i()(e.attrs,f),e}var $=["Start","Add","Remove","Update","End"],k=["Choose","Sort","Filter","Clone"],D=["Move"].concat($,k).map(function(t){return"on"+t}),R=null,V={options:Object,list:{type:Array,required:!1,default:null},value:{type:Array,required:!1,default:null},noTransitionOnDrag:{type:Boolean,default:!1},clone:{type:Function,default:function(t){return t}},element:{type:String,default:"div"},tag:{type:String,default:null},move:{type:Function,default:null},componentData:{type:Object,required:!1,default:null}},N={name:"draggable",inheritAttrs:!1,props:V,data:function(){return{transitionMode:!1,noneFunctionalComponentMode:!1,init:!1}},render:function(t){var n=this.$slots.default;this.transitionMode=I(n);var e=L(n,this.$slots),r=e.children,o=e.headerOffset,i=e.footerOffset;this.headerOffset=o,this.footerOffset=i;var u=F(this.$attrs,this.componentData);return t(this.getTag(),u,r)},created:function(){null!==this.list&&null!==this.value&&M["b"].error("Value and list props are mutually exclusive! Please set one or another."),"div"!==this.element&&M["b"].warn("Element props is deprecated please use tag props instead. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#element-props"),void 0!==this.options&&M["b"].warn("Options props is deprecated, add sortable options directly as vue.draggable item, or use v-bind. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#options-props")},mounted:function(){var t=this;if(this.noneFunctionalComponentMode=this.getTag().toLowerCase()!==this.$el.nodeName.toLowerCase(),this.noneFunctionalComponentMode&&this.transitionMode)throw new Error("Transition-group inside component is not supported. Please alter tag value or remove transition-group. Current tag value: ".concat(this.getTag()));var n={};$.forEach(function(e){n["on"+e]=P.call(t,e)}),k.forEach(function(e){n["on"+e]=A.bind(t,e)});var e=c()(this.$attrs).reduce(function(n,e){return n[Object(M["a"])(e)]=t.$attrs[e],n},{}),r=i()({},this.options,e,n,{onMove:function(n,e){return t.onDragMove(n,e)}});!("draggable"in r)&&(r.draggable=">*"),this._sortable=new _.a(this.rootContainer,r),this.computeIndexes()},beforeDestroy:function(){void 0!==this._sortable&&this._sortable.destroy()},computed:{rootContainer:function(){return this.transitionMode?this.$el.children[0]:this.$el},realList:function(){return this.list?this.list:this.value}},watch:{options:{handler:function(t){this.updateOptions(t)},deep:!0},$attrs:{handler:function(t){this.updateOptions(t)},deep:!0},realList:function(){this.computeIndexes()}},methods:{getTag:function(){return this.tag||this.element},updateOptions:function(t){for(var n in t){var e=Object(M["a"])(n);-1===D.indexOf(e)&&this._sortable.option(e,t[n])}},getChildrenNodes:function(){if(this.init||(this.noneFunctionalComponentMode=this.noneFunctionalComponentMode&&1===this.$children.length,this.init=!0),this.noneFunctionalComponentMode)return this.$children[0].$slots.default;var t=this.$slots.default;return this.transitionMode?t[0].child.$slots.default:t},computeIndexes:function(){var t=this;this.$nextTick(function(){t.visibleIndexes=E(t.getChildrenNodes(),t.rootContainer.children,t.transitionMode,t.footerOffset)})},getUnderlyingVm:function(t){var n=C(this.getChildrenNodes()||[],t);if(-1===n)return null;var e=this.realList[n];return{index:n,element:e}},getUnderlyingPotencialDraggableComponent:function(t){var n=t.__vue__;return n&&n.$options&&"transition-group"===n.$options._componentTag?n.$parent:n},emitChanges:function(t){var n=this;this.$nextTick(function(){n.$emit("change",t)})},alterList:function(t){if(this.list)t(this.list);else{var n=S(this.value);t(n),this.$emit("input",n)}},spliceList:function(){var t=arguments,n=function(n){return n.splice.apply(n,S(t))};this.alterList(n)},updatePosition:function(t,n){var e=function(e){return e.splice(n,0,e.splice(t,1)[0])};this.alterList(e)},getRelatedContextFromMoveEvent:function(t){var n=t.to,e=t.related,r=this.getUnderlyingPotencialDraggableComponent(n);if(!r)return{component:r};var o=r.realList,u={list:o,component:r};if(n!==e&&o&&r.getUnderlyingVm){var c=r.getUnderlyingVm(e);if(c)return i()(c,u)}return u},getVmIndex:function(t){var n=this.visibleIndexes,e=n.length;return t>e-1?e:n[t]},getComponent:function(){return this.$slots.default[0].componentInstance},resetTransitionData:function(t){if(this.noTransitionOnDrag&&this.transitionMode){var n=this.getChildrenNodes();n[t].data=null;var e=this.getComponent();e.children=[],e.kept=void 0}},onDragStart:function(t){this.context=this.getUnderlyingVm(t.item),t.item._underlying_vm_=this.clone(this.context.element),R=t.item},onDragAdd:function(t){var n=t.item._underlying_vm_;if(void 0!==n){Object(M["d"])(t.item);var e=this.getVmIndex(t.newIndex);this.spliceList(e,0,n),this.computeIndexes();var r={element:n,newIndex:e};this.emitChanges({added:r})}},onDragRemove:function(t){if(Object(M["c"])(this.rootContainer,t.item,t.oldIndex),"clone"!==t.pullMode){var n=this.context.index;this.spliceList(n,1);var e={element:this.context.element,oldIndex:n};this.resetTransitionData(n),this.emitChanges({removed:e})}else Object(M["d"])(t.clone)},onDragUpdate:function(t){Object(M["d"])(t.item),Object(M["c"])(t.from,t.item,t.oldIndex);var n=this.context.index,e=this.getVmIndex(t.newIndex);this.updatePosition(n,e);var r={element:this.context.element,oldIndex:n,newIndex:e};this.emitChanges({moved:r})},updateProperty:function(t,n){t.hasOwnProperty(n)&&(t[n]+=this.headerOffset)},computeFutureIndex:function(t,n){if(!t.element)return 0;var e=S(n.to.children).filter(function(t){return"none"!==t.style["display"]}),r=e.indexOf(n.related),o=t.component.getVmIndex(r),i=-1!==e.indexOf(R);return i||!n.willInsertAfter?o:o+1},onDragMove:function(t,n){var e=this.move;if(!e||!this.realList)return!0;var r=this.getRelatedContextFromMoveEvent(t),o=this.context,u=this.computeFutureIndex(r,t);i()(o,{futureIndex:u});var c=i()({},t,{relatedContext:r,draggedContext:o});return e(c,n)},onDragEnd:function(){this.computeIndexes(),R=null}}};"undefined"!==typeof window&&"Vue"in window&&window.Vue.component("draggable",N);var U=N;n["default"]=U}})["default"]}); -//# sourceMappingURL=vuedraggable.umd.min.js.map \ No newline at end of file +//# sourceMappingURL=vuedraggable.umd.min.js.map diff --git a/frontend/express/public/javascripts/visualization/d3/d3.min.js b/frontend/express/public/javascripts/visualization/d3/d3.min.js deleted file mode 100644 index 1984d1723f2..00000000000 --- a/frontend/express/public/javascripts/visualization/d3/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(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 o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(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 Z(n){return ya(n,Sa),n}function V(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=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(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 B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(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 mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))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(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.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 _t(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 at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){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 void o.error.call(i,r)}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!this.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(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=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)}:y;return function(n){var e=ic.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=oc.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 cc(e-1)),1),e}function i(n,e){return t(n=new cc(+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{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=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{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=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 sc?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{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(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 It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(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 It(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 Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.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=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.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);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.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]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}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:b,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]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-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?qa:-qa,c=ga(i-e);ga(c-qa)0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)Ca?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*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){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+qa/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+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La: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)*tt(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(-Ca>i||Ca>i&&0>yc)^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?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,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=ga(A-qa)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)qa^(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:qa-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=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}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 Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)0?0:3:ga(r[0]-e)0?2:1:ga(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&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(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(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,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 Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},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,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=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){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}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:b};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=ga(ga(w)-1)i||ga((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*Da),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*Pa,e*Pa])});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]*Da,n[1]*Da),[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]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),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,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},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*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},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*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La: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>qa?t-La:-qa>t?t+La: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),tt(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),tt(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*La)):(u=n+o*La,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=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,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-Ca,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(it(r-t)+u*o*it(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)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=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;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}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?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);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(qa/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=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},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 ga(u)u;u++){for(;r>1&&Q(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=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.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&&ga(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=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));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 Ir(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=Kc,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,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)Ca?{x:f,y:ga(t-f)Ca?{x:ga(e-p)Ca?{x:h,y:ga(t-h)Ca?{x:ga(e-g)=-za)){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=rl.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=tl._;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-n.x,d=e-n.y,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"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(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=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.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=ol.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*Ra)}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/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/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 st(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 ct(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 ht(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}}:ml}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?Iu: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 Ii(n,t,e,r)},u()}function Yi(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=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(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 yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(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:xl);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 Ml;arguments.length<2?t=Ml:"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)},Yi(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)},Yi(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 l;for(var i,o=-1,a=r.length;++oe?[0/0,0/0]:[e>0?a[e-1]:n[0],et?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=Et(e),p=Et(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,a)}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=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}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(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[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)},Yi(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.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,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 e,r=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 ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},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=Math.random()*i--|0,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,o),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++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 m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(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,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.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(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++uu){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.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},_a.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},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.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 l,y=new Array(o);for(r=-1;++rr;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.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 A(u)},_a.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},_a.sort=function(n){n=I.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},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.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(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,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=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*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+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*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))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){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]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){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(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[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},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.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 mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=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,rebeccapurple:6697881,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});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),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 m,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 Ka,Qa,nc,tc,ec,rc=this[x(this,"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};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(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 uc=["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)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=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))))}}),ac=ta.time={},cc=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(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(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}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.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=ac[n]=Ft(function(n){return(n=ac.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=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=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=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t -},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};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*Da,e*Da]);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]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;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+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(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]:nyc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>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){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=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=Ie(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 Ye(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+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.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 Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,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]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,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]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{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)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,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 ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).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+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},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]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(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=Et(e),i=Et(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)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;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(Yr),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=Et(a),x=Et(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=cl.get(e)||al,r=ll.get(r)||y,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:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={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=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];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,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=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;s>a;++a){var u=M[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=M[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,M[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,M[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(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=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===pl?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=pl,r=0,u=La,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 pl={};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=y,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:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.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 vl=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}),dl=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=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(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 ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={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 Ml=ta.format(".0e"),xl={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(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);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)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)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===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(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)<=qa?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)<=qa?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),I=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],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 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",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 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=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(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-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=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});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[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(y)},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)-Ra,s=l.call(n,u,r)-Ra;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>qa)+",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=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(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=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(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(zl.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=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=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*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},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/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{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 Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.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)},Pl.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)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.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)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(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}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(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}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,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 Yo(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):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}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=jl,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 Fl?t+"":jl,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 jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[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 c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=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?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.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]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.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]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},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/frontend/express/public/javascripts/visualization/flot/LICENSE.txt b/frontend/express/public/javascripts/visualization/flot/LICENSE.txt deleted file mode 100644 index 719da064fef..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2007-2014 IOLA and Ole Laursen - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/public/javascripts/visualization/flot/excanvas.js b/frontend/express/public/javascripts/visualization/flot/excanvas.js deleted file mode 100644 index 70a8f25ca86..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/excanvas.js +++ /dev/null @@ -1,1428 +0,0 @@ -// Copyright 2006 Google Inc. -// -// 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. - - -// Known Issues: -// -// * Patterns only support repeat. -// * Radial gradient are not implemented. The VML version of these look very -// different from the canvas one. -// * Clipping paths are not implemented. -// * Coordsize. The width and height attribute have higher priority than the -// width and height style values which isn't correct. -// * Painting mode isn't implemented. -// * Canvas width/height should is using content-box by default. IE in -// Quirks mode will draw the canvas using border-box. Either change your -// doctype to HTML5 -// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) -// or use Box Sizing Behavior from WebFX -// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) -// * Non uniform scaling does not correctly scale strokes. -// * Filling very large shapes (above 5000 points) is buggy. -// * Optimize. There is always room for speed improvements. - -// Only add this code if we do not already have a canvas implementation -if (!document.createElement('canvas').getContext) { - -(function() { - - // alias some functions to make (compiled) code shorter - var m = Math; - var mr = m.round; - var ms = m.sin; - var mc = m.cos; - var abs = m.abs; - var sqrt = m.sqrt; - - // this is used for sub pixel precision - var Z = 10; - var Z2 = Z / 2; - - var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1]; - - /** - * This funtion is assigned to the elements as element.getContext(). - * @this {HTMLElement} - * @return {CanvasRenderingContext2D_} - */ - function getContext() { - return this.context_ || - (this.context_ = new CanvasRenderingContext2D_(this)); - } - - var slice = Array.prototype.slice; - - /** - * Binds a function to an object. The returned function will always use the - * passed in {@code obj} as {@code this}. - * - * Example: - * - * g = bind(f, obj, a, b) - * g(c, d) // will do f.call(obj, a, b, c, d) - * - * @param {Function} f The function to bind the object to - * @param {Object} obj The object that should act as this when the function - * is called - * @param {*} var_args Rest arguments that will be used as the initial - * arguments when the function is called - * @return {Function} A new function that has bound this - */ - 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'); - - // Setup default CSS. Only add one style sheet per document - if (!doc.styleSheets['ex_canvas_']) { - var ss = doc.createStyleSheet(); - ss.owningElement.id = 'ex_canvas_'; - ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + - // default size is 300x150 in Gecko and Opera - 'text-align:left;width:300px;height:150px}'; - } - } - - // Add namespaces and stylesheet at startup. - addNamespacesAndStylesheet(document); - - var G_vmlCanvasManager_ = { - init: function(opt_doc) { - var doc = opt_doc || document; - // Create a dummy element so that IE will allow canvas elements to be - // recognized. - doc.createElement('canvas'); - doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); - }, - - init_: function(doc) { - // find all canvas elements - var els = doc.getElementsByTagName('canvas'); - for (var i = 0; i < els.length; i++) { - this.initElement(els[i]); - } - }, - - /** - * Public initializes a canvas element so that it can be used as canvas - * element from now on. This is called automatically before the page is - * loaded but if you are creating elements using createElement you need to - * make sure this is called on the element. - * @param {HTMLElement} el The canvas element to initialize. - * @return {HTMLElement} the element that was created. - */ - initElement: function(el) { - if (!el.getContext) { - el.getContext = getContext; - - // Add namespaces and stylesheet to document of the element. - addNamespacesAndStylesheet(el.ownerDocument); - - // Remove fallback content. There is no way to hide text nodes so we - // just remove all childNodes. We could hide all elements and remove - // text nodes but who really cares about the fallback content. - el.innerHTML = ''; - - // do not use inline function because that will leak memory - el.attachEvent('onpropertychange', onPropertyChange); - el.attachEvent('onresize', onResize); - - var attrs = el.attributes; - if (attrs.width && attrs.width.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setWidth_(attrs.width.nodeValue); - el.style.width = attrs.width.nodeValue + 'px'; - } else { - el.width = el.clientWidth; - } - if (attrs.height && attrs.height.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setHeight_(attrs.height.nodeValue); - el.style.height = attrs.height.nodeValue + 'px'; - } else { - el.height = el.clientHeight; - } - //el.getContext().setCoordsize_() - } - return el; - } - }; - - function onPropertyChange(e) { - var el = e.srcElement; - - switch (e.propertyName) { - case 'width': - el.getContext().clearRect(); - el.style.width = el.attributes.width.nodeValue + 'px'; - // In IE8 this does not trigger onresize. - el.firstChild.style.width = el.clientWidth + 'px'; - break; - case 'height': - el.getContext().clearRect(); - el.style.height = el.attributes.height.nodeValue + 'px'; - el.firstChild.style.height = el.clientHeight + 'px'; - break; - } - } - - function onResize(e) { - var el = e.srcElement; - if (el.firstChild) { - el.firstChild.style.width = el.clientWidth + 'px'; - el.firstChild.style.height = el.clientHeight + 'px'; - } - } - - G_vmlCanvasManager_.init(); - - // precompute "00" to "FF" - var decToHex = []; - for (var i = 0; i < 16; i++) { - for (var j = 0; j < 16; j++) { - decToHex[i * 16 + j] = i.toString(16) + j.toString(16); - } - } - - function createMatrixIdentity() { - return [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1] - ]; - } - - function matrixMultiply(m1, m2) { - var result = createMatrixIdentity(); - - for (var x = 0; x < 3; x++) { - for (var y = 0; y < 3; y++) { - var sum = 0; - - for (var z = 0; z < 3; z++) { - sum += m1[x][z] * m2[z][y]; - } - - result[x][y] = sum; - } - } - return result; - } - - function copyState(o1, o2) { - o2.fillStyle = o1.fillStyle; - o2.lineCap = o1.lineCap; - o2.lineJoin = o1.lineJoin; - o2.lineWidth = o1.lineWidth; - o2.miterLimit = o1.miterLimit; - o2.shadowBlur = o1.shadowBlur; - o2.shadowColor = o1.shadowColor; - o2.shadowOffsetX = o1.shadowOffsetX; - o2.shadowOffsetY = o1.shadowOffsetY; - o2.strokeStyle = o1.strokeStyle; - o2.globalAlpha = o1.globalAlpha; - o2.font = o1.font; - o2.textAlign = o1.textAlign; - o2.textBaseline = o1.textBaseline; - o2.arcScaleX_ = o1.arcScaleX_; - o2.arcScaleY_ = o1.arcScaleY_; - o2.lineScale_ = o1.lineScale_; - } - - var colorData = { - aliceblue: '#F0F8FF', - antiquewhite: '#FAEBD7', - aquamarine: '#7FFFD4', - azure: '#F0FFFF', - beige: '#F5F5DC', - bisque: '#FFE4C4', - black: '#000000', - blanchedalmond: '#FFEBCD', - blueviolet: '#8A2BE2', - brown: '#A52A2A', - burlywood: '#DEB887', - cadetblue: '#5F9EA0', - chartreuse: '#7FFF00', - chocolate: '#D2691E', - coral: '#FF7F50', - cornflowerblue: '#6495ED', - cornsilk: '#FFF8DC', - crimson: '#DC143C', - cyan: '#00FFFF', - darkblue: '#00008B', - darkcyan: '#008B8B', - darkgoldenrod: '#B8860B', - darkgray: '#A9A9A9', - darkgreen: '#006400', - darkgrey: '#A9A9A9', - darkkhaki: '#BDB76B', - darkmagenta: '#8B008B', - darkolivegreen: '#556B2F', - darkorange: '#FF8C00', - darkorchid: '#9932CC', - darkred: '#8B0000', - darksalmon: '#E9967A', - darkseagreen: '#8FBC8F', - darkslateblue: '#483D8B', - darkslategray: '#2F4F4F', - darkslategrey: '#2F4F4F', - darkturquoise: '#00CED1', - darkviolet: '#9400D3', - deeppink: '#FF1493', - deepskyblue: '#00BFFF', - dimgray: '#696969', - dimgrey: '#696969', - dodgerblue: '#1E90FF', - firebrick: '#B22222', - floralwhite: '#FFFAF0', - forestgreen: '#228B22', - gainsboro: '#DCDCDC', - ghostwhite: '#F8F8FF', - gold: '#FFD700', - goldenrod: '#DAA520', - grey: '#808080', - greenyellow: '#ADFF2F', - honeydew: '#F0FFF0', - hotpink: '#FF69B4', - indianred: '#CD5C5C', - indigo: '#4B0082', - ivory: '#FFFFF0', - khaki: '#F0E68C', - lavender: '#E6E6FA', - lavenderblush: '#FFF0F5', - lawngreen: '#7CFC00', - lemonchiffon: '#FFFACD', - lightblue: '#ADD8E6', - lightcoral: '#F08080', - lightcyan: '#E0FFFF', - lightgoldenrodyellow: '#FAFAD2', - lightgreen: '#90EE90', - lightgrey: '#D3D3D3', - lightpink: '#FFB6C1', - lightsalmon: '#FFA07A', - lightseagreen: '#20B2AA', - lightskyblue: '#87CEFA', - lightslategray: '#778899', - lightslategrey: '#778899', - lightsteelblue: '#B0C4DE', - lightyellow: '#FFFFE0', - limegreen: '#32CD32', - linen: '#FAF0E6', - magenta: '#FF00FF', - mediumaquamarine: '#66CDAA', - mediumblue: '#0000CD', - mediumorchid: '#BA55D3', - mediumpurple: '#9370DB', - mediumseagreen: '#3CB371', - mediumslateblue: '#7B68EE', - mediumspringgreen: '#00FA9A', - mediumturquoise: '#48D1CC', - mediumvioletred: '#C71585', - midnightblue: '#191970', - mintcream: '#F5FFFA', - mistyrose: '#FFE4E1', - moccasin: '#FFE4B5', - navajowhite: '#FFDEAD', - oldlace: '#FDF5E6', - olivedrab: '#6B8E23', - orange: '#FFA500', - orangered: '#FF4500', - orchid: '#DA70D6', - palegoldenrod: '#EEE8AA', - palegreen: '#98FB98', - paleturquoise: '#AFEEEE', - palevioletred: '#DB7093', - papayawhip: '#FFEFD5', - peachpuff: '#FFDAB9', - peru: '#CD853F', - pink: '#FFC0CB', - plum: '#DDA0DD', - powderblue: '#B0E0E6', - rosybrown: '#BC8F8F', - royalblue: '#4169E1', - saddlebrown: '#8B4513', - salmon: '#FA8072', - sandybrown: '#F4A460', - seagreen: '#2E8B57', - seashell: '#FFF5EE', - sienna: '#A0522D', - skyblue: '#87CEEB', - slateblue: '#6A5ACD', - slategray: '#708090', - slategrey: '#708090', - snow: '#FFFAFA', - springgreen: '#00FF7F', - steelblue: '#4682B4', - tan: '#D2B48C', - thistle: '#D8BFD8', - tomato: '#FF6347', - turquoise: '#40E0D0', - violet: '#EE82EE', - wheat: '#F5DEB3', - whitesmoke: '#F5F5F5', - yellowgreen: '#9ACD32' - }; - - - function getRgbHslContent(styleString) { - var start = styleString.indexOf('(', 3); - var end = styleString.indexOf(')', start + 1); - var parts = styleString.substring(start + 1, end).split(','); - // add alpha if needed - if (parts.length != 4 || styleString.charAt(3) != 'a') { - parts[3] = 1; - } - return parts; - } - - function percent(s) { - return parseFloat(s) / 100; - } - - function clamp(v, min, max) { - return Math.min(max, Math.max(min, v)); - } - - function hslToRgb(parts){ - var r, g, b, h, s, l; - h = parseFloat(parts[0]) / 360 % 360; - if (h < 0) - h++; - s = clamp(percent(parts[1]), 0, 1); - l = clamp(percent(parts[2]), 0, 1); - if (s == 0) { - r = g = b = l; // achromatic - } else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hueToRgb(p, q, h + 1 / 3); - g = hueToRgb(p, q, h); - b = hueToRgb(p, q, h - 1 / 3); - } - - return '#' + decToHex[Math.floor(r * 255)] + - decToHex[Math.floor(g * 255)] + - decToHex[Math.floor(b * 255)]; - } - - function hueToRgb(m1, m2, h) { - if (h < 0) - h++; - if (h > 1) - 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' - }; - - // Internal text style cache - 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) { - // Ignore failures to set to invalid font. - } - - 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]; - } - - // Compute the size - 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 / .75; - } else { - computedStyle.size = canvasFontSize; - } - - // Different scaling between normal text and VML text. This was found using - // trial and error to get the same size as non VML text. - 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'; - } - - /** - * This class implements CanvasRenderingContext2D interface as described by - * the WHATWG. - * @param {HTMLElement} canvasElement The element that the 2D context should - * be associated with - */ - function CanvasRenderingContext2D_(canvasElement) { - this.m_ = createMatrixIdentity(); - - this.mStack_ = []; - this.aStack_ = []; - this.currentPath_ = []; - - // Canvas context properties - 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); - // Use a non transparent background. - 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() { - // TODO: Branch current matrix so that save/restore has no effect - // as per safari docs. - 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); - }; - - // Helper function that takes the already fixed cordinates. - 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) { - // the following is lifted almost directly from - // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes - - var cp = getCoords(this, aCPx, aCPy); - var p = getCoords(this, aX, aY); - - var cp1 = { - x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), - y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) - }; - var cp2 = { - x: cp1.x + (p.x - this.currentX_) / 3.0, - y: cp1.y + (p.y - this.currentY_) / 3.0 - }; - - 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; - - // IE won't render arches drawn counter clockwise if xStart == xEnd. - if (xStart == xEnd && !aClockwise) { - xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something - // that can be represented in binary - } - - 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; - - // to find the original width we overide the width and height - var oldRuntimeWidth = image.runtimeStyle.width; - var oldRuntimeHeight = image.runtimeStyle.height; - image.runtimeStyle.width = 'auto'; - image.runtimeStyle.height = 'auto'; - - // get the original size - var w = image.width; - var h = image.height; - - // and remove overides - 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; - - // For some reason that I've now forgotten, using divs didn't work - vmlStr.push(' ' , - '', - ''); - - this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); - }; - - contextPrototype.stroke = function(aFill) { - var W = 10; - var H = 10; - // Divide the shape into chunks if it's too long because IE has a limit - // somewhere for how long a VML shape can be. This simple division does - // not work with fills, only strokes, unfortunately. - var chunkSize = 5000; - - var min = {x: null, y: null}; - var max = {x: null, y: null}; - - for (var j = 0; j < this.currentPath_.length; j += chunkSize) { - var lineStr = []; - var lineOpen = false; - - 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; - - // VML cannot correctly render a line if the width is less than 1px. - // In that case, we dilute the color to make the line look thinner. - 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_) { - // TODO: Gradients transformed with the transformation matrix. - var angle = 0; - var focus = {x: 0, y: 0}; - - // additional offset - var shift = 0; - // scale factor for offset - 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; - - // The angle should be a non-negative number. - if (angle < 0) { - angle += 360; - } - - // Very small angles produce an unexpected result because they are - // converted to a scientific notation string. - 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; - } - - // We need to sort the color stops in ascending order by offset, - // otherwise IE won't interpret it correctly. - 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 < length; i++) { - var stop = stops[i]; - colors.push(stop.offset * expansion + shift + ' ' + stop.color); - } - - // When colors attribute is used, the meanings of opacity and o:opacity2 - // are reversed. - lineStr.push(''); - } 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) { - // Get the line scale. - // Determinant of this.m_ means how much the area is enlarged by the - // transformation. So its square root can be used as a scale factor - // for width. - 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); - }; - - /** - * The text drawing function. - * The maxWidth argument isn't taken in account, since no browser supports - * it yet. - */ - contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) { - var m = this.m_, - delta = 1000, - 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'; - } - - // 1.75 is an arbitrary number, as there is no info about the text baseline - 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 { - // TODO: Fix the min and max params. - 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; - // Don't use innerHTML or innerText because they allow markup/whitespace. - this.textMeasureEl_.appendChild(doc.createTextNode(text)); - return {width: this.textMeasureEl_.offsetWidth}; - }; - - /******** STUBS ********/ - contextPrototype.clip = function() { - // TODO: Implement - }; - - contextPrototype.arcTo = function() { - // TODO: Implement - }; - - contextPrototype.createPattern = function(image, repetition) { - return new CanvasPattern_(image, repetition); - }; - - // Gradient / Pattern Stubs - 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; - - // set up externs - G_vmlCanvasManager = G_vmlCanvasManager_; - CanvasRenderingContext2D = CanvasRenderingContext2D_; - CanvasGradient = CanvasGradient_; - CanvasPattern = CanvasPattern_; - DOMException = DOMException_; -})(); - -} // if diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.colorhelpers.js b/frontend/express/public/javascripts/visualization/flot/jquery.colorhelpers.js deleted file mode 100644 index b2f6dc4e433..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.colorhelpers.js +++ /dev/null @@ -1,180 +0,0 @@ -/* Plugin for jQuery for working with colors. - * - * Version 1.1. - * - * Inspiration from jQuery color animation plugin by John Resig. - * - * Released under the MIT license by Ole Laursen, October 2009. - * - * Examples: - * - * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() - * var c = $.color.extract($("#mydiv"), 'background-color'); - * console.log(c.r, c.g, c.b, c.a); - * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" - * - * Note that .scale() and .add() return the same modified object - * instead of making a new one. - * - * V. 1.1: Fix error handling so e.g. parsing an empty string does - * produce a color rather than just crashing. - */ - -(function($) { - $.color = {}; - - // construct color object with some convenient chainable helpers - $.color.make = function (r, g, b, a) { - var o = {}; - o.r = r || 0; - o.g = g || 0; - o.b = b || 0; - o.a = a != null ? a : 1; - - o.add = function (c, d) { - for (var i = 0; i < c.length; ++i) - o[c.charAt(i)] += d; - return o.normalize(); - }; - - o.scale = function (c, f) { - for (var i = 0; i < c.length; ++i) - o[c.charAt(i)] *= f; - return o.normalize(); - }; - - o.toString = function () { - if (o.a >= 1.0) { - return "rgb("+[o.r, o.g, o.b].join(",")+")"; - } else { - return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")"; - } - }; - - o.normalize = function () { - function clamp(min, value, max) { - return value < min ? min: (value > max ? max: value); - } - - o.r = clamp(0, parseInt(o.r), 255); - o.g = clamp(0, parseInt(o.g), 255); - o.b = clamp(0, parseInt(o.b), 255); - o.a = clamp(0, o.a, 1); - return o; - }; - - o.clone = function () { - return $.color.make(o.r, o.b, o.g, o.a); - }; - - return o.normalize(); - } - - // extract CSS color property from element, going up in the DOM - // if it's "transparent" - $.color.extract = function (elem, css) { - var c; - - do { - c = elem.css(css).toLowerCase(); - // keep going until we find an element that has color, or - // we hit the body or root (have no parent) - if (c != '' && c != 'transparent') - break; - elem = elem.parent(); - } while (elem.length && !$.nodeName(elem.get(0), "body")); - - // catch Safari's way of signalling transparent - if (c == "rgba(0, 0, 0, 0)") - c = "transparent"; - - return $.color.parse(c); - } - - // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"), - // returns color object, if parsing failed, you get black (0, 0, - // 0) out - $.color.parse = function (str) { - var res, m = $.color.make; - - // Look for rgb(num,num,num) - if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str)) - return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10)); - - // Look for rgba(num,num,num,num) - if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) - return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4])); - - // Look for rgb(num%,num%,num%) - if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str)) - return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55); - - // Look for rgba(num%,num%,num%,num) - if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) - return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4])); - - // Look for #a0b1c2 - if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str)) - return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16)); - - // Look for #fff - if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str)) - return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16)); - - // Otherwise, we're most likely dealing with a named color - var name = $.trim(str).toLowerCase(); - if (name == "transparent") - return m(255, 255, 255, 0); - else { - // default to black - res = lookupColors[name] || [0, 0, 0]; - return m(res[0], res[1], res[2]); - } - } - - var lookupColors = { - aqua:[0,255,255], - azure:[240,255,255], - beige:[245,245,220], - black:[0,0,0], - blue:[0,0,255], - brown:[165,42,42], - cyan:[0,255,255], - darkblue:[0,0,139], - darkcyan:[0,139,139], - darkgrey:[169,169,169], - darkgreen:[0,100,0], - darkkhaki:[189,183,107], - darkmagenta:[139,0,139], - darkolivegreen:[85,107,47], - darkorange:[255,140,0], - darkorchid:[153,50,204], - darkred:[139,0,0], - darksalmon:[233,150,122], - darkviolet:[148,0,211], - fuchsia:[255,0,255], - gold:[255,215,0], - green:[0,128,0], - indigo:[75,0,130], - khaki:[240,230,140], - lightblue:[173,216,230], - lightcyan:[224,255,255], - lightgreen:[144,238,144], - lightgrey:[211,211,211], - lightpink:[255,182,193], - lightyellow:[255,255,224], - lime:[0,255,0], - magenta:[255,0,255], - maroon:[128,0,0], - navy:[0,0,128], - olive:[128,128,0], - orange:[255,165,0], - pink:[255,192,203], - purple:[128,0,128], - violet:[128,0,128], - red:[255,0,0], - silver:[192,192,192], - white:[255,255,255], - yellow:[255,255,0] - }; -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.canvas.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.canvas.js deleted file mode 100644 index 29328d58121..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.canvas.js +++ /dev/null @@ -1,345 +0,0 @@ -/* Flot plugin for drawing all elements of a plot on the canvas. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -Flot normally produces certain elements, like axis labels and the legend, using -HTML elements. This permits greater interactivity and customization, and often -looks better, due to cross-browser canvas text inconsistencies and limitations. - -It can also be desirable to render the plot entirely in canvas, particularly -if the goal is to save it as an image, or if Flot is being used in a context -where the HTML DOM does not exist, as is the case within Node.js. This plugin -switches out Flot's standard drawing operations for canvas-only replacements. - -Currently the plugin supports only axis labels, but it will eventually allow -every element of the plot to be rendered directly to canvas. - -The plugin supports these options: - -{ - canvas: boolean -} - -The "canvas" option controls whether full canvas drawing is enabled, making it -possible to toggle on and off. This is useful when a plot uses HTML text in the -browser, but needs to redraw with canvas text when exporting as an image. - -*/ - -(function($) { - - var options = { - canvas: true - }; - - var render, getTextInfo, addText; - - // Cache the prototype hasOwnProperty for faster access - - var hasOwnProperty = Object.prototype.hasOwnProperty; - - function init(plot, classes) { - - var Canvas = classes.Canvas; - - // We only want to replace the functions once; the second time around - // we would just get our new function back. This whole replacing of - // prototype functions is a disaster, and needs to be changed ASAP. - - if (render == null) { - getTextInfo = Canvas.prototype.getTextInfo, - addText = Canvas.prototype.addText, - render = Canvas.prototype.render; - } - - // Finishes rendering the canvas, including overlaid text - - Canvas.prototype.render = function() { - - if (!plot.getOptions().canvas) { - return render.call(this); - } - - var context = this.context, - cache = this._textCache; - - // For each text layer, render elements marked as active - - context.save(); - context.textBaseline = "middle"; - - for (var layerKey in cache) { - if (hasOwnProperty.call(cache, layerKey)) { - var layerCache = cache[layerKey]; - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey], - updateStyles = true; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - - var info = styleCache[key], - positions = info.positions, - lines = info.lines; - - // Since every element at this level of the cache have the - // same font and fill styles, we can just change them once - // using the values from the first element. - - if (updateStyles) { - context.fillStyle = info.font.color; - context.font = info.font.definition; - updateStyles = false; - } - - for (var i = 0, position; position = positions[i]; i++) { - if (position.active) { - for (var j = 0, line; line = position.lines[j]; j++) { - context.fillText(lines[j].text, line[0], line[1]); - } - } else { - positions.splice(i--, 1); - } - } - - if (positions.length == 0) { - delete styleCache[key]; - } - } - } - } - } - } - } - - context.restore(); - }; - - // Creates (if necessary) and returns a text info object. - // - // When the canvas option is set, the object looks like this: - // - // { - // width: Width of the text's bounding box. - // height: Height of the text's bounding box. - // positions: Array of positions at which this text is drawn. - // lines: [{ - // height: Height of this line. - // widths: Width of this line. - // text: Text on this line. - // }], - // font: { - // definition: Canvas font property string. - // color: Color of the text. - // }, - // } - // - // The positions array contains objects that look like this: - // - // { - // active: Flag indicating whether the text should be visible. - // lines: Array of [x, y] coordinates at which to draw the line. - // x: X coordinate at which to draw the text. - // y: Y coordinate at which to draw the text. - // } - - Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { - - if (!plot.getOptions().canvas) { - return getTextInfo.call(this, layer, text, font, angle, width); - } - - var textStyle, layerCache, styleCache, info; - - // Cast the value to a string, in case we were given a number - - text = "" + text; - - // If the font is a font-spec object, generate a CSS definition - - if (typeof font === "object") { - textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family; - } else { - textStyle = font; - } - - // Retrieve (or create) the cache for the text's layer and styles - - layerCache = this._textCache[layer]; - - if (layerCache == null) { - layerCache = this._textCache[layer] = {}; - } - - styleCache = layerCache[textStyle]; - - if (styleCache == null) { - styleCache = layerCache[textStyle] = {}; - } - - info = styleCache[text]; - - if (info == null) { - - var context = this.context; - - // If the font was provided as CSS, create a div with those - // classes and examine it to generate a canvas font spec. - - if (typeof font !== "object") { - - var element = $("
       
      ") - .css("position", "absolute") - .addClass(typeof font === "string" ? font : null) - .appendTo(this.getTextLayer(layer)); - - font = { - lineHeight: element.height(), - style: element.css("font-style"), - variant: element.css("font-variant"), - weight: element.css("font-weight"), - family: element.css("font-family"), - color: element.css("color") - }; - - // Setting line-height to 1, without units, sets it equal - // to the font-size, even if the font-size is abstract, - // like 'smaller'. This enables us to read the real size - // via the element's height, working around browsers that - // return the literal 'smaller' value. - - font.size = element.css("line-height", 1).height(); - - element.remove(); - } - - textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family; - - // Create a new info object, initializing the dimensions to - // zero so we can count them up line-by-line. - - info = styleCache[text] = { - width: 0, - height: 0, - positions: [], - lines: [], - font: { - definition: textStyle, - color: font.color - } - }; - - context.save(); - context.font = textStyle; - - // Canvas can't handle multi-line strings; break on various - // newlines, including HTML brs, to build a list of lines. - // Note that we could split directly on regexps, but IE < 9 is - // broken; revisit when we drop IE 7/8 support. - - var lines = (text + "").replace(/
      |\r\n|\r/g, "\n").split("\n"); - - for (var i = 0; i < lines.length; ++i) { - - var lineText = lines[i], - measured = context.measureText(lineText); - - info.width = Math.max(measured.width, info.width); - info.height += font.lineHeight; - - info.lines.push({ - text: lineText, - width: measured.width, - height: font.lineHeight - }); - } - - context.restore(); - } - - return info; - }; - - // Adds a text string to the canvas text overlay. - - Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { - - if (!plot.getOptions().canvas) { - return addText.call(this, layer, x, y, text, font, angle, width, halign, valign); - } - - var info = this.getTextInfo(layer, text, font, angle, width), - positions = info.positions, - lines = info.lines; - - // Text is drawn with baseline 'middle', which we need to account - // for by adding half a line's height to the y position. - - y += info.height / lines.length / 2; - - // Tweak the initial y-position to match vertical alignment - - if (valign == "middle") { - y = Math.round(y - info.height / 2); - } else if (valign == "bottom") { - y = Math.round(y - info.height); - } else { - y = Math.round(y); - } - - // FIXME: LEGACY BROWSER FIX - // AFFECTS: Opera < 12.00 - - // Offset the y coordinate, since Opera is off pretty - // consistently compared to the other browsers. - - if (!!(window.opera && window.opera.version().split(".")[0] < 12)) { - y -= 2; - } - - // Determine whether this text already exists at this position. - // If so, mark it for inclusion in the next render pass. - - for (var i = 0, position; position = positions[i]; i++) { - if (position.x == x && position.y == y) { - position.active = true; - return; - } - } - - // If the text doesn't exist at this position, create a new entry - - position = { - active: true, - lines: [], - x: x, - y: y - }; - - positions.push(position); - - // Fill in the x & y positions of each line, adjusting them - // individually for horizontal alignment. - - for (var i = 0, line; line = lines[i]; i++) { - if (halign == "center") { - position.lines.push([Math.round(x - line.width / 2), y]); - } else if (halign == "right") { - position.lines.push([Math.round(x - line.width), y]); - } else { - position.lines.push([Math.round(x), y]); - } - y += line.height; - } - }; - } - - $.plot.plugins.push({ - init: init, - options: options, - name: "canvas", - version: "1.0" - }); - -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.categories.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.categories.js deleted file mode 100644 index 2f9b2579714..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.categories.js +++ /dev/null @@ -1,190 +0,0 @@ -/* Flot plugin for plotting textual data or categories. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin -allows you to plot such a dataset directly. - -To enable it, you must specify mode: "categories" on the axis with the textual -labels, e.g. - - $.plot("#placeholder", data, { xaxis: { mode: "categories" } }); - -By default, the labels are ordered as they are met in the data series. If you -need a different ordering, you can specify "categories" on the axis options -and list the categories there: - - xaxis: { - mode: "categories", - categories: ["February", "March", "April"] - } - -If you need to customize the distances between the categories, you can specify -"categories" as an object mapping labels to values - - xaxis: { - mode: "categories", - categories: { "February": 1, "March": 3, "April": 4 } - } - -If you don't specify all categories, the remaining categories will be numbered -from the max value plus 1 (with a spacing of 1 between each). - -Internally, the plugin works by transforming the input data through an auto- -generated mapping where the first category becomes 0, the second 1, etc. -Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this -is visible in hover and click events that return numbers rather than the -category labels). The plugin also overrides the tick generator to spit out the -categories as ticks instead of the values. - -If you need to map a value back to its label, the mapping is always accessible -as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories. - -*/ - -(function ($) { - var options = { - xaxis: { - categories: null - }, - yaxis: { - categories: null - } - }; - - function processRawData(plot, series, data, datapoints) { - // if categories are enabled, we need to disable - // auto-transformation to numbers so the strings are intact - // for later processing - - var xCategories = series.xaxis.options.mode == "categories", - yCategories = series.yaxis.options.mode == "categories"; - - if (!(xCategories || yCategories)) - return; - - var format = datapoints.format; - - if (!format) { - // FIXME: auto-detection should really not be defined here - var s = series; - format = []; - format.push({ x: true, number: true, required: true }); - format.push({ y: true, number: true, required: true }); - - if (s.bars.show || (s.lines.show && s.lines.fill)) { - var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); - format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); - if (s.bars.horizontal) { - delete format[format.length - 1].y; - format[format.length - 1].x = true; - } - } - - datapoints.format = format; - } - - for (var m = 0; m < format.length; ++m) { - if (format[m].x && xCategories) - format[m].number = false; - - if (format[m].y && yCategories) - format[m].number = false; - } - } - - function getNextIndex(categories) { - var index = -1; - - for (var v in categories) - if (categories[v] > index) - index = categories[v]; - - return index + 1; - } - - function categoriesTickGenerator(axis) { - var res = []; - for (var label in axis.categories) { - var v = axis.categories[label]; - if (v >= axis.min && v <= axis.max) - res.push([v, label]); - } - - res.sort(function (a, b) { return a[0] - b[0]; }); - - return res; - } - - function setupCategoriesForAxis(series, axis, datapoints) { - if (series[axis].options.mode != "categories") - return; - - if (!series[axis].categories) { - // parse options - var c = {}, o = series[axis].options.categories || {}; - if ($.isArray(o)) { - for (var i = 0; i < o.length; ++i) - c[o[i]] = i; - } - else { - for (var v in o) - c[v] = o[v]; - } - - series[axis].categories = c; - } - - // fix ticks - if (!series[axis].options.ticks) - series[axis].options.ticks = categoriesTickGenerator; - - transformPointsOnAxis(datapoints, axis, series[axis].categories); - } - - function transformPointsOnAxis(datapoints, axis, categories) { - // go through the points, transforming them - var points = datapoints.points, - ps = datapoints.pointsize, - format = datapoints.format, - formatColumn = axis.charAt(0), - index = getNextIndex(categories); - - for (var i = 0; i < points.length; i += ps) { - if (points[i] == null) - continue; - - for (var m = 0; m < ps; ++m) { - var val = points[i + m]; - - if (val == null || !format[m][formatColumn]) - continue; - - if (!(val in categories)) { - categories[val] = index; - ++index; - } - - points[i + m] = categories[val]; - } - } - } - - function processDatapoints(plot, series, datapoints) { - setupCategoriesForAxis(series, "xaxis", datapoints); - setupCategoriesForAxis(series, "yaxis", datapoints); - } - - function init(plot) { - plot.hooks.processRawData.push(processRawData); - plot.hooks.processDatapoints.push(processDatapoints); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'categories', - version: '1.0' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.crosshair.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.crosshair.js deleted file mode 100644 index 533958c22bb..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.crosshair.js +++ /dev/null @@ -1,177 +0,0 @@ -/* Flot plugin for showing crosshairs when the mouse hovers over the plot. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin supports these options: - - crosshair: { - mode: null or "x" or "y" or "xy" - color: color - lineWidth: number - } - -Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical -crosshair that lets you trace the values on the x axis, "y" enables a -horizontal crosshair and "xy" enables them both. "color" is the color of the -crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of -the drawn lines (default is 1). - -The plugin also adds four public methods: - - - setCrosshair( pos ) - - Set the position of the crosshair. Note that this is cleared if the user - moves the mouse. "pos" is in coordinates of the plot and should be on the - form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple - axes), which is coincidentally the same format as what you get from a - "plothover" event. If "pos" is null, the crosshair is cleared. - - - clearCrosshair() - - Clear the crosshair. - - - lockCrosshair(pos) - - Cause the crosshair to lock to the current location, no longer updating if - the user moves the mouse. Optionally supply a position (passed on to - setCrosshair()) to move it to. - - Example usage: - - var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; - $("#graph").bind( "plothover", function ( evt, position, item ) { - if ( item ) { - // Lock the crosshair to the data point being hovered - myFlot.lockCrosshair({ - x: item.datapoint[ 0 ], - y: item.datapoint[ 1 ] - }); - } else { - // Return normal crosshair operation - myFlot.unlockCrosshair(); - } - }); - - - unlockCrosshair() - - Free the crosshair to move again after locking it. -*/ - -(function ($) { - var options = { - crosshair: { - mode: null, // one of null, "x", "y" or "xy", - color: "rgba(170, 0, 0, 0.80)", - lineWidth: 1 - } - }; - - function init(plot) { - // position of crosshair in pixels - var crosshair = { x: -1, y: -1, locked: false }; - - plot.setCrosshair = function setCrosshair(pos) { - if (!pos) - crosshair.x = -1; - else { - var o = plot.p2c(pos); - crosshair.x = Math.max(0, Math.min(o.left, plot.width())); - crosshair.y = Math.max(0, Math.min(o.top, plot.height())); - } - - plot.triggerRedrawOverlay(); - }; - - plot.clearCrosshair = plot.setCrosshair; // passes null for pos - - plot.lockCrosshair = function lockCrosshair(pos) { - if (pos) - plot.setCrosshair(pos); - crosshair.locked = true; - }; - - plot.unlockCrosshair = function unlockCrosshair() { - crosshair.locked = false; - }; - - function onMouseOut(e) { - // onur, in order to remove crosshair if mouse is not on the graph - //if (crosshair.locked) - // return; - - if (crosshair.x != -1) { - crosshair.x = -1; - plot.triggerRedrawOverlay(); - } - } - - function onMouseMove(e) { - if (crosshair.locked) - return; - - if (plot.getSelection && plot.getSelection()) { - crosshair.x = -1; // hide the crosshair while selecting - return; - } - - var offset = plot.offset(); - crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); - crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); - plot.triggerRedrawOverlay(); - } - - plot.hooks.bindEvents.push(function (plot, eventHolder) { - if (!plot.getOptions().crosshair.mode) - return; - - eventHolder.mouseout(onMouseOut); - eventHolder.mousemove(onMouseMove); - }); - - plot.hooks.drawOverlay.push(function (plot, ctx) { - var c = plot.getOptions().crosshair; - if (!c.mode) - return; - - var plotOffset = plot.getPlotOffset(); - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - if (crosshair.x != -1) { - var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0; - - ctx.strokeStyle = c.color; - ctx.lineWidth = c.lineWidth; - ctx.lineJoin = "round"; - - ctx.beginPath(); - if (c.mode.indexOf("x") != -1) { - var drawX = Math.floor(crosshair.x) + adj; - ctx.moveTo(drawX, 0); - ctx.lineTo(drawX, plot.height()); - } - if (c.mode.indexOf("y") != -1) { - var drawY = Math.floor(crosshair.y) + adj; - ctx.moveTo(0, drawY); - ctx.lineTo(plot.width(), drawY); - } - ctx.stroke(); - } - ctx.restore(); - }); - - plot.hooks.shutdown.push(function (plot, eventHolder) { - eventHolder.unbind("mouseout", onMouseOut); - eventHolder.unbind("mousemove", onMouseMove); - }); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'crosshair', - version: '1.0' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.errorbars.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.errorbars.js deleted file mode 100644 index 2583d5c20c3..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.errorbars.js +++ /dev/null @@ -1,353 +0,0 @@ -/* Flot plugin for plotting error bars. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -Error bars are used to show standard deviation and other statistical -properties in a plot. - -* Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com - -This plugin allows you to plot error-bars over points. Set "errorbars" inside -the points series to the axis name over which there will be error values in -your data array (*even* if you do not intend to plot them later, by setting -"show: null" on xerr/yerr). - -The plugin supports these options: - - series: { - points: { - errorbars: "x" or "y" or "xy", - xerr: { - show: null/false or true, - asymmetric: null/false or true, - upperCap: null or "-" or function, - lowerCap: null or "-" or function, - color: null or color, - radius: null or number - }, - yerr: { same options as xerr } - } - } - -Each data point array is expected to be of the type: - - "x" [ x, y, xerr ] - "y" [ x, y, yerr ] - "xy" [ x, y, xerr, yerr ] - -Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and -equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric -error-bars on X and asymmetric on Y would be: - - [ x, y, xerr, yerr_lower, yerr_upper ] - -By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will -draw a small cap perpendicular to the error bar. They can also be set to a -user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg. - - function drawSemiCircle( ctx, x, y, radius ) { - ctx.beginPath(); - ctx.arc( x, y, radius, 0, Math.PI, false ); - ctx.moveTo( x - radius, y ); - ctx.lineTo( x + radius, y ); - ctx.stroke(); - } - -Color and radius both default to the same ones of the points series if not -set. The independent radius parameter on xerr/yerr is useful for the case when -we may want to add error-bars to a line, without showing the interconnecting -points (with radius: 0), and still showing end caps on the error-bars. -shadowSize and lineWidth are derived as well from the points series. - -*/ - -(function ($) { - var options = { - series: { - points: { - errorbars: null, //should be 'x', 'y' or 'xy' - xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}, - yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null} - } - } - }; - - function processRawData(plot, series, data, datapoints){ - if (!series.points.errorbars) - return; - - // x,y values - var format = [ - { x: true, number: true, required: true }, - { y: true, number: true, required: true } - ]; - - var errors = series.points.errorbars; - // error bars - first X then Y - if (errors == 'x' || errors == 'xy') { - // lower / upper error - if (series.points.xerr.asymmetric) { - format.push({ x: true, number: true, required: true }); - format.push({ x: true, number: true, required: true }); - } else - format.push({ x: true, number: true, required: true }); - } - if (errors == 'y' || errors == 'xy') { - // lower / upper error - if (series.points.yerr.asymmetric) { - format.push({ y: true, number: true, required: true }); - format.push({ y: true, number: true, required: true }); - } else - format.push({ y: true, number: true, required: true }); - } - datapoints.format = format; - } - - function parseErrors(series, i){ - - var points = series.datapoints.points; - - // read errors from points array - var exl = null, - exu = null, - eyl = null, - eyu = null; - var xerr = series.points.xerr, - yerr = series.points.yerr; - - var eb = series.points.errorbars; - // error bars - first X - if (eb == 'x' || eb == 'xy') { - if (xerr.asymmetric) { - exl = points[i + 2]; - exu = points[i + 3]; - if (eb == 'xy') - if (yerr.asymmetric){ - eyl = points[i + 4]; - eyu = points[i + 5]; - } else eyl = points[i + 4]; - } else { - exl = points[i + 2]; - if (eb == 'xy') - if (yerr.asymmetric) { - eyl = points[i + 3]; - eyu = points[i + 4]; - } else eyl = points[i + 3]; - } - // only Y - } else if (eb == 'y') - if (yerr.asymmetric) { - eyl = points[i + 2]; - eyu = points[i + 3]; - } else eyl = points[i + 2]; - - // symmetric errors? - if (exu == null) exu = exl; - if (eyu == null) eyu = eyl; - - var errRanges = [exl, exu, eyl, eyu]; - // nullify if not showing - if (!xerr.show){ - errRanges[0] = null; - errRanges[1] = null; - } - if (!yerr.show){ - errRanges[2] = null; - errRanges[3] = null; - } - return errRanges; - } - - function drawSeriesErrors(plot, ctx, s){ - - var points = s.datapoints.points, - ps = s.datapoints.pointsize, - ax = [s.xaxis, s.yaxis], - radius = s.points.radius, - err = [s.points.xerr, s.points.yerr]; - - //sanity check, in case some inverted axis hack is applied to flot - var invertX = false; - if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) { - invertX = true; - var tmp = err[0].lowerCap; - err[0].lowerCap = err[0].upperCap; - err[0].upperCap = tmp; - } - - var invertY = false; - if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) { - invertY = true; - var tmp = err[1].lowerCap; - err[1].lowerCap = err[1].upperCap; - err[1].upperCap = tmp; - } - - for (var i = 0; i < s.datapoints.points.length; i += ps) { - - //parse - var errRanges = parseErrors(s, i); - - //cycle xerr & yerr - for (var e = 0; e < err.length; e++){ - - var minmax = [ax[e].min, ax[e].max]; - - //draw this error? - if (errRanges[e * err.length]){ - - //data coordinates - var x = points[i], - y = points[i + 1]; - - //errorbar ranges - var upper = [x, y][e] + errRanges[e * err.length + 1], - lower = [x, y][e] - errRanges[e * err.length]; - - //points outside of the canvas - if (err[e].err == 'x') - if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max) - continue; - if (err[e].err == 'y') - if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max) - continue; - - // prevent errorbars getting out of the canvas - var drawUpper = true, - drawLower = true; - - if (upper > minmax[1]) { - drawUpper = false; - upper = minmax[1]; - } - if (lower < minmax[0]) { - drawLower = false; - lower = minmax[0]; - } - - //sanity check, in case some inverted axis hack is applied to flot - if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) { - //swap coordinates - var tmp = lower; - lower = upper; - upper = tmp; - tmp = drawLower; - drawLower = drawUpper; - drawUpper = tmp; - tmp = minmax[0]; - minmax[0] = minmax[1]; - minmax[1] = tmp; - } - - // convert to pixels - x = ax[0].p2c(x), - y = ax[1].p2c(y), - upper = ax[e].p2c(upper); - lower = ax[e].p2c(lower); - minmax[0] = ax[e].p2c(minmax[0]); - minmax[1] = ax[e].p2c(minmax[1]); - - //same style as points by default - var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth, - sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize; - - //shadow as for points - if (lw > 0 && sw > 0) { - var w = sw / 2; - ctx.lineWidth = w; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax); - - ctx.strokeStyle = "rgba(0,0,0,0.2)"; - drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax); - } - - ctx.strokeStyle = err[e].color? err[e].color: s.color; - ctx.lineWidth = lw; - //draw it - drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax); - } - } - } - } - - function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){ - - //shadow offset - y += offset; - upper += offset; - lower += offset; - - // error bar - avoid plotting over circles - if (err.err == 'x'){ - if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]); - else drawUpper = false; - if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] ); - else drawLower = false; - } - else { - if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] ); - else drawUpper = false; - if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] ); - else drawLower = false; - } - - //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps - //this is a way to get errorbars on lines without visible connecting dots - radius = err.radius != null? err.radius: radius; - - // upper cap - if (drawUpper) { - if (err.upperCap == '-'){ - if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] ); - else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] ); - } else if ($.isFunction(err.upperCap)){ - if (err.err=='x') err.upperCap(ctx, upper, y, radius); - else err.upperCap(ctx, x, upper, radius); - } - } - // lower cap - if (drawLower) { - if (err.lowerCap == '-'){ - if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] ); - else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] ); - } else if ($.isFunction(err.lowerCap)){ - if (err.err=='x') err.lowerCap(ctx, lower, y, radius); - else err.lowerCap(ctx, x, lower, radius); - } - } - } - - function drawPath(ctx, pts){ - ctx.beginPath(); - ctx.moveTo(pts[0][0], pts[0][1]); - for (var p=1; p < pts.length; p++) - ctx.lineTo(pts[p][0], pts[p][1]); - ctx.stroke(); - } - - function draw(plot, ctx){ - var plotOffset = plot.getPlotOffset(); - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - $.each(plot.getData(), function (i, s) { - if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show)) - drawSeriesErrors(plot, ctx, s); - }); - ctx.restore(); - } - - function init(plot) { - plot.hooks.processRawData.push(processRawData); - plot.hooks.draw.push(draw); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'errorbars', - version: '1.0' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.fillbetween.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.fillbetween.js deleted file mode 100644 index 18b15d26db8..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.fillbetween.js +++ /dev/null @@ -1,226 +0,0 @@ -/* Flot plugin for computing bottoms for filled line and bar charts. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The case: you've got two series that you want to fill the area between. In Flot -terms, you need to use one as the fill bottom of the other. You can specify the -bottom of each data point as the third coordinate manually, or you can use this -plugin to compute it for you. - -In order to name the other series, you need to give it an id, like this: - - var dataset = [ - { data: [ ... ], id: "foo" } , // use default bottom - { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom - ]; - - $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }}); - -As a convenience, if the id given is a number that doesn't appear as an id in -the series, it is interpreted as the index in the array instead (so fillBetween: -0 can also mean the first series). - -Internally, the plugin modifies the datapoints in each series. For line series, -extra data points might be inserted through interpolation. Note that at points -where the bottom line is not defined (due to a null point or start/end of line), -the current line will show a gap too. The algorithm comes from the -jquery.flot.stack.js plugin, possibly some code could be shared. - -*/ - -(function ( $ ) { - - var options = { - series: { - fillBetween: null // or number - } - }; - - function init( plot ) { - - function findBottomSeries( s, allseries ) { - - var i; - - for ( i = 0; i < allseries.length; ++i ) { - if ( allseries[ i ].id === s.fillBetween ) { - return allseries[ i ]; - } - } - - if ( typeof s.fillBetween === "number" ) { - if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) { - return null; - } - return allseries[ s.fillBetween ]; - } - - return null; - } - - function computeFillBottoms( plot, s, datapoints ) { - - if ( s.fillBetween == null ) { - return; - } - - var other = findBottomSeries( s, plot.getData() ); - - if ( !other ) { - return; - } - - var ps = datapoints.pointsize, - points = datapoints.points, - otherps = other.datapoints.pointsize, - otherpoints = other.datapoints.points, - newpoints = [], - px, py, intery, qx, qy, bottom, - withlines = s.lines.show, - withbottom = ps > 2 && datapoints.format[2].y, - withsteps = withlines && s.lines.steps, - fromgap = true, - i = 0, - j = 0, - l, m; - - while ( true ) { - - if ( i >= points.length ) { - break; - } - - l = newpoints.length; - - if ( points[ i ] == null ) { - - // copy gaps - - for ( m = 0; m < ps; ++m ) { - newpoints.push( points[ i + m ] ); - } - - i += ps; - - } else if ( j >= otherpoints.length ) { - - // for lines, we can't use the rest of the points - - if ( !withlines ) { - for ( m = 0; m < ps; ++m ) { - newpoints.push( points[ i + m ] ); - } - } - - i += ps; - - } else if ( otherpoints[ j ] == null ) { - - // oops, got a gap - - for ( m = 0; m < ps; ++m ) { - newpoints.push( null ); - } - - fromgap = true; - j += otherps; - - } else { - - // cases where we actually got two points - - px = points[ i ]; - py = points[ i + 1 ]; - qx = otherpoints[ j ]; - qy = otherpoints[ j + 1 ]; - bottom = 0; - - if ( px === qx ) { - - for ( m = 0; m < ps; ++m ) { - newpoints.push( points[ i + m ] ); - } - - //newpoints[ l + 1 ] += qy; - bottom = qy; - - i += ps; - j += otherps; - - } else if ( px > qx ) { - - // we got past point below, might need to - // insert interpolated extra point - - if ( withlines && i > 0 && points[ i - ps ] != null ) { - intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px ); - newpoints.push( qx ); - newpoints.push( intery ); - for ( m = 2; m < ps; ++m ) { - newpoints.push( points[ i + m ] ); - } - bottom = qy; - } - - j += otherps; - - } else { // px < qx - - // if we come from a gap, we just skip this point - - if ( fromgap && withlines ) { - i += ps; - continue; - } - - for ( m = 0; m < ps; ++m ) { - newpoints.push( points[ i + m ] ); - } - - // we might be able to interpolate a point below, - // this can give us a better y - - if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) { - bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx ); - } - - //newpoints[l + 1] += bottom; - - i += ps; - } - - fromgap = false; - - if ( l !== newpoints.length && withbottom ) { - newpoints[ l + 2 ] = bottom; - } - } - - // maintain the line steps invariant - - if ( withsteps && l !== newpoints.length && l > 0 && - newpoints[ l ] !== null && - newpoints[ l ] !== newpoints[ l - ps ] && - newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) { - for (m = 0; m < ps; ++m) { - newpoints[ l + ps + m ] = newpoints[ l + m ]; - } - newpoints[ l + 1 ] = newpoints[ l - ps + 1 ]; - } - } - - datapoints.points = newpoints; - } - - plot.hooks.processDatapoints.push( computeFillBottoms ); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: "fillbetween", - version: "1.0" - }); - -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.grow.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.grow.js deleted file mode 100644 index bc3894aa132..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.grow.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * The MIT License - -Copyright (c) 2010 by Juergen Marsch - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -(function ($) -{ var options = - { series: { - grow: { - active: true, - valueIndex: 1, - stepDelay: 1, - steps:100, - stepMode: "maximum", - stepDirection: "up" - } - } - }; - function init(plot) { - var done = false; - var growfunc; - var plt = plot; - var data = null; - var opt = null; - var valueIndex; - plot.hooks.bindEvents.push(processbindEvents); - plot.hooks.drawSeries.push(processSeries); - function processSeries(plot, canvascontext, series) - { opt = plot.getOptions(); - valueIndex = opt.series.grow.valueIndex; - if(opt.series.grow.active == true) - { if (done == false) - { data = plot.getData(); - data.actualStep = 0; - for (var j = 0; j < data.length; j++) - { data[j].dataOrg = clone(data[j].data); - for (var i = 0; i < data[j].data.length; i++) - data[j].data[i][valueIndex] = 0; - } - plot.setData(data); - done = true; - } - } - } - function processbindEvents(plot,eventHolder) - { opt = plot.getOptions(); - if (opt.series.grow.active == true) - { var d = plot.getData(); - for (var j = 0; j < data.length; j++) { - opt.series.grow.steps = Math.max(opt.series.grow.steps, d[j].grow.steps); - } - if(opt.series.grow.stepDelay == 0) opt.series.grow.stepDelay++; - growfunc = window.setInterval(growing, opt.series.grow.stepDelay); - } - } - function growing() - { if (data.actualStep < opt.series.grow.steps) - { data.actualStep++; - for(var j = 0; j < data.length; j++) - { if (typeof data[j].grow.stepMode == "function") - { data[j].grow.stepMode(data[j],data.actualStep,valueIndex); } - else - { if (data[j].grow.stepMode == "linear") growLinear(); - else if (data[j].grow.stepMode == "maximum") growMaximum(); - else if (data[j].grow.stepMode == "delay") growDelay(); - else growNone(); - } - } - plt.setData(data); - plt.draw(); - } - else - { window.clearInterval(growfunc); } - function growNone() - { if (data.actualStep == 1) - { for (var i = 0; i < data[j].data.length; i++) - { data[j].data[i][valueIndex] = data[j].dataOrg[i][valueIndex]; } - } - } - function growLinear() - { if (data.actualStep <= data[j].grow.steps) - { for (var i = 0; i < data[j].data.length; i++) - { if (data[j].grow.stepDirection == "up") - { data[j].data[i][valueIndex] = data[j].dataOrg[i][valueIndex] / data[j].grow.steps * data.actualStep;} - else if(data[j].grow.stepDirection == "down") - { data[j].data[i][valueIndex] = data[j].dataOrg[i][valueIndex] + (data[j].yaxis.max - data[j].dataOrg[i][valueIndex]) / data[j].grow.steps * (data[j].grow.steps - data.actualStep); } - } - } - } - function growMaximum() - { if (data.actualStep <= data[j].grow.steps) - { for (var i = 0; i < data[j].data.length; i++) - { if (data[j].grow.stepDirection == "up") - { data[j].data[i][valueIndex] = Math.min(data[j].dataOrg[i][valueIndex], data[j].yaxis.max / data[j].grow.steps * data.actualStep); } - else if (data[j].grow.stepDirection == "down") - { data[j].data[i][valueIndex] = Math.max(data[j].dataOrg[i][valueIndex], data[j].yaxis.max / data[j].grow.steps * (data[j].grow.steps - data.actualStep) ); } - } - } - } - function growDelay() - { if (data.actualStep == data[j].grow.steps) - { for (var i = 0; i < data[j].data.length; i++) - { data[j].data[i][valueIndex] = data[j].dataOrg[i][valueIndex]; } - } - } - } - function clone(obj) - { if(obj == null || typeof(obj) != 'object') return obj; - var temp = new obj.constructor(); - for(var key in obj) temp[key] = clone(obj[key]); - return temp; - } - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'grow', - version: '0.2' - }); -})(jQuery); \ No newline at end of file diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.image.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.image.js deleted file mode 100644 index 625a03571d2..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.image.js +++ /dev/null @@ -1,241 +0,0 @@ -/* Flot plugin for plotting images. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and -(x2, y2) are where you intend the two opposite corners of the image to end up -in the plot. Image must be a fully loaded Javascript image (you can make one -with new Image()). If the image is not complete, it's skipped when plotting. - -There are two helpers included for retrieving images. The easiest work the way -that you put in URLs instead of images in the data, like this: - - [ "myimage.png", 0, 0, 10, 10 ] - -Then call $.plot.image.loadData( data, options, callback ) where data and -options are the same as you pass in to $.plot. This loads the images, replaces -the URLs in the data with the corresponding images and calls "callback" when -all images are loaded (or failed loading). In the callback, you can then call -$.plot with the data set. See the included example. - -A more low-level helper, $.plot.image.load(urls, callback) is also included. -Given a list of URLs, it calls callback with an object mapping from URL to -Image object when all images are loaded or have failed loading. - -The plugin supports these options: - - series: { - images: { - show: boolean - anchor: "corner" or "center" - alpha: [ 0, 1 ] - } - } - -They can be specified for a specific series: - - $.plot( $("#placeholder"), [{ - data: [ ... ], - images: { ... } - ]) - -Note that because the data format is different from usual data points, you -can't use images with anything else in a specific data series. - -Setting "anchor" to "center" causes the pixels in the image to be anchored at -the corner pixel centers inside of at the pixel corners, effectively letting -half a pixel stick out to each side in the plot. - -A possible future direction could be support for tiling for large images (like -Google Maps). - -*/ - -(function ($) { - var options = { - series: { - images: { - show: false, - alpha: 1, - anchor: "corner" // or "center" - } - } - }; - - $.plot.image = {}; - - $.plot.image.loadDataImages = function (series, options, callback) { - var urls = [], points = []; - - var defaultShow = options.series.images.show; - - $.each(series, function (i, s) { - if (!(defaultShow || s.images.show)) - return; - - if (s.data) - s = s.data; - - $.each(s, function (i, p) { - if (typeof p[0] == "string") { - urls.push(p[0]); - points.push(p); - } - }); - }); - - $.plot.image.load(urls, function (loadedImages) { - $.each(points, function (i, p) { - var url = p[0]; - if (loadedImages[url]) - p[0] = loadedImages[url]; - }); - - callback(); - }); - } - - $.plot.image.load = function (urls, callback) { - var missing = urls.length, loaded = {}; - if (missing == 0) - callback({}); - - $.each(urls, function (i, url) { - var handler = function () { - --missing; - - loaded[url] = this; - - if (missing == 0) - callback(loaded); - }; - - $('').load(handler).error(handler).attr('src', url); - }); - }; - - function drawSeries(plot, ctx, series) { - var plotOffset = plot.getPlotOffset(); - - if (!series.images || !series.images.show) - return; - - var points = series.datapoints.points, - ps = series.datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - var img = points[i], - x1 = points[i + 1], y1 = points[i + 2], - x2 = points[i + 3], y2 = points[i + 4], - xaxis = series.xaxis, yaxis = series.yaxis, - tmp; - - // actually we should check img.complete, but it - // appears to be a somewhat unreliable indicator in - // IE6 (false even after load event) - if (!img || img.width <= 0 || img.height <= 0) - continue; - - if (x1 > x2) { - tmp = x2; - x2 = x1; - x1 = tmp; - } - if (y1 > y2) { - tmp = y2; - y2 = y1; - y1 = tmp; - } - - // if the anchor is at the center of the pixel, expand the - // image by 1/2 pixel in each direction - if (series.images.anchor == "center") { - tmp = 0.5 * (x2-x1) / (img.width - 1); - x1 -= tmp; - x2 += tmp; - tmp = 0.5 * (y2-y1) / (img.height - 1); - y1 -= tmp; - y2 += tmp; - } - - // clip - if (x1 == x2 || y1 == y2 || - x1 >= xaxis.max || x2 <= xaxis.min || - y1 >= yaxis.max || y2 <= yaxis.min) - continue; - - var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height; - if (x1 < xaxis.min) { - sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1); - x1 = xaxis.min; - } - - if (x2 > xaxis.max) { - sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1); - x2 = xaxis.max; - } - - if (y1 < yaxis.min) { - sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1); - y1 = yaxis.min; - } - - if (y2 > yaxis.max) { - sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1); - y2 = yaxis.max; - } - - x1 = xaxis.p2c(x1); - x2 = xaxis.p2c(x2); - y1 = yaxis.p2c(y1); - y2 = yaxis.p2c(y2); - - // the transformation may have swapped us - if (x1 > x2) { - tmp = x2; - x2 = x1; - x1 = tmp; - } - if (y1 > y2) { - tmp = y2; - y2 = y1; - y1 = tmp; - } - - tmp = ctx.globalAlpha; - ctx.globalAlpha *= series.images.alpha; - ctx.drawImage(img, - sx1, sy1, sx2 - sx1, sy2 - sy1, - x1 + plotOffset.left, y1 + plotOffset.top, - x2 - x1, y2 - y1); - ctx.globalAlpha = tmp; - } - } - - function processRawData(plot, series, data, datapoints) { - if (!series.images.show) - return; - - // format is Image, x1, y1, x2, y2 (opposite corners) - datapoints.format = [ - { required: true }, - { x: true, number: true, required: true }, - { y: true, number: true, required: true }, - { x: true, number: true, required: true }, - { y: true, number: true, required: true } - ]; - } - - function init(plot) { - plot.hooks.processRawData.push(processRawData); - plot.hooks.drawSeries.push(drawSeries); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'image', - version: '1.1' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.js deleted file mode 100644 index 2ca5c4934fd..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.js +++ /dev/null @@ -1,3297 +0,0 @@ -/* Javascript plotting library for jQuery, version 0.8.3. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -*/ - -// first an inline dependency, jquery.colorhelpers.js, we inline it here -// for convenience - -/* Plugin for jQuery for working with colors. - * - * Version 1.1. - * - * Inspiration from jQuery color animation plugin by John Resig. - * - * Released under the MIT license by Ole Laursen, October 2009. - * - * Examples: - * - * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() - * var c = $.color.extract($("#mydiv"), 'background-color'); - * console.log(c.r, c.g, c.b, c.a); - * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" - * - * Note that .scale() and .add() return the same modified object - * instead of making a new one. - * - * V. 1.1: Fix error handling so e.g. parsing an empty string does - * produce a color rather than just crashing. - */ -(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return valuemax?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); - -CanvasRenderingContext2D.prototype.dashedLineTo = function(fromX, fromY, toX, toY, pattern) { - // Our growth rate for our line can be one of the following: - // (+,+), (+,-), (-,+), (-,-) - // Because of this, our algorithm needs to understand if the x-coord and - // y-coord should be getting smaller or larger and properly cap the values - // based on (x,y). - - fromX = fromX || 0; - fromY = fromY || 0; - toX = toX || 0; - toY = toY || 0; - var lt = function (a, b) { return a <= b; }; - var gt = function (a, b) { return a >= b; }; - var capmin = function (a, b) { return Math.min(a, b); }; - var capmax = function (a, b) { return Math.max(a, b); }; - - var checkX = { thereYet: gt, cap: capmin }; - var checkY = { thereYet: gt, cap: capmin }; - - if (fromY - toY > 0) { - checkY.thereYet = lt; - checkY.cap = capmax; - } - if (fromX - toX > 0) { - checkX.thereYet = lt; - checkX.cap = capmax; - } - - this.moveTo(fromX, fromY); - var offsetX = fromX; - var offsetY = fromY; - var idx = 0, dash = true; - while (!(checkX.thereYet(offsetX, toX) && checkY.thereYet(offsetY, toY))) { - var ang = Math.atan2(toY - fromY, toX - fromX); - var len = pattern[idx]; - - offsetX = checkX.cap(toX, offsetX + (Math.cos(ang) * len)); - offsetY = checkY.cap(toY, offsetY + (Math.sin(ang) * len)); - - if (dash) this.lineTo(offsetX, offsetY); - else this.moveTo(offsetX, offsetY); - - idx = (idx + 1) % pattern.length; - dash = !dash; - } -}; - -// the actual Flot code -(function($) { - - // Cache the prototype hasOwnProperty for faster access - - var hasOwnProperty = Object.prototype.hasOwnProperty; - - // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM - // operation produces the same effect as detach, i.e. removing the element - // without touching its jQuery data. - - // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+. - - if (!$.fn.detach) { - $.fn.detach = function() { - return this.each(function() { - if (this.parentNode) { - this.parentNode.removeChild( this ); - } - }); - }; - } - - /////////////////////////////////////////////////////////////////////////// - // The Canvas object is a wrapper around an HTML5 tag. - // - // @constructor - // @param {string} cls List of classes to apply to the canvas. - // @param {element} container Element onto which to append the canvas. - // - // Requiring a container is a little iffy, but unfortunately canvas - // operations don't work unless the canvas is attached to the DOM. - - function Canvas(cls, container) { - - var element = container.children("." + cls)[0]; - - if (element == null) { - - element = document.createElement("canvas"); - element.className = cls; - - $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) - .appendTo(container); - - // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas - - if (!element.getContext) { - if (window.G_vmlCanvasManager) { - element = window.G_vmlCanvasManager.initElement(element); - } else { - throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); - } - } - } - - this.element = element; - - var context = this.context = element.getContext("2d"); - - // Determine the screen's ratio of physical to device-independent - // pixels. This is the ratio between the canvas width that the browser - // advertises and the number of pixels actually present in that space. - - // The iPhone 4, for example, has a device-independent width of 320px, - // but its screen is actually 640px wide. It therefore has a pixel - // ratio of 2, while most normal devices have a ratio of 1. - - var devicePixelRatio = window.devicePixelRatio || 1, - backingStoreRatio = - context.webkitBackingStorePixelRatio || - context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || - context.oBackingStorePixelRatio || - context.backingStorePixelRatio || 1; - - this.pixelRatio = devicePixelRatio / backingStoreRatio; - - // Size the canvas to match the internal dimensions of its container - - this.resize(container.width(), container.height()); - - // Collection of HTML div layers for text overlaid onto the canvas - - this.textContainer = null; - this.text = {}; - - // Cache of text fragments and metrics, so we can avoid expensively - // re-calculating them when the plot is re-rendered in a loop. - - this._textCache = {}; - } - - // Resizes the canvas to the given dimensions. - // - // @param {number} width New width of the canvas, in pixels. - // @param {number} width New height of the canvas, in pixels. - - Canvas.prototype.resize = function(width, height) { - - if (width <= 0 || height <= 0) { - throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); - } - - var element = this.element, - context = this.context, - pixelRatio = this.pixelRatio; - - // Resize the canvas, increasing its density based on the display's - // pixel ratio; basically giving it more pixels without increasing the - // size of its element, to take advantage of the fact that retina - // displays have that many more pixels in the same advertised space. - - // Resizing should reset the state (excanvas seems to be buggy though) - - if (this.width != width) { - element.width = width * pixelRatio; - element.style.width = width + "px"; - this.width = width; - } - - if (this.height != height) { - element.height = height * pixelRatio; - element.style.height = height + "px"; - this.height = height; - } - - // Save the context, so we can reset in case we get replotted. The - // restore ensure that we're really back at the initial state, and - // should be safe even if we haven't saved the initial state yet. - - context.restore(); - context.save(); - - // Scale the coordinate space to match the display density; so even though we - // may have twice as many pixels, we still want lines and other drawing to - // appear at the same size; the extra pixels will just make them crisper. - - context.scale(pixelRatio, pixelRatio); - }; - - // Clears the entire canvas area, not including any overlaid HTML text - - Canvas.prototype.clear = function() { - this.context.clearRect(0, 0, this.width, this.height); - }; - - // Finishes rendering the canvas, including managing the text overlay. - - Canvas.prototype.render = function() { - - var cache = this._textCache; - - // For each text layer, add elements marked as active that haven't - // already been rendered, and remove those that are no longer active. - - for (var layerKey in cache) { - if (hasOwnProperty.call(cache, layerKey)) { - - var layer = this.getTextLayer(layerKey), - layerCache = cache[layerKey]; - - layer.hide(); - - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey]; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - - var positions = styleCache[key].positions; - - for (var i = 0, position; position = positions[i]; i++) { - if (position.active) { - if (!position.rendered) { - layer.append(position.element); - position.rendered = true; - } - } else { - positions.splice(i--, 1); - if (position.rendered) { - position.element.detach(); - } - } - } - - if (positions.length == 0) { - delete styleCache[key]; - } - } - } - } - } - - layer.show(); - } - } - }; - - // Creates (if necessary) and returns the text overlay container. - // - // @param {string} classes String of space-separated CSS classes used to - // uniquely identify the text layer. - // @return {object} The jQuery-wrapped text-layer div. - - Canvas.prototype.getTextLayer = function(classes) { - - var layer = this.text[classes]; - - // Create the text layer if it doesn't exist - - if (layer == null) { - - // Create the text layer container, if it doesn't exist - - if (this.textContainer == null) { - this.textContainer = $("
      ") - .css({ - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0, - 'font-size': "smaller", - color: "#545454" - }) - .insertAfter(this.element); - } - - layer = this.text[classes] = $("
      ") - .addClass(classes) - .css({ - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0 - }) - .appendTo(this.textContainer); - } - - return layer; - }; - - // Creates (if necessary) and returns a text info object. - // - // The object looks like this: - // - // { - // width: Width of the text's wrapper div. - // height: Height of the text's wrapper div. - // element: The jQuery-wrapped HTML div containing the text. - // positions: Array of positions at which this text is drawn. - // } - // - // The positions array contains objects that look like this: - // - // { - // active: Flag indicating whether the text should be visible. - // rendered: Flag indicating whether the text is currently visible. - // element: The jQuery-wrapped HTML div containing the text. - // x: X coordinate at which to draw the text. - // y: Y coordinate at which to draw the text. - // } - // - // Each position after the first receives a clone of the original element. - // - // The idea is that that the width, height, and general 'identity' of the - // text is constant no matter where it is placed; the placements are a - // secondary property. - // - // Canvas maintains a cache of recently-used text info objects; getTextInfo - // either returns the cached element or creates a new entry. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {string} text Text string to retrieve info for. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which to rotate the text, in degrees. - // Angle is currently unused, it will be implemented in the future. - // @param {number=} width Maximum width of the text before it wraps. - // @return {object} a text info object. - - Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { - - var textStyle, layerCache, styleCache, info; - - // Cast the value to a string, in case we were given a number or such - - text = "" + text; - - // If the font is a font-spec object, generate a CSS font definition - - if (typeof font === "object") { - textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; - } else { - textStyle = font; - } - - // Retrieve (or create) the cache for the text's layer and styles - - layerCache = this._textCache[layer]; - - if (layerCache == null) { - layerCache = this._textCache[layer] = {}; - } - - styleCache = layerCache[textStyle]; - - if (styleCache == null) { - styleCache = layerCache[textStyle] = {}; - } - - info = styleCache[text]; - - // If we can't find a matching element in our cache, create a new one - - if (info == null) { - - var element = $("
      ").html(text) - .css({ - position: "absolute", - 'max-width': width, - top: -9999 - }) - .appendTo(this.getTextLayer(layer)); - - if (typeof font === "object") { - element.css({ - font: textStyle, - color: font.color - }); - } else if (typeof font === "string") { - element.addClass(font); - } - - info = styleCache[text] = { - width: element.outerWidth(true), - height: element.outerHeight(true), - element: element, - positions: [] - }; - - element.detach(); - } - - return info; - }; - - // Adds a text string to the canvas text overlay. - // - // The text isn't drawn immediately; it is marked as rendering, which will - // result in its addition to the canvas on the next render pass. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {number} x X coordinate at which to draw the text. - // @param {number} y Y coordinate at which to draw the text. - // @param {string} text Text string to draw. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which to rotate the text, in degrees. - // Angle is currently unused, it will be implemented in the future. - // @param {number=} width Maximum width of the text before it wraps. - // @param {string=} halign Horizontal alignment of the text; either "left", - // "center" or "right". - // @param {string=} valign Vertical alignment of the text; either "top", - // "middle" or "bottom". - - Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { - - var info = this.getTextInfo(layer, text, font, angle, width), - positions = info.positions; - - // Tweak the div's position to match the text's alignment - - if (halign == "center") { - x -= info.width / 2; - } else if (halign == "right") { - x -= info.width; - } - - if (valign == "middle") { - y -= info.height / 2; - } else if (valign == "bottom") { - y -= info.height; - } else if (valign == "top") { // onur, add top option - y -= info.height + 2; - } - - // Determine whether this text already exists at this position. - // If so, mark it for inclusion in the next render pass. - - for (var i = 0, position; position = positions[i]; i++) { - if (position.x == x && position.y == y) { - position.active = true; - return; - } - } - - // If the text doesn't exist at this position, create a new entry - - // For the very first position we'll re-use the original element, - // while for subsequent ones we'll clone it. - - position = { - active: true, - rendered: false, - element: positions.length ? info.element.clone() : info.element, - x: x, - y: y - }; - - positions.push(position); - - // Move the element to its final position within the container - - position.element.css({ - top: Math.round(y), - left: Math.round(x), - 'text-align': halign // In case the text wraps - }); - }; - - // Removes one or more text strings from the canvas text overlay. - // - // If no parameters are given, all text within the layer is removed. - // - // Note that the text is not immediately removed; it is simply marked as - // inactive, which will result in its removal on the next render pass. - // This avoids the performance penalty for 'clear and redraw' behavior, - // where we potentially get rid of all text on a layer, but will likely - // add back most or all of it later, as when redrawing axes, for example. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {number=} x X coordinate of the text. - // @param {number=} y Y coordinate of the text. - // @param {string=} text Text string to remove. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which the text is rotated, in degrees. - // Angle is currently unused, it will be implemented in the future. - - Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { - if (text == null) { - var layerCache = this._textCache[layer]; - if (layerCache != null) { - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey]; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - var positions = styleCache[key].positions; - for (var i = 0, position; position = positions[i]; i++) { - position.active = false; - } - } - } - } - } - } - } else { - var positions = this.getTextInfo(layer, text, font, angle).positions; - for (var i = 0, position; position = positions[i]; i++) { - if (position.x == x && position.y == y) { - position.active = false; - } - } - } - }; - - /////////////////////////////////////////////////////////////////////////// - // The top-level container for the entire plot. - - function Plot(placeholder, data_, options_, plugins) { - // data is on the form: - // [ series1, series2 ... ] - // where series is either just the data as [ [x1, y1], [x2, y2], ... ] - // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } - - var series = [], - options = { - // the color theme used for graphs - colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], - legend: { - show: true, - noColumns: 1, // number of colums in legend table - labelFormatter: null, // fn: string -> string - labelBoxBorderColor: "#ccc", // border color for the little label boxes - container: null, // container (as jQuery object) to put legend in, null means default on top of graph - position: "ne", // position of default legend container within plot - margin: 5, // distance from grid edge to default legend container within plot - backgroundColor: null, // null means auto-detect - backgroundOpacity: 0.85, // set to 0 to avoid background - sorted: null // default to no legend sorting - }, - xaxis: { - show: null, // null = auto-detect, true = always, false = never - position: "bottom", // or "top" - mode: null, // null or "time" - font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } - color: null, // base color, labels, ticks - tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" - transform: null, // null or f: number -> number to transform axis - inverseTransform: null, // if transform is set, this should be the inverse function - min: null, // min. value to show, null means set automatically - max: null, // max. value to show, null means set automatically - autoscaleMargin: null, // margin in % to add if auto-setting min/max - ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks - tickFormatter: null, // fn: number -> string - labelWidth: null, // size of tick labels in pixels - labelHeight: null, - reserveSpace: null, // whether to reserve space even if axis isn't shown - tickLength: null, // size in pixels of ticks, or "full" for whole line - alignTicksWithAxis: null, // axis number or null for no sync - tickDecimals: null, // no. of decimals, null means auto - tickSize: null, // number or [number, "unit"] - minTickSize: null // number or [number, "unit"] - }, - yaxis: { - autoscaleMargin: 0.02, - position: "left" // or "right" - }, - xaxes: [], - yaxes: [], - series: { - points: { - show: false, - radius: 3, - lineWidth: 2, // in pixels - fill: true, - fillColor: "#ffffff", - symbol: "circle" // or callback - }, - lines: { - // we don't put in show: false so we can see - // whether lines were actively disabled - lineWidth: 2, // in pixels - fill: false, - fillColor: null, - steps: false - // Omit 'zero', so we can later default its value to - // match that of the 'fill' option. - }, - bars: { - show: false, - lineWidth: 1, // in pixels - barWidth: 1, // in units of the x axis - fill: true, - fillColor: null, - align: "left", // "left", "right", or "center" - horizontal: false, - zero: true - }, - shadowSize: 3, - highlightColor: null - }, - grid: { - show: true, - aboveData: false, - color: "#545454", // primary color used for outline and labels - backgroundColor: null, // null for transparent, else color - borderColor: null, // set if different from the grid color - tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" - margin: 0, // distance from the canvas edge to the grid - labelMargin: 5, // in pixels - axisMargin: 8, // in pixels - borderWidth: 2, // in pixels - minBorderMargin: null, // in pixels, null means taken from points radius - markings: null, // array of ranges or fn: axes -> array of ranges - markingsColor: "#f4f4f4", - markingsLineWidth: 2, - // interactive stuff - clickable: false, - hoverable: false, - autoHighlight: true, // highlight in case mouse is near - mouseActiveRadius: 10 // how far the mouse can be away to activate an item - }, - interaction: { - redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow - }, - hooks: {} - }, - surface = null, // the canvas for the plot itself - overlay = null, // canvas for interactive stuff on top of plot - eventHolder = null, // jQuery object that events should be bound to - ctx = null, octx = null, - xaxes = [], yaxes = [], - plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, - plotWidth = 0, plotHeight = 0, - hooks = { - processOptions: [], - processRawData: [], - processDatapoints: [], - processOffset: [], - drawBackground: [], - drawSeries: [], - draw: [], - bindEvents: [], - drawOverlay: [], - shutdown: [] - }, - plot = this; - - // public functions - plot.setData = setData; - plot.setupGrid = setupGrid; - plot.draw = draw; - plot.getPlaceholder = function() { return placeholder; }; - plot.getCanvas = function() { return surface.element; }; - plot.getPlotOffset = function() { return plotOffset; }; - plot.width = function () { return plotWidth; }; - plot.height = function () { return plotHeight; }; - plot.offset = function () { - var o = eventHolder.offset(); - o.left += plotOffset.left; - o.top += plotOffset.top; - return o; - }; - plot.getData = function () { return series; }; - plot.getAxes = function () { - var res = {}, i; - $.each(xaxes.concat(yaxes), function (_, axis) { - if (axis) - res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; - }); - return res; - }; - plot.getXAxes = function () { return xaxes; }; - plot.getYAxes = function () { return yaxes; }; - plot.c2p = canvasToAxisCoords; - plot.p2c = axisToCanvasCoords; - plot.getOptions = function () { return options; }; - plot.highlight = highlight; - plot.unhighlight = unhighlight; - plot.triggerRedrawOverlay = triggerRedrawOverlay; - plot.pointOffset = function(point) { - return { - left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), - top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) - }; - }; - plot.shutdown = shutdown; - plot.destroy = function () { - shutdown(); - placeholder.removeData("plot").empty(); - - series = []; - options = null; - surface = null; - overlay = null; - eventHolder = null; - ctx = null; - octx = null; - xaxes = []; - yaxes = []; - hooks = null; - highlights = []; - plot = null; - }; - plot.resize = function () { - var width = placeholder.width(), - height = placeholder.height(); - surface.resize(width, height); - overlay.resize(width, height); - }; - - // public attributes - plot.hooks = hooks; - - // initialize - initPlugins(plot); - parseOptions(options_); - setupCanvases(); - setData(data_); - setupGrid(); - draw(); - bindEvents(); - - - function executeHooks(hook, args) { - args = [plot].concat(args); - for (var i = 0; i < hook.length; ++i) - hook[i].apply(this, args); - } - - function initPlugins() { - - // References to key classes, allowing plugins to modify them - - var classes = { - Canvas: Canvas - }; - - for (var i = 0; i < plugins.length; ++i) { - var p = plugins[i]; - p.init(plot, classes); - if (p.options) - $.extend(true, options, p.options); - } - } - - function parseOptions(opts) { - - $.extend(true, options, opts); - - // $.extend merges arrays, rather than replacing them. When less - // colors are provided than the size of the default palette, we - // end up with those colors plus the remaining defaults, which is - // not expected behavior; avoid it by replacing them here. - - if (opts && opts.colors) { - options.colors = opts.colors; - } - - if (options.xaxis.color == null) - options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - if (options.yaxis.color == null) - options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - - if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility - options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; - if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility - options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; - - if (options.grid.borderColor == null) - options.grid.borderColor = options.grid.color; - if (options.grid.tickColor == null) - options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - - // Fill in defaults for axis options, including any unspecified - // font-spec fields, if a font-spec was provided. - - // If no x/y axis options were provided, create one of each anyway, - // since the rest of the code assumes that they exist. - - var i, axisOptions, axisCount, - fontSize = placeholder.css("font-size"), - fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13, - fontDefaults = { - style: placeholder.css("font-style"), - size: Math.round(0.8 * fontSizeDefault), - variant: placeholder.css("font-variant"), - weight: placeholder.css("font-weight"), - family: placeholder.css("font-family") - }; - - axisCount = options.xaxes.length || 1; - for (i = 0; i < axisCount; ++i) { - - axisOptions = options.xaxes[i]; - if (axisOptions && !axisOptions.tickColor) { - axisOptions.tickColor = axisOptions.color; - } - - axisOptions = $.extend(true, {}, options.xaxis, axisOptions); - options.xaxes[i] = axisOptions; - - if (axisOptions.font) { - axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); - if (!axisOptions.font.color) { - axisOptions.font.color = axisOptions.color; - } - if (!axisOptions.font.lineHeight) { - axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); - } - } - } - - axisCount = options.yaxes.length || 1; - for (i = 0; i < axisCount; ++i) { - - axisOptions = options.yaxes[i]; - if (axisOptions && !axisOptions.tickColor) { - axisOptions.tickColor = axisOptions.color; - } - - axisOptions = $.extend(true, {}, options.yaxis, axisOptions); - options.yaxes[i] = axisOptions; - - if (axisOptions.font) { - axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); - if (!axisOptions.font.color) { - axisOptions.font.color = axisOptions.color; - } - if (!axisOptions.font.lineHeight) { - axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); - } - } - } - - // backwards compatibility, to be removed in future - if (options.xaxis.noTicks && options.xaxis.ticks == null) - options.xaxis.ticks = options.xaxis.noTicks; - if (options.yaxis.noTicks && options.yaxis.ticks == null) - options.yaxis.ticks = options.yaxis.noTicks; - if (options.x2axis) { - options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); - options.xaxes[1].position = "top"; - // Override the inherit to allow the axis to auto-scale - if (options.x2axis.min == null) { - options.xaxes[1].min = null; - } - if (options.x2axis.max == null) { - options.xaxes[1].max = null; - } - } - if (options.y2axis) { - options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); - options.yaxes[1].position = "right"; - // Override the inherit to allow the axis to auto-scale - if (options.y2axis.min == null) { - options.yaxes[1].min = null; - } - if (options.y2axis.max == null) { - options.yaxes[1].max = null; - } - } - if (options.grid.coloredAreas) - options.grid.markings = options.grid.coloredAreas; - if (options.grid.coloredAreasColor) - options.grid.markingsColor = options.grid.coloredAreasColor; - if (options.lines) - $.extend(true, options.series.lines, options.lines); - if (options.points) - $.extend(true, options.series.points, options.points); - if (options.bars) - $.extend(true, options.series.bars, options.bars); - if (options.shadowSize != null) - options.series.shadowSize = options.shadowSize; - if (options.highlightColor != null) - options.series.highlightColor = options.highlightColor; - - // save options on axes for future reference - for (i = 0; i < options.xaxes.length; ++i) - getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; - for (i = 0; i < options.yaxes.length; ++i) - getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; - - // add hooks from options - for (var n in hooks) - if (options.hooks[n] && options.hooks[n].length) - hooks[n] = hooks[n].concat(options.hooks[n]); - - executeHooks(hooks.processOptions, [options]); - } - - function setData(d) { - series = parseData(d); - fillInSeriesOptions(); - processData(); - } - - function parseData(d) { - var res = []; - for (var i = 0; i < d.length; ++i) { - var s = $.extend(true, {}, options.series); - - if (d[i].data != null) { - s.data = d[i].data; // move the data instead of deep-copy - delete d[i].data; - - $.extend(true, s, d[i]); - - d[i].data = s.data; - } - else - s.data = d[i]; - res.push(s); - } - - return res; - } - - function axisNumber(obj, coord) { - var a = obj[coord + "axis"]; - if (typeof a == "object") // if we got a real axis, extract number - a = a.n; - if (typeof a != "number") - a = 1; // default to first axis - return a; - } - - function allAxes() { - // return flat array without annoying null entries - return $.grep(xaxes.concat(yaxes), function (a) { return a; }); - } - - function canvasToAxisCoords(pos) { - // return an object with x/y corresponding to all used axes - var res = {}, i, axis; - for (i = 0; i < xaxes.length; ++i) { - axis = xaxes[i]; - if (axis && axis.used) - res["x" + axis.n] = axis.c2p(pos.left); - } - - for (i = 0; i < yaxes.length; ++i) { - axis = yaxes[i]; - if (axis && axis.used) - res["y" + axis.n] = axis.c2p(pos.top); - } - - if (res.x1 !== undefined) - res.x = res.x1; - if (res.y1 !== undefined) - res.y = res.y1; - - return res; - } - - function axisToCanvasCoords(pos) { - // get canvas coords from the first pair of x/y found in pos - var res = {}, i, axis, key; - - for (i = 0; i < xaxes.length; ++i) { - axis = xaxes[i]; - if (axis && axis.used) { - key = "x" + axis.n; - if (pos[key] == null && axis.n == 1) - key = "x"; - - if (pos[key] != null) { - res.left = axis.p2c(pos[key]); - break; - } - } - } - - for (i = 0; i < yaxes.length; ++i) { - axis = yaxes[i]; - if (axis && axis.used) { - key = "y" + axis.n; - if (pos[key] == null && axis.n == 1) - key = "y"; - - if (pos[key] != null) { - res.top = axis.p2c(pos[key]); - break; - } - } - } - - return res; - } - - function getOrCreateAxis(axes, number) { - if (!axes[number - 1]) - axes[number - 1] = { - n: number, // save the number for future reference - direction: axes == xaxes ? "x" : "y", - options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) - }; - - return axes[number - 1]; - } - - function fillInSeriesOptions() { - - var neededColors = series.length, maxIndex = -1, i; - - // Subtract the number of series that already have fixed colors or - // color indexes from the number that we still need to generate. - - for (i = 0; i < series.length; ++i) { - var sc = series[i].color; - if (sc != null) { - neededColors--; - if (typeof sc == "number" && sc > maxIndex) { - maxIndex = sc; - } - } - } - - // If any of the series have fixed color indexes, then we need to - // generate at least as many colors as the highest index. - - if (neededColors <= maxIndex) { - neededColors = maxIndex + 1; - } - - // Generate all the colors, using first the option colors and then - // variations on those colors once they're exhausted. - - var c, colors = [], colorPool = options.colors, - colorPoolSize = colorPool.length, variation = 0; - - for (i = 0; i < neededColors; i++) { - - c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); - - // Each time we exhaust the colors in the pool we adjust - // a scaling factor used to produce more variations on - // those colors. The factor alternates negative/positive - // to produce lighter/darker colors. - - // Reset the variation after every few cycles, or else - // it will end up producing only white or black colors. - - if (i % colorPoolSize == 0 && i) { - if (variation >= 0) { - if (variation < 0.5) { - variation = -variation - 0.2; - } else variation = 0; - } else variation = -variation; - } - - colors[i] = c.scale('rgb', 1 + variation); - } - - // Finalize the series options, filling in their colors - - var colori = 0, s; - for (i = 0; i < series.length; ++i) { - s = series[i]; - - // assign colors - if (s.color == null) { - s.color = colors[colori].toString(); - ++colori; - } - else if (typeof s.color == "number") - s.color = colors[s.color].toString(); - - // turn on lines automatically in case nothing is set - if (s.lines.show == null) { - var v, show = true; - for (v in s) - if (s[v] && s[v].show) { - show = false; - break; - } - if (show) - s.lines.show = true; - } - - // If nothing was provided for lines.zero, default it to match - // lines.fill, since areas by default should extend to zero. - - if (s.lines.zero == null) { - s.lines.zero = !!s.lines.fill; - } - - // setup axes - s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); - s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); - } - } - - function processData() { - var topSentry = Number.POSITIVE_INFINITY, - bottomSentry = Number.NEGATIVE_INFINITY, - fakeInfinity = Number.MAX_VALUE, - i, j, k, m, length, - s, points, ps, x, y, axis, val, f, p, - data, format; - - function updateAxis(axis, min, max) { - if (min < axis.datamin && min != -fakeInfinity) - axis.datamin = min; - if (max > axis.datamax && max != fakeInfinity) - axis.datamax = max; - } - - $.each(allAxes(), function (_, axis) { - // init axis - axis.datamin = topSentry; - axis.datamax = bottomSentry; - axis.used = false; - }); - - for (i = 0; i < series.length; ++i) { - s = series[i]; - s.datapoints = { points: [] }; - - executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); - } - - // first pass: clean and copy data - for (i = 0; i < series.length; ++i) { - s = series[i]; - - data = s.data; - format = s.datapoints.format; - - if (!format) { - format = []; - // find out how to copy - format.push({ x: true, number: true, required: true }); - format.push({ y: true, number: true, required: true }); - - if (s.bars.show || (s.lines.show && s.lines.fill)) { - var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); - format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); - if (s.bars.horizontal) { - delete format[format.length - 1].y; - format[format.length - 1].x = true; - } - } - - s.datapoints.format = format; - } - - if (s.datapoints.pointsize != null) - continue; // already filled in - - s.datapoints.pointsize = format.length; - - ps = s.datapoints.pointsize; - points = s.datapoints.points; - - var insertSteps = s.lines.show && s.lines.steps; - s.xaxis.used = s.yaxis.used = true; - - for (j = k = 0; j < data.length; ++j, k += ps) { - p = data[j]; - - var nullify = p == null; - if (!nullify) { - for (m = 0; m < ps; ++m) { - val = p[m]; - f = format[m]; - - if (f) { - if (f.number && val != null) { - val = +val; // convert to number - if (isNaN(val)) - val = null; - else if (val == Infinity) - val = fakeInfinity; - else if (val == -Infinity) - val = -fakeInfinity; - } - - if (val == null) { - if (f.required) - nullify = true; - - if (f.defaultValue != null) - val = f.defaultValue; - } - } - - points[k + m] = val; - } - } - - if (nullify) { - for (m = 0; m < ps; ++m) { - val = points[k + m]; - if (val != null) { - f = format[m]; - // extract min/max info - if (f.autoscale !== false) { - if (f.x) { - updateAxis(s.xaxis, val, val); - } - if (f.y) { - updateAxis(s.yaxis, val, val); - } - } - } - points[k + m] = null; - } - } - else { - // a little bit of line specific stuff that - // perhaps shouldn't be here, but lacking - // better means... - if (insertSteps && k > 0 - && points[k - ps] != null - && points[k - ps] != points[k] - && points[k - ps + 1] != points[k + 1]) { - // copy the point to make room for a middle point - for (m = 0; m < ps; ++m) - points[k + ps + m] = points[k + m]; - - // middle point has same y - points[k + 1] = points[k - ps + 1]; - - // we've added a point, better reflect that - k += ps; - } - } - } - } - - // give the hooks a chance to run - for (i = 0; i < series.length; ++i) { - s = series[i]; - - executeHooks(hooks.processDatapoints, [ s, s.datapoints]); - } - - // second pass: find datamax/datamin for auto-scaling - for (i = 0; i < series.length; ++i) { - s = series[i]; - points = s.datapoints.points; - ps = s.datapoints.pointsize; - format = s.datapoints.format; - - var xmin = topSentry, ymin = topSentry, - xmax = bottomSentry, ymax = bottomSentry; - - for (j = 0; j < points.length; j += ps) { - if (points[j] == null) - continue; - - for (m = 0; m < ps; ++m) { - val = points[j + m]; - f = format[m]; - if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) - continue; - - if (f.x) { - if (val < xmin) - xmin = val; - if (val > xmax) - xmax = val; - } - if (f.y) { - if (val < ymin) - ymin = val; - if (val > ymax) - ymax = val; - } - } - } - - if (s.bars.show) { - // make sure we got room for the bar on the dancing floor - var delta; - - switch (s.bars.align) { - case "left": - delta = 0; - break; - case "right": - delta = -s.bars.barWidth; - break; - default: - delta = -s.bars.barWidth / 2; - } - - if (s.bars.horizontal) { - ymin += delta; - ymax += delta + s.bars.barWidth; - } - else { - xmin += delta; - xmax += delta + s.bars.barWidth; - } - } - - updateAxis(s.xaxis, xmin, xmax); - updateAxis(s.yaxis, ymin, ymax); - } - - $.each(allAxes(), function (_, axis) { - if (axis.datamin == topSentry) - axis.datamin = null; - if (axis.datamax == bottomSentry) - axis.datamax = null; - }); - } - - function setupCanvases() { - - // Make sure the placeholder is clear of everything except canvases - // from a previous plot in this container that we'll try to re-use. - - placeholder.css("padding", 0) // padding messes up the positioning - .children().filter(function(){ - return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base'); - }).remove(); - - if (placeholder.css("position") == 'static') - placeholder.css("position", "relative"); // for positioning labels and overlay - - surface = new Canvas("flot-base", placeholder); - overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features - - //catch cases when canvas does not exist - surface.width = surface.width || 0; - surface.height = surface.height || 0; - overlay.width = overlay.width || 0; - overlay.height = overlay.height || 0; - - ctx = surface.context; - octx = overlay.context; - - // define which element we're listening for events on - eventHolder = $(overlay.element).unbind(); - - // If we're re-using a plot object, shut down the old one - - var existing = placeholder.data("plot"); - - if (existing) { - existing.shutdown(); - overlay.clear(); - } - - // save in case we get replotted - placeholder.data("plot", plot); - } - - function bindEvents() { - // bind events - if (options.grid.hoverable) { - eventHolder.mousemove(onMouseMove); - - // Use bind, rather than .mouseleave, because we officially - // still support jQuery 1.2.6, which doesn't define a shortcut - // for mouseenter or mouseleave. This was a bug/oversight that - // was fixed somewhere around 1.3.x. We can return to using - // .mouseleave when we drop support for 1.2.6. - - eventHolder.bind("mouseleave", onMouseLeave); - } - - if (options.grid.clickable) - eventHolder.click(onClick); - - executeHooks(hooks.bindEvents, [eventHolder]); - } - - function shutdown() { - if (redrawTimeout) - clearTimeout(redrawTimeout); - - eventHolder.unbind("mousemove", onMouseMove); - eventHolder.unbind("mouseleave", onMouseLeave); - eventHolder.unbind("click", onClick); - - executeHooks(hooks.shutdown, [eventHolder]); - } - - function setTransformationHelpers(axis) { - // set helper functions on the axis, assumes plot area - // has been computed already - - function identity(x) { return x; } - - var s, m, t = axis.options.transform || identity, - it = axis.options.inverseTransform; - - // precompute how much the axis is scaling a point - // in canvas space - if (axis.direction == "x") { - s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); - m = Math.min(t(axis.max), t(axis.min)); - } - else { - s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); - s = -s; - m = Math.max(t(axis.max), t(axis.min)); - } - - // data point to canvas coordinate - if (t == identity) // slight optimization - axis.p2c = function (p) { return (p - m) * s; }; - else - axis.p2c = function (p) { return (t(p) - m) * s; }; - // canvas coordinate to data point - if (!it) - axis.c2p = function (c) { return m + c / s; }; - else - axis.c2p = function (c) { return it(m + c / s); }; - } - - function measureTickLabels(axis) { - - var opts = axis.options, - ticks = axis.ticks || [], - labelWidth = opts.labelWidth || 0, - labelHeight = opts.labelHeight || 0, - maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null), - legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", - layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, - font = opts.font || "flot-tick-label tickLabel"; - - for (var i = 0; i < ticks.length; ++i) { - - var t = ticks[i]; - - if (!t.label) - continue; - - var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); - - labelWidth = Math.max(labelWidth, info.width); - labelHeight = Math.max(labelHeight, info.height); - } - - axis.labelWidth = opts.labelWidth || labelWidth; - axis.labelHeight = opts.labelHeight || labelHeight; - } - - function allocateAxisBoxFirstPhase(axis) { - // find the bounding box of the axis by looking at label - // widths/heights and ticks, make room by diminishing the - // plotOffset; this first phase only looks at one - // dimension per axis, the other dimension depends on the - // other axes so will have to wait - - var lw = axis.labelWidth, - lh = axis.labelHeight, - pos = axis.options.position, - isXAxis = axis.direction === "x", - tickLength = axis.options.tickLength, - axisMargin = options.grid.axisMargin, - padding = options.grid.labelMargin, - innermost = true, - outermost = true, - first = true, - found = false; - - // Determine the axis's position in its direction and on its side - - $.each(isXAxis ? xaxes : yaxes, function(i, a) { - if (a && (a.show || a.reserveSpace)) { - if (a === axis) { - found = true; - } else if (a.options.position === pos) { - if (found) { - outermost = false; - } else { - innermost = false; - } - } - if (!found) { - first = false; - } - } - }); - - // The outermost axis on each side has no margin - - if (outermost) { - axisMargin = 0; - } - - // The ticks for the first axis in each direction stretch across - - if (tickLength == null) { - tickLength = first ? "full" : 5; - } - - if (!isNaN(+tickLength)) - padding += +tickLength; - - if (isXAxis) { - lh += padding; - - if (pos == "bottom") { - plotOffset.bottom += lh + axisMargin; - axis.box = { top: surface.height - plotOffset.bottom, height: lh }; - } - else { - axis.box = { top: plotOffset.top + axisMargin, height: lh }; - plotOffset.top += lh + axisMargin; - } - } - else { - lw += padding; - - if (pos == "left") { - axis.box = { left: plotOffset.left + axisMargin, width: lw }; - plotOffset.left += lw + axisMargin; - } - else { - plotOffset.right += lw + axisMargin; - axis.box = { left: surface.width - plotOffset.right, width: lw }; - } - } - - // save for future reference - axis.position = pos; - axis.tickLength = tickLength; - axis.box.padding = padding; - axis.innermost = innermost; - } - - function allocateAxisBoxSecondPhase(axis) { - // now that all axis boxes have been placed in one - // dimension, we can set the remaining dimension coordinates - if (axis.direction == "x") { - axis.box.left = plotOffset.left - axis.labelWidth / 2; - axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; - } - else { - axis.box.top = plotOffset.top - axis.labelHeight / 2; - axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; - } - } - - function adjustLayoutForThingsStickingOut() { - // possibly adjust plot offset to ensure everything stays - // inside the canvas and isn't clipped off - - var minMargin = options.grid.minBorderMargin, - axis, i; - - // check stuff from the plot (FIXME: this should just read - // a value from the series, otherwise it's impossible to - // customize) - if (minMargin == null) { - minMargin = 0; - for (i = 0; i < series.length; ++i) - minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); - } - - var margins = { - left: minMargin, - right: minMargin, - top: minMargin, - bottom: minMargin - }; - - // check axis labels, note we don't check the actual - // labels but instead use the overall width/height to not - // jump as much around with replots - $.each(allAxes(), function (_, axis) { - if (axis.reserveSpace && axis.ticks && axis.ticks.length) { - if (axis.direction === "x") { - margins.left = Math.max(margins.left, axis.labelWidth / 2); - margins.right = Math.max(margins.right, axis.labelWidth / 2); - } else { - margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); - margins.top = Math.max(margins.top, axis.labelHeight / 2); - } - } - }); - - // onur, left and right are fixed values now - plotOffset.left = 10; // Math.ceil(Math.max(margins.left, plotOffset.left)); - plotOffset.right = 10; // Math.ceil(Math.max(margins.right, plotOffset.right)); - plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); - plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); - } - - function setupGrid() { - var i, axes = allAxes(), showGrid = options.grid.show; - - // Initialize the plot's offset from the edge of the canvas - - for (var a in plotOffset) { - var margin = options.grid.margin || 0; - plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; - } - - executeHooks(hooks.processOffset, [plotOffset]); - - // If the grid is visible, add its border width to the offset - - for (var a in plotOffset) { - if(typeof(options.grid.borderWidth) == "object") { - plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; - } - else { - plotOffset[a] += showGrid ? options.grid.borderWidth : 0; - } - } - - $.each(axes, function (_, axis) { - var axisOpts = axis.options; - axis.show = axisOpts.show == null ? axis.used : axisOpts.show; - axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace; - setRange(axis); - }); - - if (showGrid) { - - var allocatedAxes = $.grep(axes, function (axis) { - return axis.show || axis.reserveSpace; - }); - - $.each(allocatedAxes, function (_, axis) { - // make the ticks - setupTickGeneration(axis); - setTicks(axis); - snapRangeToTicks(axis, axis.ticks); - // find labelWidth/Height for axis - measureTickLabels(axis); - }); - - // with all dimensions calculated, we can compute the - // axis bounding boxes, start from the outside - // (reverse order) - for (i = allocatedAxes.length - 1; i >= 0; --i) - allocateAxisBoxFirstPhase(allocatedAxes[i]); - - // make sure we've got enough space for things that - // might stick out - adjustLayoutForThingsStickingOut(); - - $.each(allocatedAxes, function (_, axis) { - allocateAxisBoxSecondPhase(axis); - }); - } - - plotWidth = surface.width - plotOffset.left - plotOffset.right; - plotHeight = surface.height - plotOffset.bottom - plotOffset.top; - - // now we got the proper plot dimensions, we can compute the scaling - $.each(axes, function (_, axis) { - setTransformationHelpers(axis); - }); - - if (showGrid) { - drawAxisLabels(); - } - - insertLegend(); - } - - function setRange(axis) { - var opts = axis.options, - min = +(opts.min != null ? opts.min : axis.datamin), - max = +(opts.max != null ? opts.max : axis.datamax), - delta = max - min; - - if (delta == 0.0) { - // degenerate case - var widen = max == 0 ? 1 : 0.01; - - if (opts.min == null) - min -= widen; - // always widen max if we couldn't widen min to ensure we - // don't fall into min == max which doesn't work - if (opts.max == null || opts.min != null) - max += widen; - } - else { - // consider autoscaling - var margin = opts.autoscaleMargin; - if (margin != null) { - if (opts.min == null) { - min -= delta * margin; - // make sure we don't go below zero if all values - // are positive - if (min < 0 && axis.datamin != null && axis.datamin >= 0) - min = 0; - } - if (opts.max == null) { - max += delta * margin; - if (max > 0 && axis.datamax != null && axis.datamax <= 0) - max = 0; - } - } - } - axis.min = min; - axis.max = max; - } - - function setupTickGeneration(axis) { - var opts = axis.options; - - // estimate number of ticks - var noTicks; - if (typeof opts.ticks == "number" && opts.ticks > 0) - noTicks = opts.ticks; - else - // heuristic based on the model a*sqrt(x) fitted to - // some data points that seemed reasonable - noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); - - var delta = (axis.max - axis.min) / noTicks, - dec = -Math.floor(Math.log(delta) / Math.LN10), - maxDec = opts.tickDecimals; - - if (maxDec != null && dec > maxDec) { - dec = maxDec; - } - - var magn = Math.pow(10, -dec), - norm = delta / magn, // norm is between 1.0 and 10.0 - size; - - if (norm < 1.5) { - size = 1; - } else if (norm < 3) { - size = 2; - // special case for 2.5, requires an extra decimal - if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { - size = 2.5; - ++dec; - } - } else if (norm < 7.5) { - size = 5; - } else { - size = 10; - } - - size *= magn; - - if (opts.minTickSize != null && size < opts.minTickSize) { - size = opts.minTickSize; - } - - axis.delta = delta; - axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); - axis.tickSize = opts.tickSize || size; - - // Time mode was moved to a plug-in in 0.8, and since so many people use it - // we'll add an especially friendly reminder to make sure they included it. - - if (opts.mode == "time" && !axis.tickGenerator) { - throw new Error("Time mode requires the flot.time plugin."); - } - - // Flot supports base-10 axes; any other mode else is handled by a plug-in, - // like flot.time.js. - - if (!axis.tickGenerator) { - - axis.tickGenerator = function (axis) { - - var ticks = [], - start = floorInBase(axis.min, axis.tickSize), - i = 0, - v = Number.NaN, - prev; - - do { - prev = v; - v = start + i * axis.tickSize; - ticks.push(v); - ++i; - } while (v < axis.max && v != prev); - return ticks; - }; - - axis.tickFormatter = function (value, axis) { - - var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; - var formatted = "" + Math.round(value * factor) / factor; - - // If tickDecimals was specified, ensure that we have exactly that - // much precision; otherwise default to the value's own precision. - - if (axis.tickDecimals != null) { - var decimal = formatted.indexOf("."); - var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; - if (precision < axis.tickDecimals) { - return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); - } - } - - return formatted; - }; - } - - if ($.isFunction(opts.tickFormatter)) - axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; - - if (opts.alignTicksWithAxis != null) { - var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; - if (otherAxis && otherAxis.used && otherAxis != axis) { - // consider snapping min/max to outermost nice ticks - var niceTicks = axis.tickGenerator(axis); - if (niceTicks.length > 0) { - if (opts.min == null) - axis.min = Math.min(axis.min, niceTicks[0]); - if (opts.max == null && niceTicks.length > 1) - axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); - } - - axis.tickGenerator = function (axis) { - // copy ticks, scaled to this axis - var ticks = [], v, i; - for (i = 0; i < otherAxis.ticks.length; ++i) { - v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); - v = axis.min + v * (axis.max - axis.min); - ticks.push(v); - } - return ticks; - }; - - // we might need an extra decimal since forced - // ticks don't necessarily fit naturally - if (!axis.mode && opts.tickDecimals == null) { - var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), - ts = axis.tickGenerator(axis); - - // only proceed if the tick interval rounded - // with an extra decimal doesn't give us a - // zero at end - if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) - axis.tickDecimals = extraDec; - } - } - } - } - - function setTicks(axis) { - var oticks = axis.options.ticks, ticks = []; - if (oticks == null || (typeof oticks == "number" && oticks > 0)) - ticks = axis.tickGenerator(axis); - else if (oticks) { - if ($.isFunction(oticks)) - // generate the ticks - ticks = oticks(axis); - else - ticks = oticks; - } - - var isYAxisTick = (axis && axis.direction == "y"); - - // clean up/labelify the supplied ticks, copy them over - var i, v; - axis.ticks = []; - for (i = 0; i < ticks.length; ++i) { - var label = null; - var t = ticks[i]; - if (typeof t == "object") { - v = +t[0]; - if (t.length > 1) - label = t[1]; - } - else - v = +t; - if (label == null) - label = axis.tickFormatter(v, axis); - - if (!isNaN(v)) { - if (isYAxisTick) { - //onur: Set yAxis ticks as short numbers such as 1B, 1M, 1K - axis.ticks.push({v: v, label: countlyCommon.getShortNumber(label)}); - } else { - axis.ticks.push({v: v, label: label}); - } - } - } - } - - function snapRangeToTicks(axis, ticks) { - if (axis.options.autoscaleMargin && ticks.length > 0) { - // snap to ticks - if (axis.options.min == null) - axis.min = Math.min(axis.min, ticks[0].v); - if (axis.options.max == null && ticks.length > 1) - axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); - } - } - - function draw() { - - surface.clear(); - - executeHooks(hooks.drawBackground, [ctx]); - - var grid = options.grid; - - // draw background, if any - if (grid.show && grid.backgroundColor) - drawBackground(); - - if (grid.show && !grid.aboveData) { - drawGrid(); - } - - for (var i = 0; i < series.length; ++i) { - executeHooks(hooks.drawSeries, [ctx, series[i]]); - drawSeries(series[i]); - } - - executeHooks(hooks.draw, [ctx]); - - if (grid.show && grid.aboveData) { - drawGrid(); - } - - surface.render(); - - // A draw implies that either the axes or data have changed, so we - // should probably update the overlay highlights as well. - - triggerRedrawOverlay(); - } - - function extractRange(ranges, coord) { - var axis, from, to, key, axes = allAxes(); - - for (var i = 0; i < axes.length; ++i) { - axis = axes[i]; - if (axis.direction == coord) { - key = coord + axis.n + "axis"; - if (!ranges[key] && axis.n == 1) - key = coord + "axis"; // support x1axis as xaxis - if (ranges[key]) { - from = ranges[key].from; - to = ranges[key].to; - break; - } - } - } - - // backwards-compat stuff - to be removed in future - if (!ranges[key]) { - axis = coord == "x" ? xaxes[0] : yaxes[0]; - from = ranges[coord + "1"]; - to = ranges[coord + "2"]; - } - - // auto-reverse as an added bonus - if (from != null && to != null && from > to) { - var tmp = from; - from = to; - to = tmp; - } - - return { from: from, to: to, axis: axis }; - } - - function drawBackground() { - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); - ctx.fillRect(0, 0, plotWidth, plotHeight); - ctx.restore(); - } - - function drawGrid() { - var i, axes, bw, bc; - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - // draw markings - var markings = options.grid.markings; - if (markings) { - if ($.isFunction(markings)) { - axes = plot.getAxes(); - // xmin etc. is backwards compatibility, to be - // removed in the future - axes.xmin = axes.xaxis.min; - axes.xmax = axes.xaxis.max; - axes.ymin = axes.yaxis.min; - axes.ymax = axes.yaxis.max; - - markings = markings(axes); - } - - for (i = 0; i < markings.length; ++i) { - var m = markings[i], - xrange = extractRange(m, "x"), - yrange = extractRange(m, "y"); - - // fill in missing - if (xrange.from == null) - xrange.from = xrange.axis.min; - if (xrange.to == null) - xrange.to = xrange.axis.max; - if (yrange.from == null) - yrange.from = yrange.axis.min; - if (yrange.to == null) - yrange.to = yrange.axis.max; - - // clip - if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || - yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) - continue; - - xrange.from = Math.max(xrange.from, xrange.axis.min); - xrange.to = Math.min(xrange.to, xrange.axis.max); - yrange.from = Math.max(yrange.from, yrange.axis.min); - yrange.to = Math.min(yrange.to, yrange.axis.max); - - var xequal = xrange.from === xrange.to, - yequal = yrange.from === yrange.to; - - if (xequal && yequal) { - continue; - } - - // then draw - xrange.from = Math.floor(xrange.axis.p2c(xrange.from)); - xrange.to = Math.floor(xrange.axis.p2c(xrange.to)); - yrange.from = Math.floor(yrange.axis.p2c(yrange.from)); - yrange.to = Math.floor(yrange.axis.p2c(yrange.to)); - - if (xequal || yequal) { - var lineWidth = m.lineWidth || options.grid.markingsLineWidth, - subPixel = lineWidth % 2 ? 0.5 : 0; - ctx.beginPath(); - ctx.strokeStyle = m.color || options.grid.markingsColor; - ctx.lineWidth = lineWidth; - if (xequal) { - ctx.moveTo(xrange.to + subPixel, yrange.from); - ctx.lineTo(xrange.to + subPixel, yrange.to); - } else { - ctx.moveTo(xrange.from, yrange.to + subPixel); - ctx.lineTo(xrange.to, yrange.to + subPixel); - } - ctx.stroke(); - } else { - ctx.fillStyle = m.color || options.grid.markingsColor; - ctx.fillRect(xrange.from, yrange.to, - xrange.to - xrange.from, - yrange.from - yrange.to); - } - } - } - - // draw the ticks - axes = allAxes(); - bw = options.grid.borderWidth; - - for (var j = 0; j < axes.length; ++j) { - var axis = axes[j], box = axis.box, - t = axis.tickLength, x, y, xoff, yoff; - if (!axis.show || axis.ticks.length == 0) - continue; - - ctx.lineWidth = 1; - - // find the edges - if (axis.direction == "x") { - x = 0; - if (t == "full") - y = (axis.position == "top" ? 0 : plotHeight); - else - y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); - } - else { - y = 0; - if (t == "full") - x = (axis.position == "left" ? 0 : plotWidth); - else - x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); - } - - // draw tick bar - if (!axis.innermost) { - ctx.strokeStyle = axis.options.color; - ctx.beginPath(); - xoff = yoff = 0; - if (axis.direction == "x") - xoff = plotWidth + 1; - else - yoff = plotHeight + 1; - - if (ctx.lineWidth == 1) { - if (axis.direction == "x") { - y = Math.floor(y) + 0.5; - } else { - x = Math.floor(x) + 0.5; - } - } - - ctx.moveTo(x, y); - ctx.lineTo(x + xoff, y + yoff); - ctx.stroke(); - } - - // draw ticks - - ctx.strokeStyle = axis.options.tickColor; - - ctx.beginPath(); - for (i = 0; i < axis.ticks.length; ++i) { - var v = axis.ticks[i].v; - - xoff = yoff = 0; - - if (isNaN(v) || v < axis.min || v > axis.max - // skip those lying on the axes if we got a border - || (t == "full" - && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) - && (v == axis.min || v == axis.max))) - continue; - - if (axis.direction == "x") { - x = axis.p2c(v); - yoff = t == "full" ? -plotHeight : t; - - if (axis.position == "top") - yoff = -yoff; - } - else { - y = axis.p2c(v); - xoff = t == "full" ? -plotWidth : t; - - if (axis.position == "left") - xoff = -xoff; - } - - if (ctx.lineWidth == 1) { - if (axis.direction == "x") - x = Math.floor(x) + 0.5; - else - y = Math.floor(y) + 0.5; - } - - // onur, add dashedLine to all grid lines except first one - if (v == 0) { - ctx.moveTo(x, y); - ctx.lineTo(x + xoff, y + yoff); - } else { - ctx.dashedLineTo(x, y, x + xoff, y + yoff, [5,5]); - } - - // onur, comment out since above logic is used - //ctx.moveTo(x, y); - //ctx.lineTo(x + xoff, y + yoff); - } - - ctx.stroke(); - } - - - // draw border - if (bw) { - // If either borderWidth or borderColor is an object, then draw the border - // line by line instead of as one rectangle - bc = options.grid.borderColor; - if(typeof bw == "object" || typeof bc == "object") { - if (typeof bw !== "object") { - bw = {top: bw, right: bw, bottom: bw, left: bw}; - } - if (typeof bc !== "object") { - bc = {top: bc, right: bc, bottom: bc, left: bc}; - } - - if (bw.top > 0) { - ctx.strokeStyle = bc.top; - ctx.lineWidth = bw.top; - ctx.beginPath(); - ctx.moveTo(0 - bw.left, 0 - bw.top/2); - ctx.lineTo(plotWidth, 0 - bw.top/2); - ctx.stroke(); - } - - if (bw.right > 0) { - ctx.strokeStyle = bc.right; - ctx.lineWidth = bw.right; - ctx.beginPath(); - ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); - ctx.lineTo(plotWidth + bw.right / 2, plotHeight); - ctx.stroke(); - } - - if (bw.bottom > 0) { - ctx.strokeStyle = bc.bottom; - ctx.lineWidth = bw.bottom; - ctx.beginPath(); - ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); - ctx.lineTo(0, plotHeight + bw.bottom / 2); - ctx.stroke(); - } - - if (bw.left > 0) { - ctx.strokeStyle = bc.left; - ctx.lineWidth = bw.left; - ctx.beginPath(); - ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); - ctx.lineTo(0- bw.left/2, 0); - ctx.stroke(); - } - } - else { - ctx.lineWidth = bw; - ctx.strokeStyle = options.grid.borderColor; - ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); - } - } - - ctx.restore(); - } - - function drawAxisLabels() { - - $.each(allAxes(), function (_, axis) { - var box = axis.box, - legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", - layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, - font = axis.options.font || "flot-tick-label tickLabel", - tick, x, y, halign, valign; - - // Remove text before checking for axis.show and ticks.length; - // otherwise plugins, like flot-tickrotor, that draw their own - // tick labels will end up with both theirs and the defaults. - - surface.removeText(layer); - - if (!axis.show || axis.ticks.length == 0) - return; - - for (var i = 0; i < axis.ticks.length; ++i) { - - tick = axis.ticks[i]; - if (!tick.label || tick.v < axis.min || tick.v > axis.max) - continue; - - if (axis.direction == "x") { - halign = "center"; - x = plotOffset.left + axis.p2c(tick.v); - if (axis.position == "bottom") { - y = box.top + box.padding; - } else { - y = box.top + box.height - box.padding; - valign = "bottom"; - } - } else { - // onur, add skip 0 - if (!axis.options.showZeroTick && tick.v == 0) { - continue; - } - - //onur, change overall y axis calculations - - valign = "top"; - y = plotOffset.top + axis.p2c(tick.v) + 10; - - halign = "right"; - - if (box.width > 20) { - x = Math.ceil(box.width / 2) + 4; - } else if (box.width <= 10) { - x = 15; - } else { - x = box.width; - } - - x -= 15; - - // onur, draw the same y axis ticks to left first - surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); - - halign = "left"; - - if (box.width > 20) { - x = box.left + Math.ceil(box.width / 3); - } else if (box.width <= 10) { - x = box.left - 8; - } else { - x = box.left; - } - - x += 15; - } - - surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); - } - }); - } - - function drawSeries(series) { - if (series.lines.show) - drawSeriesLines(series); - if (series.bars.show) - drawSeriesBars(series); - if (series.points.show) - drawSeriesPoints(series); - } - - function drawSeriesLines(series) { - function plotLine(datapoints, xoffset, yoffset, axisx, axisy, options) { - var points = datapoints.points, - ps = datapoints.pointsize, - prevx = null, prevy = null, - dashed = false, - dashAfter = -1; - if(options){ - dashed = options.dashed; - dashAfter = options.dashAfter; - if(options.alpha){ - ctx.globalAlpha = options.alpha; - } - } - - ctx.beginPath(); - if(dashed) { - ctx.setLineDash([4, 4]); - } - for (var i = ps; i < points.length; i += ps) { - if(dashAfter && (dashAfter*ps) < i){ - ctx.stroke(); - ctx.beginPath(); - ctx.moveTo(axisx.p2c(prevx) + xoffset, axisy.p2c(prevy) + yoffset); - ctx.setLineDash([4, 4]); - dashAfter = -1; //to not set again; - } - var x1 = points[i - ps], y1 = points[i - ps + 1], - x2 = points[i], y2 = points[i + 1]; - - if (x1 == null || x2 == null) - continue; - - // clip with ymin - if (y1 <= y2 && y1 < axisy.min) { - if (y2 < axisy.min) - continue; // line segment is outside - // compute new intersection point - x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.min; - } - else if (y2 <= y1 && y2 < axisy.min) { - if (y1 < axisy.min) - continue; - x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.min; - } - - // clip with ymax - if (y1 >= y2 && y1 > axisy.max) { - if (y2 > axisy.max) - continue; - x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.max; - } - else if (y2 >= y1 && y2 > axisy.max) { - if (y1 > axisy.max) - continue; - x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.max; - } - - // clip with xmin - if (x1 <= x2 && x1 < axisx.min) { - if (x2 < axisx.min) - continue; - y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.min; - } - else if (x2 <= x1 && x2 < axisx.min) { - if (x1 < axisx.min) - continue; - y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.min; - } - - // clip with xmax - if (x1 >= x2 && x1 > axisx.max) { - if (x2 > axisx.max) - continue; - y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.max; - } - else if (x2 >= x1 && x2 > axisx.max) { - if (x1 > axisx.max) - continue; - y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.max; - } - - if (x1 != prevx || y1 != prevy) - ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); - - prevx = x2; - prevy = y2; - ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); - } - ctx.stroke(); - ctx.globalAlpha = 1.0; - } - - function plotLineArea(datapoints, axisx, axisy) { - var points = datapoints.points, - ps = datapoints.pointsize, - bottom = Math.min(Math.max(0, axisy.min), axisy.max), - i = 0, top, areaOpen = false, - ypos = 1, segmentStart = 0, segmentEnd = 0; - - // we process each segment in two turns, first forward - // direction to sketch out top, then once we hit the - // end we go backwards to sketch the bottom - while (true) { - if (ps > 0 && i > points.length + ps) - break; - - i += ps; // ps is negative if going backwards - - var x1 = points[i - ps], - y1 = points[i - ps + ypos], - x2 = points[i], y2 = points[i + ypos]; - - if (areaOpen) { - if (ps > 0 && x1 != null && x2 == null) { - // at turning point - segmentEnd = i; - ps = -ps; - ypos = 2; - continue; - } - - if (ps < 0 && i == segmentStart + ps) { - // done with the reverse sweep - ctx.fill(); - areaOpen = false; - ps = -ps; - ypos = 1; - i = segmentStart = segmentEnd + ps; - continue; - } - } - - if (x1 == null || x2 == null) - continue; - - // clip x values - - // clip with xmin - if (x1 <= x2 && x1 < axisx.min) { - if (x2 < axisx.min) - continue; - y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.min; - } - else if (x2 <= x1 && x2 < axisx.min) { - if (x1 < axisx.min) - continue; - y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.min; - } - - // clip with xmax - if (x1 >= x2 && x1 > axisx.max) { - if (x2 > axisx.max) - continue; - y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.max; - } - else if (x2 >= x1 && x2 > axisx.max) { - if (x1 > axisx.max) - continue; - y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.max; - } - - if (!areaOpen) { - // open area - ctx.beginPath(); - ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); - areaOpen = true; - } - - // now first check the case where both is outside - if (y1 >= axisy.max && y2 >= axisy.max) { - ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); - continue; - } - else if (y1 <= axisy.min && y2 <= axisy.min) { - ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); - continue; - } - - // else it's a bit more complicated, there might - // be a flat maxed out rectangle first, then a - // triangular cutout or reverse; to find these - // keep track of the current x values - var x1old = x1, x2old = x2; - - // clip the y values, without shortcutting, we - // go through all cases in turn - - // clip with ymin - if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { - x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.min; - } - else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { - x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.min; - } - - // clip with ymax - if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { - x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.max; - } - else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { - x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.max; - } - - // if the x value was changed we got a rectangle - // to fill - if (x1 != x1old) { - ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); - // it goes to (x1, y1), but we fill that below - } - - // fill triangular section, this sometimes result - // in redundant points if (x1, y1) hasn't changed - // from previous line to, but we just ignore that - ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); - - // fill the other rectangle if it's there - if (x2 != x2old) { - ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); - ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); - } - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - ctx.lineJoin = "round"; - - var lw = series.lines.lineWidth, - sw = series.shadowSize; - // FIXME: consider another form of shadow when filling is turned on - if (lw > 0 && sw > 0) { - // draw shadow as a thick and thin line with transparency - ctx.lineWidth = sw; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - // position shadow at angle from the mid of line - var angle = Math.PI/18; - plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); - ctx.lineWidth = sw/2; - plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); - if (fillStyle) { - ctx.fillStyle = fillStyle; - plotLineArea(series.datapoints, series.xaxis, series.yaxis); - } - - if (lw > 0) - plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis,{alpha:series.alpha,dashed: series.dashed, dashAfter: series.dashAfter}); - ctx.restore(); - } - - function drawSeriesPoints(series) { - function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { - var points = datapoints.points, ps = datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - var x = points[i], y = points[i + 1]; - if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) - continue; - - ctx.beginPath(); - x = axisx.p2c(x); - y = axisy.p2c(y) + offset; - if (symbol == "circle") - ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); - else - symbol(ctx, x, y, radius, shadow); - ctx.closePath(); - - if (fillStyle) { - ctx.fillStyle = fillStyle; - ctx.fill(); - } - ctx.stroke(); - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - var lw = series.points.lineWidth, - sw = series.shadowSize, - radius = series.points.radius, - symbol = series.points.symbol; - - // If the user sets the line width to 0, we change it to a very - // small value. A line width of 0 seems to force the default of 1. - // Doing the conditional here allows the shadow setting to still be - // optional even with a lineWidth of 0. - - if( lw == 0 ) - lw = 0.0001; - - if (lw > 0 && sw > 0) { - // draw shadow in two steps - var w = sw / 2; - ctx.lineWidth = w; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - plotPoints(series.datapoints, radius, null, w + w/2, true, - series.xaxis, series.yaxis, symbol); - - ctx.strokeStyle = "rgba(0,0,0,0.2)"; - plotPoints(series.datapoints, radius, null, w/2, true, - series.xaxis, series.yaxis, symbol); - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - plotPoints(series.datapoints, radius, - getFillStyle(series.points, series.color), 0, false, - series.xaxis, series.yaxis, symbol); - ctx.restore(); - } - - function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { - var left, right, bottom, top, - drawLeft, drawRight, drawTop, drawBottom, - tmp; - - // in horizontal mode, we start the bar from the left - // instead of from the bottom so it appears to be - // horizontal rather than vertical - if (horizontal) { - drawBottom = drawRight = drawTop = true; - drawLeft = false; - left = b; - right = x; - top = y + barLeft; - bottom = y + barRight; - - // account for negative bars - if (right < left) { - tmp = right; - right = left; - left = tmp; - drawLeft = true; - drawRight = false; - } - } - else { - drawLeft = drawRight = drawTop = true; - drawBottom = false; - left = x + barLeft; - right = x + barRight; - bottom = b; - top = y; - - // account for negative bars - if (top < bottom) { - tmp = top; - top = bottom; - bottom = tmp; - drawBottom = true; - drawTop = false; - } - } - - // clip - if (right < axisx.min || left > axisx.max || - top < axisy.min || bottom > axisy.max) - return; - - if (left < axisx.min) { - left = axisx.min; - drawLeft = false; - } - - if (right > axisx.max) { - right = axisx.max; - drawRight = false; - } - - if (bottom < axisy.min) { - bottom = axisy.min; - drawBottom = false; - } - - if (top > axisy.max) { - top = axisy.max; - drawTop = false; - } - - left = axisx.p2c(left); - bottom = axisy.p2c(bottom); - right = axisx.p2c(right); - top = axisy.p2c(top); - - // fill the bar - if (fillStyleCallback) { - c.fillStyle = fillStyleCallback(bottom, top); - c.fillRect(left, top, right - left, bottom - top) - } - - // draw outline - if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { - c.beginPath(); - - // FIXME: inline moveTo is buggy with excanvas - c.moveTo(left, bottom); - if (drawLeft) - c.lineTo(left, top); - else - c.moveTo(left, top); - if (drawTop) - c.lineTo(right, top); - else - c.moveTo(right, top); - if (drawRight) - c.lineTo(right, bottom); - else - c.moveTo(right, bottom); - if (drawBottom) - c.lineTo(left, bottom); - else - c.moveTo(left, bottom); - c.stroke(); - } - } - - function drawSeriesBars(series) { - function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { - var points = datapoints.points, ps = datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - if (points[i] == null) - continue; - drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - // FIXME: figure out a way to add shadows (for instance along the right edge) - ctx.lineWidth = series.bars.lineWidth; - ctx.strokeStyle = series.color; - - var barLeft; - - switch (series.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -series.bars.barWidth; - break; - default: - barLeft = -series.bars.barWidth / 2; - } - - var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; - plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); - ctx.restore(); - } - - function getFillStyle(filloptions, seriesColor, bottom, top) { - var fill = filloptions.fill; - if (!fill) - return null; - - if (filloptions.fillColor) - return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); - - var c = $.color.parse(seriesColor); - c.a = typeof fill == "number" ? fill : 0.4; - c.normalize(); - return c.toString(); - } - - function insertLegend() { - - if (options.legend.container != null) { - $(options.legend.container).html(""); - } else { - placeholder.find(".legend").remove(); - } - - if (!options.legend.show) { - return; - } - - var fragments = [], entries = [], rowStarted = false, - lf = options.legend.labelFormatter, s, label; - - // Build a list of legend entries, with each having a label and a color - - for (var i = 0; i < series.length; ++i) { - s = series[i]; - if (s.label) { - label = lf ? lf(s.label, s) : s.label; - if (label) { - entries.push({ - label: label, - color: s.color - }); - } - } - } - - // Sort the legend using either the default or a custom comparator - - if (options.legend.sorted) { - if ($.isFunction(options.legend.sorted)) { - entries.sort(options.legend.sorted); - } else if (options.legend.sorted == "reverse") { - entries.reverse(); - } else { - var ascending = options.legend.sorted != "descending"; - entries.sort(function(a, b) { - return a.label == b.label ? 0 : ( - (a.label < b.label) != ascending ? 1 : -1 // Logical XOR - ); - }); - } - } - - // Generate markup for the list of entries, in their final order - - for (var i = 0; i < entries.length; ++i) { - - var entry = entries[i]; - - if (i % options.legend.noColumns == 0) { - if (rowStarted) - fragments.push(''); - fragments.push(''); - rowStarted = true; - } - - fragments.push( - '
      ' + - '' + entry.label + '' - ); - } - - if (rowStarted) - fragments.push(''); - - if (fragments.length == 0) - return; - - var table = '' + fragments.join("") + '
      '; - if (options.legend.container != null) - $(options.legend.container).html(table); - else { - var pos = "", - p = options.legend.position, - m = options.legend.margin; - if (m[0] == null) - m = [m, m]; - if (p.charAt(0) == "n") - pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; - else if (p.charAt(0) == "s") - pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; - if (p.charAt(1) == "e") - pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; - else if (p.charAt(1) == "w") - pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; - var legend = $('
      ' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
      ').appendTo(placeholder); - if (options.legend.backgroundOpacity != 0.0) { - // put in the transparent background - // separately to avoid blended labels and - // label boxes - var c = options.legend.backgroundColor; - if (c == null) { - c = options.grid.backgroundColor; - if (c && typeof c == "string") - c = $.color.parse(c); - else - c = $.color.extract(legend, 'background-color'); - c.a = 1; - c = c.toString(); - } - var div = legend.children(); - $('
      ').prependTo(legend).css('opacity', options.legend.backgroundOpacity); - } - } - } - - - // interactive features - - var highlights = [], - redrawTimeout = null; - - // returns the data item the mouse is over, or null if none is found - function findNearbyItem(mouseX, mouseY, seriesFilter) { - var maxDistance = options.grid.mouseActiveRadius, - smallestDistance = maxDistance * maxDistance + 1, - item = null, foundPoint = false, i, j, ps; - - for (i = series.length - 1; i >= 0; --i) { - if (!seriesFilter(series[i])) - continue; - - var s = series[i], - axisx = s.xaxis, - axisy = s.yaxis, - points = s.datapoints.points, - mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster - my = axisy.c2p(mouseY), - maxx = maxDistance / axisx.scale, - maxy = maxDistance / axisy.scale; - - ps = s.datapoints.pointsize; - // with inverse transforms, we can't use the maxx/maxy - // optimization, sadly - if (axisx.options.inverseTransform) - maxx = Number.MAX_VALUE; - if (axisy.options.inverseTransform) - maxy = Number.MAX_VALUE; - - if (s.lines.show || s.points.show) { - for (j = 0; j < points.length; j += ps) { - var x = points[j], y = points[j + 1]; - if (x == null) - continue; - - // For points and lines, the cursor must be within a - // certain distance to the data point - if (x - mx > maxx || x - mx < -maxx || - y - my > maxy || y - my < -maxy) - continue; - - // We have to calculate distances in pixels, not in - // data units, because the scales of the axes may be different - var dx = Math.abs(axisx.p2c(x) - mouseX), - dy = Math.abs(axisy.p2c(y) - mouseY), - dist = dx * dx + dy * dy; // we save the sqrt - - // use <= to ensure last point takes precedence - // (last generally means on top of) - if (dist < smallestDistance) { - smallestDistance = dist; - item = [i, j / ps]; - } - } - } - - if (s.bars.show && !item) { // no other point can be nearby - - var barLeft, barRight; - - switch (s.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -s.bars.barWidth; - break; - default: - barLeft = -s.bars.barWidth / 2; - } - - barRight = barLeft + s.bars.barWidth; - - for (j = 0; j < points.length; j += ps) { - var x = points[j], y = points[j + 1], b = points[j + 2]; - if (x == null) - continue; - - // for a bar graph, the cursor must be inside the bar - if (series[i].bars.horizontal ? - (mx <= Math.max(b, x) && mx >= Math.min(b, x) && - my >= y + barLeft && my <= y + barRight) : - (mx >= x + barLeft && mx <= x + barRight && - my >= Math.min(b, y) && my <= Math.max(b, y))) - item = [i, j / ps]; - } - } - } - - if (item) { - i = item[0]; - j = item[1]; - ps = series[i].datapoints.pointsize; - - return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), - dataIndex: j, - series: series[i], - seriesIndex: i }; - } - - return null; - } - - function onMouseMove(e) { - if (options.grid.hoverable) - triggerClickHoverEvent("plothover", e, - function (s) { return s["hoverable"] != false; }); - } - - function onMouseLeave(e) { - if (options.grid.hoverable) - triggerClickHoverEvent("plothover", e, - function (s) { return false; }); - } - - function onClick(e) { - triggerClickHoverEvent("plotclick", e, - function (s) { return s["clickable"] != false; }); - } - - // trigger click or hover event (they send the same parameters - // so we share their code) - function triggerClickHoverEvent(eventname, event, seriesFilter) { - var offset = eventHolder.offset(), - canvasX = event.pageX - offset.left - plotOffset.left, - canvasY = event.pageY - offset.top - plotOffset.top, - pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); - - pos.pageX = event.pageX; - pos.pageY = event.pageY; - - var item = findNearbyItem(canvasX, canvasY, seriesFilter); - - if (item) { - // fill in mouse pos for any listeners out there - item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); - item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); - } - - if (!highlights) - highlights = []; - - if (options.grid.autoHighlight) { - // clear auto-highlights - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.auto == eventname && - !(item && h.series == item.series && - h.point[0] == item.datapoint[0] && - h.point[1] == item.datapoint[1])) - unhighlight(h.series, h.point); - } - - if (item) - highlight(item.series, item.datapoint, eventname); - } - - placeholder.trigger(eventname, [ pos, item ]); - } - - function triggerRedrawOverlay() { - var t = options.interaction.redrawOverlayInterval; - if (t == -1) { // skip event queue - drawOverlay(); - return; - } - - if (!redrawTimeout) - redrawTimeout = setTimeout(drawOverlay, t); - } - - function drawOverlay() { - redrawTimeout = null; - - // draw highlights - octx.save(); - overlay.clear(); - octx.translate(plotOffset.left, plotOffset.top); - - if (!highlights) - highlights = []; - - var i, hi; - for (i = 0; i < highlights.length; ++i) { - hi = highlights[i]; - - if (hi.series.bars.show) - drawBarHighlight(hi.series, hi.point); - else - drawPointHighlight(hi.series, hi.point); - } - octx.restore(); - - executeHooks(hooks.drawOverlay, [octx]); - } - - function highlight(s, point, auto) { - if (typeof s == "number") - s = series[s]; - - if (typeof point == "number") { - var ps = s.datapoints.pointsize; - point = s.datapoints.points.slice(ps * point, ps * (point + 1)); - } - - var i = indexOfHighlight(s, point); - if (i == -1) { - highlights.push({ series: s, point: point, auto: auto }); - - triggerRedrawOverlay(); - } - else if (!auto) - highlights[i].auto = false; - } - - function unhighlight(s, point) { - if (s == null && point == null) { - highlights = []; - triggerRedrawOverlay(); - return; - } - - if (typeof s == "number") - s = series[s]; - - if (typeof point == "number") { - var ps = s.datapoints.pointsize; - point = s.datapoints.points.slice(ps * point, ps * (point + 1)); - } - - var i = indexOfHighlight(s, point); - if (i != -1) { - highlights.splice(i, 1); - - triggerRedrawOverlay(); - } - } - - function indexOfHighlight(s, p) { - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.series == s && h.point[0] == p[0] - && h.point[1] == p[1]) - return i; - } - return -1; - } - - function drawPointHighlight(series, point) { - var x = point[0], y = point[1], - axisx = series.xaxis, axisy = series.yaxis, - highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.8).toString(); - - if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) - return; - - // onur, change hover point radius - var pointRadius = 4;//series.points.radius + series.points.lineWidth / 2; - octx.lineWidth = 2;//pointRadius; - octx.strokeStyle = highlightColor; - var radius = 1.5 * pointRadius; - x = axisx.p2c(x); - y = axisy.p2c(y); - - octx.beginPath(); - if (series.points.symbol == "circle") - octx.arc(x, y, radius, 0, 2 * Math.PI, false); - else - series.points.symbol(octx, x, y, radius, false); - octx.closePath(); - octx.stroke(); - } - - function drawBarHighlight(series, point) { - var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), - fillStyle = highlightColor, - barLeft; - - switch (series.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -series.bars.barWidth; - break; - default: - barLeft = -series.bars.barWidth / 2; - } - - octx.lineWidth = series.bars.lineWidth; - octx.strokeStyle = highlightColor; - - drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, - function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); - } - - function getColorOrGradient(spec, bottom, top, defaultColor) { - if (typeof spec == "string") - return spec; - else { - // assume this is a gradient spec; IE currently only - // supports a simple vertical gradient properly, so that's - // what we support too - var gradient = ctx.createLinearGradient(0, top, 0, bottom); - - for (var i = 0, l = spec.colors.length; i < l; ++i) { - var c = spec.colors[i]; - if (typeof c != "string") { - var co = $.color.parse(defaultColor); - if (c.brightness != null) - co = co.scale('rgb', c.brightness); - if (c.opacity != null) - co.a *= c.opacity; - c = co.toString(); - } - gradient.addColorStop(i / (l - 1), c); - } - - return gradient; - } - } - } - - // Add the plot function to the top level of the jQuery object - - $.plot = function(placeholder, data, options) { - //var t0 = new Date(); - var plot = new Plot($(placeholder), data, options, $.plot.plugins); - //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); - return plot; - }; - - $.plot.version = "0.8.3"; - - $.plot.plugins = []; - - // Also add the plot function as a chainable property - - $.fn.plot = function(data, options) { - return this.each(function() { - $.plot(this, data, options); - }); - }; - - // round to nearby lower multiple of base - function floorInBase(n, base) { - return base * Math.floor(n / base); - } - -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.navigate.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.navigate.js deleted file mode 100644 index 13fb7f17d04..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.navigate.js +++ /dev/null @@ -1,346 +0,0 @@ -/* Flot plugin for adding the ability to pan and zoom the plot. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The default behaviour is double click and scrollwheel up/down to zoom in, drag -to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and -plot.pan( offset ) so you easily can add custom controls. It also fires -"plotpan" and "plotzoom" events, useful for synchronizing plots. - -The plugin supports these options: - - zoom: { - interactive: false - trigger: "dblclick" // or "click" for single click - amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out) - } - - pan: { - interactive: false - cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer" - frameRate: 20 - } - - xaxis, yaxis, x2axis, y2axis: { - zoomRange: null // or [ number, number ] (min range, max range) or false - panRange: null // or [ number, number ] (min, max) or false - } - -"interactive" enables the built-in drag/click behaviour. If you enable -interactive for pan, then you'll have a basic plot that supports moving -around; the same for zoom. - -"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to -the current viewport. - -"cursor" is a standard CSS mouse cursor string used for visual feedback to the -user when dragging. - -"frameRate" specifies the maximum number of times per second the plot will -update itself while the user is panning around on it (set to null to disable -intermediate pans, the plot will then not update until the mouse button is -released). - -"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange: -[1, 100] the zoom will never scale the axis so that the difference between min -and max is smaller than 1 or larger than 100. You can set either end to null -to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis -will be disabled. - -"panRange" confines the panning to stay within a range, e.g. with panRange: -[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can -be null, e.g. [-10, null]. If you set panRange to false, panning on that axis -will be disabled. - -Example API usage: - - plot = $.plot(...); - - // zoom default amount in on the pixel ( 10, 20 ) - plot.zoom({ center: { left: 10, top: 20 } }); - - // zoom out again - plot.zoomOut({ center: { left: 10, top: 20 } }); - - // zoom 200% in on the pixel (10, 20) - plot.zoom({ amount: 2, center: { left: 10, top: 20 } }); - - // pan 100 pixels to the left and 20 down - plot.pan({ left: -100, top: 20 }) - -Here, "center" specifies where the center of the zooming should happen. Note -that this is defined in pixel space, not the space of the data points (you can -use the p2c helpers on the axes in Flot to help you convert between these). - -"amount" is the amount to zoom the viewport relative to the current range, so -1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You -can set the default in the options. - -*/ - -// First two dependencies, jquery.event.drag.js and -// jquery.mousewheel.js, we put them inline here to save people the -// effort of downloading them. - -/* -jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com) -Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt -*/ -(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY) max) { - // make sure min < max - var tmp = min; - min = max; - max = tmp; - } - - //Check that we are in panRange - if (pr) { - if (pr[0] != null && min < pr[0]) { - min = pr[0]; - } - if (pr[1] != null && max > pr[1]) { - max = pr[1]; - } - } - - var range = max - min; - if (zr && - ((zr[0] != null && range < zr[0] && amount >1) || - (zr[1] != null && range > zr[1] && amount <1))) - return; - - opts.min = min; - opts.max = max; - }); - - plot.setupGrid(); - plot.draw(); - - if (!args.preventEvent) - plot.getPlaceholder().trigger("plotzoom", [ plot, args ]); - }; - - plot.pan = function (args) { - var delta = { - x: +args.left, - y: +args.top - }; - - if (isNaN(delta.x)) - delta.x = 0; - if (isNaN(delta.y)) - delta.y = 0; - - $.each(plot.getAxes(), function (_, axis) { - var opts = axis.options, - min, max, d = delta[axis.direction]; - - min = axis.c2p(axis.p2c(axis.min) + d), - max = axis.c2p(axis.p2c(axis.max) + d); - - var pr = opts.panRange; - if (pr === false) // no panning on this axis - return; - - if (pr) { - // check whether we hit the wall - if (pr[0] != null && pr[0] > min) { - d = pr[0] - min; - min += d; - max += d; - } - - if (pr[1] != null && pr[1] < max) { - d = pr[1] - max; - min += d; - max += d; - } - } - - opts.min = min; - opts.max = max; - }); - - plot.setupGrid(); - plot.draw(); - - if (!args.preventEvent) - plot.getPlaceholder().trigger("plotpan", [ plot, args ]); - }; - - function shutdown(plot, eventHolder) { - eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick); - eventHolder.unbind("mousewheel", onMouseWheel); - eventHolder.unbind("dragstart", onDragStart); - eventHolder.unbind("drag", onDrag); - eventHolder.unbind("dragend", onDragEnd); - if (panTimeout) - clearTimeout(panTimeout); - } - - plot.hooks.bindEvents.push(bindEvents); - plot.hooks.shutdown.push(shutdown); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'navigate', - version: '1.3' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.orderBars.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.orderBars.js deleted file mode 100644 index 6c63c7ff7d1..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.orderBars.js +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Flot plugin to order bars side by side. This is improved version of Benjamin BUFFET work - * originally from http://en.benjaminbuffet.com/labs/flot/. - * - * Released under the MIT license by Przemyslaw Koltermann, 12-Feb-2013. - * - * This plugin is an alpha version. - * - * To activate the plugin you must specify the parameter "order" for the specific serie : - * - * $.plot($("#placeholder"), [{ data: [ ... ], bars :{ order = null or integer }]) - * - * If 2 series have the same order param, they are displayed in the same position; - * - * The plugin adjust the point by adding a value depanding of the barwidth - * Exemple for 3 series (barwidth : 0.1) : - * - * first bar décalage : -0.15 - * second bar décalage : -0.05 - * third bar décalage : 0.05 - * - */ - -(function($){ - function init(plot){ - var orderedBarSeries; - var nbOfBarsToOrder; - var seriesPos = new Array(); - var sameSeries = new Array(); - var borderWidth; - var borderWidthInXabsWidth; - var pixelInXWidthEquivalent = 1; - var isHorizontal = false; - - /* - * This method add shift to x values - */ - function reOrderBars(plot, serie, datapoints){ - var shiftedPoints = null; - - if(serieNeedToBeReordered(serie)){ - checkIfGraphIsHorizontal(serie); - calculPixel2XWidthConvert(plot); - retrieveBarSeries(plot); - calculBorderAndBarWidth(serie); - - if(nbOfBarsToOrder >= 2){ - var position = findPosition(serie); - var decallage = 0; - - var centerBarShift = calculCenterBarShift(); - - if (isBarAtLeftOfCenter(position)){ - decallage = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift; - }else{ - decallage = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2; - } - - shiftedPoints = shiftPoints(datapoints,serie,decallage); - datapoints.points = shiftedPoints; - } else if (nbOfBarsToOrder == 1){ - // To be consistent with the barshift at other uneven numbers of bars, where - // the center bar is centered around the point, we also need to shift a single bar - // left by half its width - var centerBarShift = -1*calculCenterBarShift(); - shiftedPoints = shiftPoints(datapoints,serie,centerBarShift); - datapoints.points = shiftedPoints; - } - } - return shiftedPoints; - } - - function serieNeedToBeReordered(serie){ - return serie.bars != null - && serie.bars.show - && serie.bars.order != null; - } - - function calculPixel2XWidthConvert(plot){ - var gridDimSize = isHorizontal ? plot.getPlaceholder().innerHeight() : plot.getPlaceholder().innerWidth(); - var minMaxValues = isHorizontal ? getAxeMinMaxValues(plot.getData(),1) : getAxeMinMaxValues(plot.getData(),0); - var AxeSize = minMaxValues[1] - minMaxValues[0]; - pixelInXWidthEquivalent = AxeSize / gridDimSize; - } - - function getAxeMinMaxValues(series,AxeIdx){ - var minMaxValues = new Array(); - for(var i = 0; i < series.length; i++){ - minMaxValues[0] = series[i].data[0][AxeIdx]; - minMaxValues[1] = series[i].data[series[i].data.length - 1][AxeIdx]; - } - if(typeof minMaxValues[0] == 'string'){ - minMaxValues[0] = 0; - minMaxValues[1] = series[0].data.length - 1; - } - return minMaxValues; - } - - function retrieveBarSeries(plot){ - orderedBarSeries = findOthersBarsToReOrders(plot.getData()); - nbOfBarsToOrder = orderedBarSeries.length; - } - - function findOthersBarsToReOrders(series){ - var retSeries = new Array(); - - for(var i = 0; i < series.length; i++){ - if(series[i].bars.order != null && series[i].bars.show){ - retSeries.push(series[i]); - } - } - - return sortByOrder(retSeries); - } - - function sortByOrder(series){ - var n = series.length; - do { - for (var i=0; i < n - 1; i++) { - if (series[i].bars.order > series[i + 1].bars.order) { - var tmp = series[i]; - series[i] = series[i + 1]; - series[i + 1] = tmp; - } - else if (series[i].bars.order == series[i + 1].bars.order) { - - //check if any of the series has set sameSeriesArrayIndex - var sameSeriesIndex; - if (series[i].sameSeriesArrayIndex) { - if(series[i + 1].sameSeriesArrayIndex !== undefined) { - sameSeriesIndex = series[i].sameSeriesArrayIndex; - series[i + 1].sameSeriesArrayIndex = sameSeriesIndex; - sameSeries[sameSeriesIndex].push(series[i + 1]); - sameSeries[sameSeriesIndex].sort(sortByWidth); - - series[i] = sameSeries[sameSeriesIndex][0]; - removeElement(series, i + 1); - } - } - - else if (series[i + 1].sameSeriesArrayIndex) { - if(series[i].sameSeriesArrayIndex !== undefined) { - sameSeriesIndex = series[i + 1].sameSeriesArrayIndex; - series[i].sameSeriesArrayIndex = sameSeriesIndex; - sameSeries[sameSeriesIndex].push(series[i]); - sameSeries[sameSeriesIndex].sort(sortByWidth); - - series[i] = sameSeries[sameSeriesIndex][0]; - removeElement(series, i + 1); - - } - } - - else { - sameSeriesIndex = sameSeries.length; - sameSeries[sameSeriesIndex] = new Array(); - series[i].sameSeriesArrayIndex = sameSeriesIndex; - series[i + 1].sameSeriesArrayIndex = sameSeriesIndex; - sameSeries[sameSeriesIndex].push(series[i]); - sameSeries[sameSeriesIndex].push(series[i + 1]); - sameSeries[sameSeriesIndex].sort(sortByWidth); - - series[i] = sameSeries[sameSeriesIndex][0]; - removeElement(series, i + 1); - } - i--; - n--; - - - //leave the wider serie and the other one move to - } - } - n = n-1; - } - while (n>1); - for (var i=0; i < series.length; i++) { - if (series[i].sameSeriesArrayIndex) { - seriesPos[series[i].sameSeriesArrayIndex] = i; - } - } - return series; - } - - function sortByWidth(serie1,serie2){ - var x = serie1.bars.barWidth ? serie1.bars.barWidth : 1; - var y = serie2.bars.barWidth ? serie2.bars.barWidth : 1; - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - } - function removeElement(arr, from, to) { - var rest = arr.slice((to || from) + 1 || arr.length); - arr.length = from < 0 ? arr.length + from : from; - arr.push.apply(arr, rest); - return arr; - } - - function calculBorderAndBarWidth(serie){ - borderWidth = typeof serie.bars.lineWidth === "number" ? serie.bars.lineWidth : 2; - borderWidthInXabsWidth = borderWidth * pixelInXWidthEquivalent; - } - - function checkIfGraphIsHorizontal(serie){ - if(serie.bars.horizontal){ - isHorizontal = true; - } - } - - function findPosition(serie){ - var ss = sameSeries; - var pos = 0; - if (serie.sameSeriesArrayIndex) { - pos = seriesPos[serie.sameSeriesArrayIndex]; - } - else { - for (var i = 0; i < orderedBarSeries.length; ++i) { - if (serie == orderedBarSeries[i]){ - pos = i; - break; - } - } - } - return pos+1; - } - - function calculCenterBarShift(){ - var width = 0; - - if(nbOfBarsToOrder%2 != 0) - // Since the array indexing starts at 0, we need to use Math.floor instead of - // Math.ceil otherwise we will get an error if there is only one bar - width = (orderedBarSeries[Math.floor(nbOfBarsToOrder / 2)].bars.barWidth)/2; - - return width; - } - - function isBarAtLeftOfCenter(position){ - return position <= Math.ceil(nbOfBarsToOrder / 2); - } - - function sumWidth(series,start,end){ - var totalWidth = 0; - - for(var i = start; i <= end; i++){ - totalWidth += series[i].bars.barWidth+borderWidthInXabsWidth*2; - } - - return totalWidth; - } - - function shiftPoints(datapoints,serie,dx){ - var ps = datapoints.pointsize; - var points = datapoints.points; - var j = 0; - for(var i = isHorizontal ? 1 : 0;i < points.length; i += ps){ - points[i] += dx; - //Adding the new x value in the serie to be abble to display the right tooltip value, - //using the index 3 to not overide the third index. - serie.data[j][3] = points[i]; - j++; - } - - return points; - } - - plot.hooks.processDatapoints.push(reOrderBars); - - } - - var options = { - series : { - bars: {order: null} // or number/string - } - }; - - $.plot.plugins.push({ - init: init, - options: options, - name: "orderBars", - version: "0.2" - }); - -})(jQuery); - diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.js deleted file mode 100644 index 7cca58480d5..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.js +++ /dev/null @@ -1,822 +0,0 @@ -/* Flot plugin for rendering pie charts. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin assumes that each series has a single data value, and that each -value is a positive integer or zero. Negative numbers don't make sense for a -pie chart, and have unpredictable results. The values do NOT need to be -passed in as percentages; the plugin will calculate the total and per-slice -percentages internally. - -* Created by Brian Medendorp - -* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars - -The plugin supports these options: - - series: { - pie: { - show: true/false - radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto' - innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect - startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result - tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show) - offset: { - top: integer value to move the pie up or down - left: integer value to move the pie left or right, or 'auto' - }, - stroke: { - color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF') - width: integer pixel width of the stroke - }, - label: { - show: true/false, or 'auto' - formatter: a user-defined function that modifies the text/style of the label text - radius: 0-1 for percentage of fullsize, or a specified pixel length - background: { - color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000') - opacity: 0-1 - }, - threshold: 0-1 for the percentage value at which to hide labels (if they're too small) - }, - combine: { - threshold: 0-1 for the percentage value at which to combine slices (if they're too small) - color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined - label: any text value of what the combined slice should be labeled - } - highlight: { - opacity: 0-1 - } - } - } - -More detail and specific examples can be found in the included HTML file. - -*/ - -(function($) { - - // Maximum redraw attempts when fitting labels within the plot - - var REDRAW_ATTEMPTS = 10; - - // Factor by which to shrink the pie when fitting labels within the plot - - var REDRAW_SHRINK = 0.95; - - function init(plot) { - - var canvas = null, - target = null, - options = null, - maxRadius = null, - centerLeft = null, - centerTop = null, - processed = false, - ctx = null; - - // interactive variables - - var highlights = []; - - // add hook to determine if pie plugin in enabled, and then perform necessary operations - - plot.hooks.processOptions.push(function(plot, options) { - if (options.series.pie.show) { - - options.grid.show = false; - - // set labels.show - - if (options.series.pie.label.show == "auto") { - if (options.legend.show) { - options.series.pie.label.show = false; - } else { - options.series.pie.label.show = true; - } - } - - // set radius - - if (options.series.pie.radius == "auto") { - if (options.series.pie.label.show) { - options.series.pie.radius = 3/4; - } else { - options.series.pie.radius = 1; - } - } - - // ensure sane tilt - - if (options.series.pie.tilt > 1) { - options.series.pie.tilt = 1; - } else if (options.series.pie.tilt < 0) { - options.series.pie.tilt = 0; - } - } - }); - - plot.hooks.bindEvents.push(function(plot, eventHolder) { - var options = plot.getOptions(); - if (options.series.pie.show) { - if (options.grid.hoverable) { - eventHolder.unbind("mousemove").mousemove(onMouseMove); - } - if (options.grid.clickable) { - eventHolder.unbind("click").click(onClick); - } - } - }); - - plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) { - var options = plot.getOptions(); - if (options.series.pie.show) { - processDatapoints(plot, series, data, datapoints); - } - }); - - plot.hooks.drawOverlay.push(function(plot, octx) { - var options = plot.getOptions(); - if (options.series.pie.show) { - drawOverlay(plot, octx); - } - }); - - plot.hooks.draw.push(function(plot, newCtx) { - var options = plot.getOptions(); - if (options.series.pie.show) { - draw(plot, newCtx); - } - }); - - function processDatapoints(plot, series, datapoints) { - if (!processed) { - processed = true; - canvas = plot.getCanvas(); - target = $(canvas).parent(); - options = plot.getOptions(); - plot.setData(combine(plot.getData())); - } - } - - function combine(data) { - - var total = 0, - combined = 0, - numCombined = 0, - color = options.series.pie.combine.color, - newdata = []; - - // Fix up the raw data from Flot, ensuring the data is numeric - - for (var i = 0; i < data.length; ++i) { - - var value = data[i].data; - - // If the data is an array, we'll assume that it's a standard - // Flot x-y pair, and are concerned only with the second value. - - // Note how we use the original array, rather than creating a - // new one; this is more efficient and preserves any extra data - // that the user may have stored in higher indexes. - - if ($.isArray(value) && value.length == 1) { - value = value[0]; - } - - if ($.isArray(value)) { - // Equivalent to $.isNumeric() but compatible with jQuery < 1.7 - if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) { - value[1] = +value[1]; - } else { - value[1] = 0; - } - } else if (!isNaN(parseFloat(value)) && isFinite(value)) { - value = [1, +value]; - } else { - value = [1, 0]; - } - - data[i].data = [value]; - } - - // Sum up all the slices, so we can calculate percentages for each - - for (var i = 0; i < data.length; ++i) { - total += data[i].data[0][1]; - } - - // Count the number of slices with percentages below the combine - // threshold; if it turns out to be just one, we won't combine. - - for (var i = 0; i < data.length; ++i) { - var value = data[i].data[0][1]; - if (value / total <= options.series.pie.combine.threshold) { - combined += value; - numCombined++; - if (!color) { - color = data[i].color; - } - } - } - - for (var i = 0; i < data.length; ++i) { - var value = data[i].data[0][1]; - if (numCombined < 2 || value / total > options.series.pie.combine.threshold) { - newdata.push( - $.extend(data[i], { /* extend to allow keeping all other original data values - and using them e.g. in labelFormatter. */ - data: [[1, value]], - color: data[i].color, - label: data[i].label, - angle: value * Math.PI * 2 / total, - percent: value / (total / 100) - }) - ); - } - } - - if (numCombined > 1) { - newdata.push({ - data: [[1, combined]], - color: color, - label: options.series.pie.combine.label, - angle: combined * Math.PI * 2 / total, - percent: combined / (total / 100) - }); - } - - return newdata; - } - - function draw(plot, newCtx) { - - if (!target) { - return; // if no series were passed - } - - var canvasWidth = plot.getPlaceholder().width(), - canvasHeight = plot.getPlaceholder().height(), - legendWidth = target.children().filter(".legend").children().width() || 0; - - ctx = newCtx; - - // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE! - - // When combining smaller slices into an 'other' slice, we need to - // add a new series. Since Flot gives plugins no way to modify the - // list of series, the pie plugin uses a hack where the first call - // to processDatapoints results in a call to setData with the new - // list of series, then subsequent processDatapoints do nothing. - - // The plugin-global 'processed' flag is used to control this hack; - // it starts out false, and is set to true after the first call to - // processDatapoints. - - // Unfortunately this turns future setData calls into no-ops; they - // call processDatapoints, the flag is true, and nothing happens. - - // To fix this we'll set the flag back to false here in draw, when - // all series have been processed, so the next sequence of calls to - // processDatapoints once again starts out with a slice-combine. - // This is really a hack; in 0.9 we need to give plugins a proper - // way to modify series before any processing begins. - - processed = false; - - // calculate maximum radius and center point - - maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2; - centerTop = canvasHeight / 2 + options.series.pie.offset.top; - centerLeft = canvasWidth / 2; - - if (options.series.pie.offset.left == "auto") { - if (options.legend.position.match("w")) { - centerLeft += legendWidth / 2; - } else { - centerLeft -= legendWidth / 2; - } - if (centerLeft < maxRadius) { - centerLeft = maxRadius; - } else if (centerLeft > canvasWidth - maxRadius) { - centerLeft = canvasWidth - maxRadius; - } - } else { - centerLeft += options.series.pie.offset.left; - } - - var slices = plot.getData(), - attempts = 0; - - // Keep shrinking the pie's radius until drawPie returns true, - // indicating that all the labels fit, or we try too many times. - - do { - if (attempts > 0) { - maxRadius *= REDRAW_SHRINK; - } - attempts += 1; - clear(); - if (options.series.pie.tilt <= 0.8) { - drawShadow(); - } - } while (!drawPie() && attempts < REDRAW_ATTEMPTS) - - if (attempts >= REDRAW_ATTEMPTS) { - clear(); - // onur: remove error div - //target.prepend("
      Could not draw pie with labels contained inside canvas
      "); - } - - if (plot.setSeries && plot.insertLegend) { - plot.setSeries(slices); - plot.insertLegend(); - } - - // we're actually done at this point, just defining internal functions at this point - - function clear() { - ctx.clearRect(0, 0, canvasWidth, canvasHeight); - target.children().filter(".pieLabel, .pieLabelBackground").remove(); - } - - function drawShadow() { - - var shadowLeft = options.series.pie.shadow.left; - var shadowTop = options.series.pie.shadow.top; - var edge = 10; - var alpha = options.series.pie.shadow.alpha; - var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; - - if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) { - return; // shadow would be outside canvas, so don't draw it - } - - ctx.save(); - ctx.translate(shadowLeft,shadowTop); - ctx.globalAlpha = alpha; - ctx.fillStyle = "#000"; - - // center and rotate to starting position - - ctx.translate(centerLeft,centerTop); - ctx.scale(1, options.series.pie.tilt); - - //radius -= edge; - - for (var i = 1; i <= edge; i++) { - ctx.beginPath(); - ctx.arc(0, 0, radius, 0, Math.PI * 2, false); - ctx.fill(); - radius -= i; - } - - ctx.restore(); - } - - function drawPie() { - - var startAngle = Math.PI * options.series.pie.startAngle; - var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; - - // center and rotate to starting position - - ctx.save(); - ctx.translate(centerLeft,centerTop); - ctx.scale(1, options.series.pie.tilt); - //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera - - // draw slices - - ctx.save(); - var currentAngle = startAngle; - for (var i = 0; i < slices.length; ++i) { - slices[i].startAngle = currentAngle; - drawSlice(slices[i].angle, slices[i].color, true); - } - ctx.restore(); - - // draw slice outlines - - if (options.series.pie.stroke.width > 0) { - ctx.save(); - ctx.lineWidth = options.series.pie.stroke.width; - currentAngle = startAngle; - for (var i = 0; i < slices.length; ++i) { - drawSlice(slices[i].angle, options.series.pie.stroke.color, false); - } - ctx.restore(); - } - - // draw donut hole - - drawDonutHole(ctx); - - ctx.restore(); - - // Draw the labels, returning true if they fit within the plot - - if (options.series.pie.label.show) { - return drawLabels(); - } else return true; - - function drawSlice(angle, color, fill) { - - if (angle <= 0 || isNaN(angle)) { - return; - } - - if (fill) { - ctx.fillStyle = color; - } else { - ctx.strokeStyle = color; - ctx.lineJoin = "round"; - } - - ctx.beginPath(); - if (Math.abs(angle - Math.PI * 2) > 0.000000001) { - ctx.moveTo(0, 0); // Center of the pie - } - - //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera - ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false); - ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false); - ctx.closePath(); - //ctx.rotate(angle); // This doesn't work properly in Opera - currentAngle += angle; - - if (fill) { - ctx.fill(); - } else { - ctx.stroke(); - } - } - - function drawLabels() { - - var currentAngle = startAngle; - var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius; - - for (var i = 0; i < slices.length; ++i) { - if (slices[i].percent >= options.series.pie.label.threshold * 100) { - if (!drawLabel(slices[i], currentAngle, i)) { - return false; - } - } - currentAngle += slices[i].angle; - } - - return true; - - function drawLabel(slice, startAngle, index) { - - if (slice.data[0][1] == 0) { - return true; - } - - // format label text - - var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter; - - if (lf) { - text = lf(slice.label, slice); - } else { - text = slice.label; - } - - if (plf) { - text = plf(text, slice); - } - - var halfAngle = ((startAngle + slice.angle) + startAngle) / 2; - var x = centerLeft + Math.round(Math.cos(halfAngle) * radius); - var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt; - - var html = "" + text + ""; - target.append(html); - - var label = target.children("#pieLabel" + index); - var labelTop = (y - label.height() / 2); - var labelLeft = (x - label.width() / 2); - - label.css("top", labelTop); - label.css("left", labelLeft); - - // check to make sure that the label is not outside the canvas - - if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) { - // onur: remove return, even if labels don't fit just draw the pie - //return false; - } - - if (options.series.pie.label.background.opacity != 0) { - - // put in the transparent background separately to avoid blended labels and label boxes - - var c = options.series.pie.label.background.color; - - if (c == null) { - c = slice.color; - } - - var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;"; - $("
      ") - .css("opacity", options.series.pie.label.background.opacity) - .insertBefore(label); - } - - return true; - } // end individual label function - } // end drawLabels function - } // end drawPie function - } // end draw function - - // Placed here because it needs to be accessed from multiple locations - - function drawDonutHole(layer) { - if (options.series.pie.innerRadius > 0) { - - // subtract the center - - layer.save(); - var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; - layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color - layer.beginPath(); - layer.fillStyle = options.series.pie.stroke.color; - layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); - layer.fill(); - layer.closePath(); - layer.restore(); - - // add inner stroke - - layer.save(); - layer.beginPath(); - layer.strokeStyle = options.series.pie.stroke.color; - layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); - layer.stroke(); - layer.closePath(); - layer.restore(); - - // TODO: add extra shadow inside hole (with a mask) if the pie is tilted. - } - } - - //-- Additional Interactive related functions -- - - function isPointInPoly(poly, pt) { - for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) - ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1])) - && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) - && (c = !c); - return c; - } - - function findNearbySlice(mouseX, mouseY) { - - var slices = plot.getData(), - options = plot.getOptions(), - radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius, - x, y; - - for (var i = 0; i < slices.length; ++i) { - - var s = slices[i]; - - if (s.pie.show) { - - ctx.save(); - ctx.beginPath(); - ctx.moveTo(0, 0); // Center of the pie - //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here. - ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false); - ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false); - ctx.closePath(); - x = mouseX - centerLeft; - y = mouseY - centerTop; - - if (ctx.isPointInPath) { - if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) { - ctx.restore(); - return { - datapoint: [s.percent, s.data], - dataIndex: 0, - series: s, - seriesIndex: i - }; - } - } else { - - // excanvas for IE doesn;t support isPointInPath, this is a workaround. - - var p1X = radius * Math.cos(s.startAngle), - p1Y = radius * Math.sin(s.startAngle), - p2X = radius * Math.cos(s.startAngle + s.angle / 4), - p2Y = radius * Math.sin(s.startAngle + s.angle / 4), - p3X = radius * Math.cos(s.startAngle + s.angle / 2), - p3Y = radius * Math.sin(s.startAngle + s.angle / 2), - p4X = radius * Math.cos(s.startAngle + s.angle / 1.5), - p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5), - p5X = radius * Math.cos(s.startAngle + s.angle), - p5Y = radius * Math.sin(s.startAngle + s.angle), - arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]], - arrPoint = [x, y]; - - // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? - - if (isPointInPoly(arrPoly, arrPoint)) { - ctx.restore(); - return { - datapoint: [s.percent, s.data], - dataIndex: 0, - series: s, - seriesIndex: i - }; - } - } - - ctx.restore(); - } - } - - return null; - } - - function onMouseMove(e) { - triggerClickHoverEvent("plothover", e); - } - - function onClick(e) { - triggerClickHoverEvent("plotclick", e); - } - - // trigger click or hover event (they send the same parameters so we share their code) - - function triggerClickHoverEvent(eventname, e) { - - var offset = plot.offset(); - var canvasX = parseInt(e.pageX - offset.left); - var canvasY = parseInt(e.pageY - offset.top); - var item = findNearbySlice(canvasX, canvasY); - - if (options.grid.autoHighlight) { - - // clear auto-highlights - - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.auto == eventname && !(item && h.series == item.series)) { - unhighlight(h.series); - } - } - } - - // highlight the slice - - if (item) { - highlight(item.series, eventname); - } - - // trigger any hover bind events - - var pos = { pageX: e.pageX, pageY: e.pageY }; - target.trigger(eventname, [pos, item]); - } - - function highlight(s, auto) { - //if (typeof s == "number") { - // s = series[s]; - //} - - var i = indexOfHighlight(s); - - if (i == -1) { - highlights.push({ series: s, auto: auto }); - plot.triggerRedrawOverlay(); - } else if (!auto) { - highlights[i].auto = false; - } - } - - function unhighlight(s) { - if (s == null) { - highlights = []; - plot.triggerRedrawOverlay(); - } - - //if (typeof s == "number") { - // s = series[s]; - //} - - var i = indexOfHighlight(s); - - if (i != -1) { - highlights.splice(i, 1); - plot.triggerRedrawOverlay(); - } - } - - function indexOfHighlight(s) { - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.series == s) - return i; - } - return -1; - } - - function drawOverlay(plot, octx) { - - var options = plot.getOptions(); - - var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; - - octx.save(); - octx.translate(centerLeft, centerTop); - octx.scale(1, options.series.pie.tilt); - - for (var i = 0; i < highlights.length; ++i) { - drawHighlight(highlights[i].series); - } - - drawDonutHole(octx); - - octx.restore(); - - function drawHighlight(series) { - - if (series.angle <= 0 || isNaN(series.angle)) { - return; - } - - //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString(); - octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor - octx.beginPath(); - if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) { - octx.moveTo(0, 0); // Center of the pie - } - octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false); - octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false); - octx.closePath(); - octx.fill(); - } - } - } // end init (plugin body) - - // define pie specific options and their default values - - var options = { - series: { - pie: { - show: false, - radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value) - innerRadius: 0, /* for donut */ - startAngle: 3/2, - tilt: 1, - shadow: { - left: 5, // shadow left offset - top: 15, // shadow top offset - alpha: 0.02 // shadow alpha - }, - offset: { - top: 0, - left: "auto" - }, - stroke: { - color: "#fff", - width: 1 - }, - label: { - show: "auto", - formatter: function(label, slice) { - return "
      " + label + "
      " + Math.round(slice.percent) + "%
      "; - }, // formatter function - radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value) - background: { - color: null, - opacity: 0 - }, - threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow) - }, - combine: { - threshold: -1, // percentage at which to combine little slices into one larger slice - color: null, // color to give the new slice (auto-generated if null) - label: "Other" // label to give the new slice - }, - highlight: { - //color: "#fff", // will add this functionality once parseColor is available - opacity: 0.5 - } - } - } - }; - - $.plot.plugins.push({ - init: init, - options: options, - name: "pie", - version: "1.1" - }); - -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js deleted file mode 100644 index 26eae79beb0..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js +++ /dev/null @@ -1,88 +0,0 @@ -/* Flot plugin for automatically redrawing plots as the placeholder resizes. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -It works by listening for changes on the placeholder div (through the jQuery -resize event plugin) - if the size changes, it will redraw the plot. - -There are no options. If you need to disable the plugin for some plots, you -can just fix the size of their placeholders. - -*/ - -/* Inline dependency: - * jQuery resize event - v1.1 - 3/14/2010 - * http://benalman.com/projects/jquery-resize-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this); - -(function ($) { - var options = { }; // no options - - function init(plot) { - function onResize() { - var placeholder = plot.getPlaceholder(); - - // somebody might have hidden us and we can't plot - // when we don't have the dimensions - if (placeholder.width() == 0 || placeholder.height() == 0) - return; - - plot.resize(); - plot.setupGrid(); - plot.draw(); - - var graphWidth = plot.width(); - - // update positions of key event labels - // each label has data-points attribute for storing - // their corresponding [index, value] - $("#dashboard-graph .graph-key-event-label").each(function() { - var o = plot.pointOffset({x: $(this).data("points")[0], y: $(this).data("points")[1]}); - - if (o.left <= 15) { - o.left = 15; - } - - if (o.left >= (graphWidth - 15)) { - o.left = (graphWidth - 15); - } - - $(this).css({ - left: o.left - }) - }); - - $("#dashboard-graph .graph-note-label").each(function() { - var o = plot.pointOffset({x: $(this).data("points")[0], y: $(this).data("points")[1]}); - - $(this).css({ - left: o.left - }) - }); - } - - function bindEvents(plot, eventHolder) { - plot.getPlaceholder().resize(onResize); - } - - function shutdown(plot, eventHolder) { - plot.getPlaceholder().unbind("resize", onResize); - } - - plot.hooks.bindEvents.push(bindEvents); - plot.hooks.shutdown.push(shutdown); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'resize', - version: '1.0' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.selection.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.selection.js deleted file mode 100644 index d3c20fa4e12..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.selection.js +++ /dev/null @@ -1,360 +0,0 @@ -/* Flot plugin for selecting regions of a plot. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin supports these options: - -selection: { - mode: null or "x" or "y" or "xy", - color: color, - shape: "round" or "miter" or "bevel", - minSize: number of pixels -} - -Selection support is enabled by setting the mode to one of "x", "y" or "xy". -In "x" mode, the user will only be able to specify the x range, similarly for -"y" mode. For "xy", the selection becomes a rectangle where both ranges can be -specified. "color" is color of the selection (if you need to change the color -later on, you can get to it with plot.getOptions().selection.color). "shape" -is the shape of the corners of the selection. - -"minSize" is the minimum size a selection can be in pixels. This value can -be customized to determine the smallest size a selection can be and still -have the selection rectangle be displayed. When customizing this value, the -fact that it refers to pixels, not axis units must be taken into account. -Thus, for example, if there is a bar graph in time mode with BarWidth set to 1 -minute, setting "minSize" to 1 will not make the minimum selection size 1 -minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent -"plotunselected" events from being fired when the user clicks the mouse without -dragging. - -When selection support is enabled, a "plotselected" event will be emitted on -the DOM element you passed into the plot function. The event handler gets a -parameter with the ranges selected on the axes, like this: - - placeholder.bind( "plotselected", function( event, ranges ) { - alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to) - // similar for yaxis - with multiple axes, the extra ones are in - // x2axis, x3axis, ... - }); - -The "plotselected" event is only fired when the user has finished making the -selection. A "plotselecting" event is fired during the process with the same -parameters as the "plotselected" event, in case you want to know what's -happening while it's happening, - -A "plotunselected" event with no arguments is emitted when the user clicks the -mouse to remove the selection. As stated above, setting "minSize" to 0 will -destroy this behavior. - -The plugin allso adds the following methods to the plot object: - -- setSelection( ranges, preventEvent ) - - Set the selection rectangle. The passed in ranges is on the same form as - returned in the "plotselected" event. If the selection mode is "x", you - should put in either an xaxis range, if the mode is "y" you need to put in - an yaxis range and both xaxis and yaxis if the selection mode is "xy", like - this: - - setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } }); - - setSelection will trigger the "plotselected" event when called. If you don't - want that to happen, e.g. if you're inside a "plotselected" handler, pass - true as the second parameter. If you are using multiple axes, you can - specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of - xaxis, the plugin picks the first one it sees. - -- clearSelection( preventEvent ) - - Clear the selection rectangle. Pass in true to avoid getting a - "plotunselected" event. - -- getSelection() - - Returns the current selection in the same format as the "plotselected" - event. If there's currently no selection, the function returns null. - -*/ - -(function ($) { - function init(plot) { - var selection = { - first: { x: -1, y: -1}, second: { x: -1, y: -1}, - show: false, - active: false - }; - - // FIXME: The drag handling implemented here should be - // abstracted out, there's some similar code from a library in - // the navigation plugin, this should be massaged a bit to fit - // the Flot cases here better and reused. Doing this would - // make this plugin much slimmer. - var savedhandlers = {}; - - var mouseUpHandler = null; - - function onMouseMove(e) { - if (selection.active) { - updateSelection(e); - - plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]); - } - } - - function onMouseDown(e) { - if (e.which != 1) // only accept left-click - return; - - // cancel out any text selections - document.body.focus(); - - // prevent text selection and drag in old-school browsers - if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) { - savedhandlers.onselectstart = document.onselectstart; - document.onselectstart = function () { return false; }; - } - if (document.ondrag !== undefined && savedhandlers.ondrag == null) { - savedhandlers.ondrag = document.ondrag; - document.ondrag = function () { return false; }; - } - - setSelectionPos(selection.first, e); - - selection.active = true; - - // this is a bit silly, but we have to use a closure to be - // able to whack the same handler again - mouseUpHandler = function (e) { onMouseUp(e); }; - - $(document).one("mouseup", mouseUpHandler); - } - - function onMouseUp(e) { - mouseUpHandler = null; - - // revert drag stuff for old-school browsers - if (document.onselectstart !== undefined) - document.onselectstart = savedhandlers.onselectstart; - if (document.ondrag !== undefined) - document.ondrag = savedhandlers.ondrag; - - // no more dragging - selection.active = false; - updateSelection(e); - - if (selectionIsSane()) - triggerSelectedEvent(); - else { - // this counts as a clear - plot.getPlaceholder().trigger("plotunselected", [ ]); - plot.getPlaceholder().trigger("plotselecting", [ null ]); - } - - return false; - } - - function getSelection() { - if (!selectionIsSane()) - return null; - - if (!selection.show) return null; - - var r = {}, c1 = selection.first, c2 = selection.second; - $.each(plot.getAxes(), function (name, axis) { - if (axis.used) { - var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); - r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) }; - } - }); - return r; - } - - function triggerSelectedEvent() { - var r = getSelection(); - - plot.getPlaceholder().trigger("plotselected", [ r ]); - - // backwards-compat stuff, to be removed in future - if (r.xaxis && r.yaxis) - plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]); - } - - function clamp(min, value, max) { - return value < min ? min: (value > max ? max: value); - } - - function setSelectionPos(pos, e) { - var o = plot.getOptions(); - var offset = plot.getPlaceholder().offset(); - var plotOffset = plot.getPlotOffset(); - pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width()); - pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height()); - - if (o.selection.mode == "y") - pos.x = pos == selection.first ? 0 : plot.width(); - - if (o.selection.mode == "x") - pos.y = pos == selection.first ? 0 : plot.height(); - } - - function updateSelection(pos) { - if (pos.pageX == null) - return; - - setSelectionPos(selection.second, pos); - if (selectionIsSane()) { - selection.show = true; - plot.triggerRedrawOverlay(); - } - else - clearSelection(true); - } - - function clearSelection(preventEvent) { - if (selection.show) { - selection.show = false; - plot.triggerRedrawOverlay(); - if (!preventEvent) - plot.getPlaceholder().trigger("plotunselected", [ ]); - } - } - - // function taken from markings support in Flot - function extractRange(ranges, coord) { - var axis, from, to, key, axes = plot.getAxes(); - - for (var k in axes) { - axis = axes[k]; - if (axis.direction == coord) { - key = coord + axis.n + "axis"; - if (!ranges[key] && axis.n == 1) - key = coord + "axis"; // support x1axis as xaxis - if (ranges[key]) { - from = ranges[key].from; - to = ranges[key].to; - break; - } - } - } - - // backwards-compat stuff - to be removed in future - if (!ranges[key]) { - axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0]; - from = ranges[coord + "1"]; - to = ranges[coord + "2"]; - } - - // auto-reverse as an added bonus - if (from != null && to != null && from > to) { - var tmp = from; - from = to; - to = tmp; - } - - return { from: from, to: to, axis: axis }; - } - - function setSelection(ranges, preventEvent) { - var axis, range, o = plot.getOptions(); - - if (o.selection.mode == "y") { - selection.first.x = 0; - selection.second.x = plot.width(); - } - else { - range = extractRange(ranges, "x"); - - selection.first.x = range.axis.p2c(range.from); - selection.second.x = range.axis.p2c(range.to); - } - - if (o.selection.mode == "x") { - selection.first.y = 0; - selection.second.y = plot.height(); - } - else { - range = extractRange(ranges, "y"); - - selection.first.y = range.axis.p2c(range.from); - selection.second.y = range.axis.p2c(range.to); - } - - selection.show = true; - plot.triggerRedrawOverlay(); - if (!preventEvent && selectionIsSane()) - triggerSelectedEvent(); - } - - function selectionIsSane() { - var minSize = plot.getOptions().selection.minSize; - return Math.abs(selection.second.x - selection.first.x) >= minSize && - Math.abs(selection.second.y - selection.first.y) >= minSize; - } - - plot.clearSelection = clearSelection; - plot.setSelection = setSelection; - plot.getSelection = getSelection; - - plot.hooks.bindEvents.push(function(plot, eventHolder) { - var o = plot.getOptions(); - if (o.selection.mode != null) { - eventHolder.mousemove(onMouseMove); - eventHolder.mousedown(onMouseDown); - } - }); - - - plot.hooks.drawOverlay.push(function (plot, ctx) { - // draw selection - if (selection.show && selectionIsSane()) { - var plotOffset = plot.getPlotOffset(); - var o = plot.getOptions(); - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - var c = $.color.parse(o.selection.color); - - ctx.strokeStyle = c.scale('a', 0.8).toString(); - ctx.lineWidth = 1; - ctx.lineJoin = o.selection.shape; - ctx.fillStyle = c.scale('a', 0.4).toString(); - - var x = Math.min(selection.first.x, selection.second.x) + 0.5, - y = Math.min(selection.first.y, selection.second.y) + 0.5, - w = Math.abs(selection.second.x - selection.first.x) - 1, - h = Math.abs(selection.second.y - selection.first.y) - 1; - - ctx.fillRect(x, y, w, h); - ctx.strokeRect(x, y, w, h); - - ctx.restore(); - } - }); - - plot.hooks.shutdown.push(function (plot, eventHolder) { - eventHolder.unbind("mousemove", onMouseMove); - eventHolder.unbind("mousedown", onMouseDown); - - if (mouseUpHandler) - $(document).unbind("mouseup", mouseUpHandler); - }); - - } - - $.plot.plugins.push({ - init: init, - options: { - selection: { - mode: null, // one of null, "x", "y" or "xy" - color: "#e8cfac", - shape: "round", // one of "round", "miter", or "bevel" - minSize: 5 // minimum number of pixels - } - }, - name: 'selection', - version: '1.1' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.spline.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.spline.js deleted file mode 100644 index eba63568af2..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.spline.js +++ /dev/null @@ -1,249 +0,0 @@ -/** - * Flot plugin that provides spline interpolation for line graphs - * author: Alex Bardas < alex.bardas@gmail.com > - * modified by: Avi Kohn https://github.com/AMKohn - * based on the spline interpolation described at: - * http://scaledinnovation.com/analytics/splines/aboutSplines.html - * - * Example usage: (add in plot options series object) - * for linespline: - * series: { - * ... - * lines: { - * show: false - * }, - * splines: { - * show: true, - * tension: x, (float between 0 and 1, defaults to 0.5), - * lineWidth: y (number, defaults to 2), - * fill: z (float between 0 .. 1 or false, as in flot documentation) - * }, - * ... - * } - * areaspline: - * series: { - * ... - * lines: { - * show: true, - * lineWidth: 0, (line drawing will not execute) - * fill: x, (float between 0 .. 1, as in flot documentation) - * ... - * }, - * splines: { - * show: true, - * tension: 0.5 (float between 0 and 1) - * }, - * ... - * } - * - */ - -(function($) { - 'use strict' - - var yAxisMax = 0; - - /** - * @param {Number} x0, y0, x1, y1: coordinates of the end (knot) points of the segment - * @param {Number} x2, y2: the next knot (not connected, but needed to calculate p2) - * @param {Number} tension: control how far the control points spread - * @return {Array}: p1 -> control point, from x1 back toward x0 - * p2 -> the next control point, returned to become the next segment's p1 - * - * @api private - */ - function getControlPoints(x0, y0, x1, y1, x2, y2, tension) { - - var pow = Math.pow, - sqrt = Math.sqrt, - d01, d12, fa, fb, p1x, p1y, p2x, p2y; - - // Scaling factors: distances from this knot to the previous and following knots. - d01 = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2)); - d12 = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); - - fa = tension * d01 / (d01 + d12); - fb = tension - fa; - - p1x = x1 + fa * (x0 - x2); - p1y = y1 + fa * (y0 - y2); - - p2x = x1 - fb * (x0 - x2); - p2y = y1 - fb * (y0 - y2); - - if (p1y > yAxisMax) { - p1y = yAxisMax; - } - - if (p2y > yAxisMax) { - p2y = yAxisMax; - } - - return [p1x, p1y, p2x, p2y]; - } - - var line = []; - - function drawLine(points, ctx, height, fill, seriesColor,options) { - var c = $.color.parse(seriesColor); - - c.a = typeof fill == "number" ? fill : .3; - c.normalize(); - c = c.toString(); - - ctx.beginPath(); - ctx.moveTo(points[0][0], points[0][1]); - var dashed = false; - var plength = points.length; - - var dashAfter = plength; - if(options) { - dashed = options.dashed; - if(dashed === true){ - ctx.setLineDash([4, 4]); - } - - dashAfter = options.dashAfter || plength; - - if(options.alpha){ - ctx.globalAlpha = options.alpha; - } - } - - for (var i = 0; i < dashAfter && i series.xaxis.max || y < series.yaxis.min || y > series.yaxis.max) { - continue; - } - - pts.push(series.xaxis.p2c(x) + plotOffset.left, series.yaxis.p2c(y) + plotOffset.top); - } - - len = pts.length; - - // Draw an open curve, not connected at the ends - for (idx = 0; idx < len - 2; idx += 2) { - cp = cp.concat(getControlPoints.apply(this, pts.slice(idx, idx + 6).concat([tension]))); - } - - ctx.save(); - ctx.strokeStyle = series.color; - ctx.lineWidth = series.splines.lineWidth; - - queue(ctx, 'quadratic', pts.slice(0, 4), cp.slice(0, 2)); - - for (idx = 2; idx < len - 3; idx += 2) { - queue(ctx, 'bezier', pts.slice(idx, idx + 4), cp.slice(2 * idx - 2, 2 * idx + 2)); - } - - queue(ctx, 'quadratic', pts.slice(len - 2, len), [cp[2 * len - 10], cp[2 * len - 9], pts[len - 4], pts[len - 3]]); - - drawLine(line, ctx, plot.height() + 10, series.splines.fill, series.color,{alpha: series.alpha, dashed:series.dashed,dashAfter:series.dashAfter}); - - ctx.restore(); - } - - $.plot.plugins.push({ - init: function(plot) { - plot.hooks.drawSeries.push(drawSpline); - }, - options: { - series: { - splines: { - show: false, - lineWidth: 2, - tension: 0.1, - fill: false - } - } - }, - name: 'spline', - version: '0.8.2' - }); -})(jQuery); \ No newline at end of file diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js deleted file mode 100644 index e75a7dfc074..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js +++ /dev/null @@ -1,188 +0,0 @@ -/* Flot plugin for stacking data sets rather than overlyaing them. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin assumes the data is sorted on x (or y if stacking horizontally). -For line charts, it is assumed that if a line has an undefined gap (from a -null point), then the line above it should have the same gap - insert zeros -instead of "null" if you want another behaviour. This also holds for the start -and end of the chart. Note that stacking a mix of positive and negative values -in most instances doesn't make sense (so it looks weird). - -Two or more series are stacked when their "stack" attribute is set to the same -key (which can be any number or string or just "true"). To specify the default -stack, you can set the stack option like this: - - series: { - stack: null/false, true, or a key (number/string) - } - -You can also specify it for a single series, like this: - - $.plot( $("#placeholder"), [{ - data: [ ... ], - stack: true - }]) - -The stacking order is determined by the order of the data series in the array -(later series end up on top of the previous). - -Internally, the plugin modifies the datapoints in each series, adding an -offset to the y value. For line series, extra data points are inserted through -interpolation. If there's a second y value, it's also adjusted (e.g for bar -charts or filled areas). - -*/ - -(function ($) { - var options = { - series: { stack: null } // or number/string - }; - - function init(plot) { - function findMatchingSeries(s, allseries) { - var res = null; - for (var i = 0; i < allseries.length; ++i) { - if (s == allseries[i]) - break; - - if (allseries[i].stack == s.stack) - res = allseries[i]; - } - - return res; - } - - function stackData(plot, s, datapoints) { - if (s.stack == null || s.stack === false) - return; - - var other = findMatchingSeries(s, plot.getData()); - if (!other) - return; - - var ps = datapoints.pointsize, - points = datapoints.points, - otherps = other.datapoints.pointsize, - otherpoints = other.datapoints.points, - newpoints = [], - px, py, intery, qx, qy, bottom, - withlines = s.lines.show, - horizontal = s.bars.horizontal, - withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y), - withsteps = withlines && s.lines.steps, - fromgap = true, - keyOffset = horizontal ? 1 : 0, - accumulateOffset = horizontal ? 0 : 1, - i = 0, j = 0, l, m; - - while (true) { - if (i >= points.length) - break; - - l = newpoints.length; - - if (points[i] == null) { - // copy gaps - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - i += ps; - } - else if (j >= otherpoints.length) { - // for lines, we can't use the rest of the points - if (!withlines) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - } - i += ps; - } - else if (otherpoints[j] == null) { - // oops, got a gap - for (m = 0; m < ps; ++m) - newpoints.push(null); - fromgap = true; - j += otherps; - } - else { - // cases where we actually got two points - px = points[i + keyOffset]; - py = points[i + accumulateOffset]; - qx = otherpoints[j + keyOffset]; - qy = otherpoints[j + accumulateOffset]; - bottom = 0; - - if (px == qx) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - - newpoints[l + accumulateOffset] += qy; - bottom = qy; - - i += ps; - j += otherps; - } - else if (px > qx) { - // we got past point below, might need to - // insert interpolated extra point - if (withlines && i > 0 && points[i - ps] != null) { - intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px); - newpoints.push(qx); - newpoints.push(intery + qy); - for (m = 2; m < ps; ++m) - newpoints.push(points[i + m]); - bottom = qy; - } - - j += otherps; - } - else { // px < qx - if (fromgap && withlines) { - // if we come from a gap, we just skip this point - i += ps; - continue; - } - - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - - // we might be able to interpolate a point below, - // this can give us a better y - if (withlines && j > 0 && otherpoints[j - otherps] != null) - bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx); - - newpoints[l + accumulateOffset] += bottom; - - i += ps; - } - - fromgap = false; - - if (l != newpoints.length && withbottom) - newpoints[l + 2] += bottom; - } - - // maintain the line steps invariant - if (withsteps && l != newpoints.length && l > 0 - && newpoints[l] != null - && newpoints[l] != newpoints[l - ps] - && newpoints[l + 1] != newpoints[l - ps + 1]) { - for (m = 0; m < ps; ++m) - newpoints[l + ps + m] = newpoints[l + m]; - newpoints[l + 1] = newpoints[l - ps + 1]; - } - } - - datapoints.points = newpoints; - } - - plot.hooks.processDatapoints.push(stackData); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'stack', - version: '1.2' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.symbol.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.symbol.js deleted file mode 100644 index 79f634971b6..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.symbol.js +++ /dev/null @@ -1,71 +0,0 @@ -/* Flot plugin that adds some extra symbols for plotting points. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The symbols are accessed as strings through the standard symbol options: - - series: { - points: { - symbol: "square" // or "diamond", "triangle", "cross" - } - } - -*/ - -(function ($) { - function processRawData(plot, series, datapoints) { - // we normalize the area of each symbol so it is approximately the - // same as a circle of the given radius - - var handlers = { - square: function (ctx, x, y, radius, shadow) { - // pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2 - var size = radius * Math.sqrt(Math.PI) / 2; - ctx.rect(x - size, y - size, size + size, size + size); - }, - diamond: function (ctx, x, y, radius, shadow) { - // pi * r^2 = 2s^2 => s = r * sqrt(pi/2) - var size = radius * Math.sqrt(Math.PI / 2); - ctx.moveTo(x - size, y); - ctx.lineTo(x, y - size); - ctx.lineTo(x + size, y); - ctx.lineTo(x, y + size); - ctx.lineTo(x - size, y); - }, - triangle: function (ctx, x, y, radius, shadow) { - // pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3)) - var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3)); - var height = size * Math.sin(Math.PI / 3); - ctx.moveTo(x - size/2, y + height/2); - ctx.lineTo(x + size/2, y + height/2); - if (!shadow) { - ctx.lineTo(x, y - height/2); - ctx.lineTo(x - size/2, y + height/2); - } - }, - cross: function (ctx, x, y, radius, shadow) { - // pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2 - var size = radius * Math.sqrt(Math.PI) / 2; - ctx.moveTo(x - size, y - size); - ctx.lineTo(x + size, y + size); - ctx.moveTo(x - size, y + size); - ctx.lineTo(x + size, y - size); - } - }; - - var s = series.points.symbol; - if (handlers[s]) - series.points.symbol = handlers[s]; - } - - function init(plot) { - plot.hooks.processDatapoints.push(processRawData); - } - - $.plot.plugins.push({ - init: init, - name: 'symbols', - version: '1.0' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.threshold.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.threshold.js deleted file mode 100644 index 8c99c401d87..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.threshold.js +++ /dev/null @@ -1,142 +0,0 @@ -/* Flot plugin for thresholding data. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin supports these options: - - series: { - threshold: { - below: number - color: colorspec - } - } - -It can also be applied to a single series, like this: - - $.plot( $("#placeholder"), [{ - data: [ ... ], - threshold: { ... } - }]) - -An array can be passed for multiple thresholding, like this: - - threshold: [{ - below: number1 - color: color1 - },{ - below: number2 - color: color2 - }] - -These multiple threshold objects can be passed in any order since they are -sorted by the processing function. - -The data points below "below" are drawn with the specified color. This makes -it easy to mark points below 0, e.g. for budget data. - -Internally, the plugin works by splitting the data into two series, above and -below the threshold. The extra series below the threshold will have its label -cleared and the special "originSeries" attribute set to the original series. -You may need to check for this in hover events. - -*/ - -(function ($) { - var options = { - series: { threshold: null } // or { below: number, color: color spec} - }; - - function init(plot) { - function thresholdData(plot, s, datapoints, below, color) { - var ps = datapoints.pointsize, i, x, y, p, prevp, - thresholded = $.extend({}, s); // note: shallow copy - - thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format }; - thresholded.label = null; - thresholded.color = color; - thresholded.threshold = null; - thresholded.originSeries = s; - thresholded.data = []; - - var origpoints = datapoints.points, - addCrossingPoints = s.lines.show; - - var threspoints = []; - var newpoints = []; - var m; - - for (i = 0; i < origpoints.length; i += ps) { - x = origpoints[i]; - y = origpoints[i + 1]; - - prevp = p; - if (y < below) - p = threspoints; - else - p = newpoints; - - if (addCrossingPoints && prevp != p && x != null - && i > 0 && origpoints[i - ps] != null) { - var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]); - prevp.push(interx); - prevp.push(below); - for (m = 2; m < ps; ++m) - prevp.push(origpoints[i + m]); - - p.push(null); // start new segment - p.push(null); - for (m = 2; m < ps; ++m) - p.push(origpoints[i + m]); - p.push(interx); - p.push(below); - for (m = 2; m < ps; ++m) - p.push(origpoints[i + m]); - } - - p.push(x); - p.push(y); - for (m = 2; m < ps; ++m) - p.push(origpoints[i + m]); - } - - datapoints.points = newpoints; - thresholded.datapoints.points = threspoints; - - if (thresholded.datapoints.points.length > 0) { - var origIndex = $.inArray(s, plot.getData()); - // Insert newly-generated series right after original one (to prevent it from becoming top-most) - plot.getData().splice(origIndex + 1, 0, thresholded); - } - - // FIXME: there are probably some edge cases left in bars - } - - function processThresholds(plot, s, datapoints) { - if (!s.threshold) - return; - - if (s.threshold instanceof Array) { - s.threshold.sort(function(a, b) { - return a.below - b.below; - }); - - $(s.threshold).each(function(i, th) { - thresholdData(plot, s, datapoints, th.below, th.color); - }); - } - else { - thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color); - } - } - - plot.hooks.processDatapoints.push(processThresholds); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'threshold', - version: '1.2' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js deleted file mode 100644 index c9476e2a271..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js +++ /dev/null @@ -1,207 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is flot-tickrotor. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Mark Cote - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * flot-tickrotor: flot plugin to display angled X-axis tick labels. - * - * Requires flot 0.7 or higher and a browser supporting . - * - * To activate, just set xaxis.rotateTicks to an angle in degrees. Labels - * are rotated clockwise, so if you want the labels to angle up and to the right (/) - * you need to provide an angle > 90. The text will be flipped so that it is still - * right-side-up. - * Angles greater than or equal to 180 are ignored. - */ -(function ($) { - var options = { }; - - function init(plot) { - // Taken from flot-axislabels. - // This is kind of a hack. There are no hooks in Flot between - // the creation and measuring of the ticks (setTicks, measureTickLabels - // in setupGrid() ) and the drawing of the ticks and plot box - // (insertAxisLabels in setupGrid() ). - // - // Therefore, we use a trick where we run the draw routine twice: - // the first time to get the tick measurements, so that we can change - // them, and then have it draw it again. - var ticks = []; - var font; - var secondPass = false; - var rotateTicks, rotateTicksRads, radsAboveHoriz; - plot.hooks.draw.push(function (plot, ctx) { - if (!secondPass) { - var opts = plot.getAxes().xaxis.options; - if (opts.rotateTicks === undefined) { - return; - } - - rotateTicks = parseInt(opts.rotateTicks, 10); - if (rotateTicks.toString() != opts.rotateTicks || rotateTicks == 0 || rotateTicks >= 180) { - return; - } - - rotateTicksRads = rotateTicks * Math.PI/180; - if (rotateTicks > 90) { - radsAboveHoriz = Math.PI - rotateTicksRads; - } else { - radsAboveHoriz = Math.PI/2 - rotateTicksRads; - } - - font = opts.rotateTicksFont; - if (!font) { - font = $('.tickLabel').css('font'); - } - if (!font) { - font = '11px sans-serif'; - } - - var elem, maxLabelWidth = 0, maxLabelHeight = 0, minX = 0, maxX = 0; - - var xaxis = plot.getAxes().xaxis; - ticks = plot.getAxes().xaxis.ticks; - opts.ticks = []; // we'll make our own - - var x; - for (var i = 0; i < ticks.length; i++) { - elem = $('' + ticks[i].label + '
      '); - //console.log(elem) - plot.getPlaceholder().append(elem); - ticks[i].height = elem.outerHeight(true); - ticks[i].width = elem.outerWidth(true); - elem.remove(); - if (ticks[i].height > maxLabelHeight) { - maxLabelHeight = ticks[i].height; - } - if (ticks[i].width > maxLabelWidth) { - maxLabelWidth = ticks[i].width; - } - var tick = ticks[i]; - // See second-draw code below for explanation of offsets. - if (rotateTicks > 90) { - // See if any labels are too long and require increased left - // padding. - x = Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v)) - - Math.ceil(Math.cos(radsAboveHoriz) * tick.height) - - Math.ceil(Math.cos(radsAboveHoriz) * tick.width); - if (x < minX) { - minX = x; - } - } else { - // See if any labels are too long and require increased right - // padding. - x = Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v)) - + Math.ceil(Math.cos(radsAboveHoriz) * tick.height) - + Math.ceil(Math.cos(radsAboveHoriz) * tick.width); - if (x > maxX) { - maxX = x; - } - } - } - - // Calculate maximum label height after rotating. - if (rotateTicks > 90) { - var acuteRads = rotateTicksRads - Math.PI/2; - opts.labelHeight = Math.ceil(Math.sin(acuteRads) * maxLabelWidth) - + Math.ceil(Math.sin(acuteRads) * maxLabelHeight); - } else { - var acuteRads = Math.PI/2 - rotateTicksRads; - // Center such that the top of the label is at the center of the tick. - opts.labelHeight = Math.ceil(Math.sin(rotateTicksRads) * maxLabelWidth) - + Math.ceil(Math.sin(acuteRads) * maxLabelHeight); - } - - if (minX < 0) { - plot.getAxes().yaxis.options.labelWidth = -1 * minX; - } - - // Doesn't seem to work if there are no values using the second y axis. - //if (maxX > xaxis.box.left + xaxis.box.width) { - // plot.getAxes().y2axis.options.labelWidth = maxX - xaxis.box.left - xaxis.box.width; - //} - - // re-draw with new label widths and heights - secondPass = true; - plot.setupGrid(); - plot.draw(); - } else { - if (ticks.length == 0) { - return; - } - var xaxis = plot.getAxes().xaxis; - var box = xaxis.box; - var tick, label, xoffset, yoffset; - for (var i = 0; i < ticks.length; i++) { - tick = ticks[i]; - if (!tick.label) { - continue; - } - ctx.save(); - ctx.font = font; - if (rotateTicks <= 90) { - // Center such that the top of the label is at the center of the tick. - xoffset = -Math.ceil(Math.cos(radsAboveHoriz) * tick.height); - yoffset = Math.ceil(Math.sin(radsAboveHoriz) * tick.height); - ctx.translate(Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v)) + xoffset, - box.top + box.padding + plot.getOptions().grid.labelMargin + yoffset); - ctx.rotate(rotateTicksRads); - } else { - // We want the text to facing up, so we have to rotate counterclockwise, - // which means the label has to *end* at the center of the tick. - xoffset = Math.ceil(Math.cos(radsAboveHoriz) * tick.height) - - Math.ceil(Math.cos(radsAboveHoriz) * tick.width); - yoffset = Math.ceil(Math.sin(radsAboveHoriz) * tick.width) - + Math.ceil(Math.sin(radsAboveHoriz) * tick.height); - ctx.translate(Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v) + xoffset), - box.top + box.padding + plot.getOptions().grid.labelMargin + yoffset); - ctx.rotate(-radsAboveHoriz); - } - ctx.fillStyle = '#999'; - ctx.fillText(tick.label, 0, 0); - ctx.restore(); - } - } - }); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'tickRotor', - version: '1.0' - }); -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/flot/jquery.flot.time.js b/frontend/express/public/javascripts/visualization/flot/jquery.flot.time.js deleted file mode 100644 index 34c1d121259..00000000000 --- a/frontend/express/public/javascripts/visualization/flot/jquery.flot.time.js +++ /dev/null @@ -1,432 +0,0 @@ -/* Pretty handling of time axes. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -Set axis.mode to "time" to enable. See the section "Time series data" in -API.txt for details. - -*/ - -(function($) { - - var options = { - xaxis: { - timezone: null, // "browser" for local to the client or timezone for timezone-js - timeformat: null, // format string to use - twelveHourClock: false, // 12 or 24 time in time mode - monthNames: null // list of names of months - } - }; - - // round to nearby lower multiple of base - - function floorInBase(n, base) { - return base * Math.floor(n / base); - } - - // Returns a string with the date d formatted according to fmt. - // A subset of the Open Group's strftime format is supported. - - function formatDate(d, fmt, monthNames, dayNames) { - - if (typeof d.strftime == "function") { - return d.strftime(fmt); - } - - var leftPad = function(n, pad) { - n = "" + n; - pad = "" + (pad == null ? "0" : pad); - return n.length == 1 ? pad + n : n; - }; - - var r = []; - var escape = false; - var hours = d.getHours(); - var isAM = hours < 12; - - if (monthNames == null) { - monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - } - - if (dayNames == null) { - dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - } - - var hours12; - - if (hours > 12) { - hours12 = hours - 12; - } else if (hours == 0) { - hours12 = 12; - } else { - hours12 = hours; - } - - for (var i = 0; i < fmt.length; ++i) { - - var c = fmt.charAt(i); - - if (escape) { - switch (c) { - case 'a': c = "" + dayNames[d.getDay()]; break; - case 'b': c = "" + monthNames[d.getMonth()]; break; - case 'd': c = leftPad(d.getDate()); break; - case 'e': c = leftPad(d.getDate(), " "); break; - case 'h': // For back-compat with 0.7; remove in 1.0 - case 'H': c = leftPad(hours); break; - case 'I': c = leftPad(hours12); break; - case 'l': c = leftPad(hours12, " "); break; - case 'm': c = leftPad(d.getMonth() + 1); break; - case 'M': c = leftPad(d.getMinutes()); break; - // quarters not in Open Group's strftime specification - case 'q': - c = "" + (Math.floor(d.getMonth() / 3) + 1); break; - case 'S': c = leftPad(d.getSeconds()); break; - case 'y': c = leftPad(d.getFullYear() % 100); break; - case 'Y': c = "" + d.getFullYear(); break; - case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; - case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; - case 'w': c = "" + d.getDay(); break; - } - r.push(c); - escape = false; - } else { - if (c == "%") { - escape = true; - } else { - r.push(c); - } - } - } - - return r.join(""); - } - - // To have a consistent view of time-based data independent of which time - // zone the client happens to be in we need a date-like object independent - // of time zones. This is done through a wrapper that only calls the UTC - // versions of the accessor methods. - - function makeUtcWrapper(d) { - - function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { - sourceObj[sourceMethod] = function() { - return targetObj[targetMethod].apply(targetObj, arguments); - }; - }; - - var utc = { - date: d - }; - - // support strftime, if found - - if (d.strftime != undefined) { - addProxyMethod(utc, "strftime", d, "strftime"); - } - - addProxyMethod(utc, "getTime", d, "getTime"); - addProxyMethod(utc, "setTime", d, "setTime"); - - var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; - - for (var p = 0; p < props.length; p++) { - addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); - addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); - } - - return utc; - }; - - // select time zone strategy. This returns a date-like object tied to the - // desired timezone - - function dateGenerator(ts, opts) { - if (opts.timezone == "browser") { - return new Date(ts); - } else if (!opts.timezone || opts.timezone == "utc") { - return makeUtcWrapper(new Date(ts)); - } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { - var d = new timezoneJS.Date(); - // timezone-js is fickle, so be sure to set the time zone before - // setting the time. - d.setTimezone(opts.timezone); - d.setTime(ts); - return d; - } else { - return makeUtcWrapper(new Date(ts)); - } - } - - // map of app. size of time units in milliseconds - - var timeUnitSize = { - "second": 1000, - "minute": 60 * 1000, - "hour": 60 * 60 * 1000, - "day": 24 * 60 * 60 * 1000, - "month": 30 * 24 * 60 * 60 * 1000, - "quarter": 3 * 30 * 24 * 60 * 60 * 1000, - "year": 365.2425 * 24 * 60 * 60 * 1000 - }; - - // the allowed tick sizes, after 1 year we use - // an integer algorithm - - var baseSpec = [ - [1, "second"], [2, "second"], [5, "second"], [10, "second"], - [30, "second"], - [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], - [30, "minute"], - [1, "hour"], [2, "hour"], [4, "hour"], - [8, "hour"], [12, "hour"], - [1, "day"], [2, "day"], [3, "day"], - [0.25, "month"], [0.5, "month"], [1, "month"], - [2, "month"] - ]; - - // we don't know which variant(s) we'll need yet, but generating both is - // cheap - - var specMonths = baseSpec.concat([[3, "month"], [6, "month"], - [1, "year"]]); - var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], - [1, "year"]]); - - function init(plot) { - plot.hooks.processOptions.push(function (plot, options) { - $.each(plot.getAxes(), function(axisName, axis) { - - var opts = axis.options; - - if (opts.mode == "time") { - axis.tickGenerator = function(axis) { - - var ticks = []; - var d = dateGenerator(axis.min, opts); - var minSize = 0; - - // make quarter use a possibility if quarters are - // mentioned in either of these options - - var spec = (opts.tickSize && opts.tickSize[1] === - "quarter") || - (opts.minTickSize && opts.minTickSize[1] === - "quarter") ? specQuarters : specMonths; - - if (opts.minTickSize != null) { - if (typeof opts.tickSize == "number") { - minSize = opts.tickSize; - } else { - minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; - } - } - - for (var i = 0; i < spec.length - 1; ++i) { - if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] - + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 - && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { - break; - } - } - - var size = spec[i][0]; - var unit = spec[i][1]; - - // special-case the possibility of several years - - if (unit == "year") { - - // if given a minTickSize in years, just use it, - // ensuring that it's an integer - - if (opts.minTickSize != null && opts.minTickSize[1] == "year") { - size = Math.floor(opts.minTickSize[0]); - } else { - - var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); - var norm = (axis.delta / timeUnitSize.year) / magn; - - if (norm < 1.5) { - size = 1; - } else if (norm < 3) { - size = 2; - } else if (norm < 7.5) { - size = 5; - } else { - size = 10; - } - - size *= magn; - } - - // minimum size for years is 1 - - if (size < 1) { - size = 1; - } - } - - axis.tickSize = opts.tickSize || [size, unit]; - var tickSize = axis.tickSize[0]; - unit = axis.tickSize[1]; - - var step = tickSize * timeUnitSize[unit]; - - if (unit == "second") { - d.setSeconds(floorInBase(d.getSeconds(), tickSize)); - } else if (unit == "minute") { - d.setMinutes(floorInBase(d.getMinutes(), tickSize)); - } else if (unit == "hour") { - d.setHours(floorInBase(d.getHours(), tickSize)); - } else if (unit == "month") { - d.setMonth(floorInBase(d.getMonth(), tickSize)); - } else if (unit == "quarter") { - d.setMonth(3 * floorInBase(d.getMonth() / 3, - tickSize)); - } else if (unit == "year") { - d.setFullYear(floorInBase(d.getFullYear(), tickSize)); - } - - // reset smaller components - - d.setMilliseconds(0); - - if (step >= timeUnitSize.minute) { - d.setSeconds(0); - } - if (step >= timeUnitSize.hour) { - d.setMinutes(0); - } - if (step >= timeUnitSize.day) { - d.setHours(0); - } - if (step >= timeUnitSize.day * 4) { - d.setDate(1); - } - if (step >= timeUnitSize.month * 2) { - d.setMonth(floorInBase(d.getMonth(), 3)); - } - if (step >= timeUnitSize.quarter * 2) { - d.setMonth(floorInBase(d.getMonth(), 6)); - } - if (step >= timeUnitSize.year) { - d.setMonth(0); - } - - var carry = 0; - var v = Number.NaN; - var prev; - - do { - - prev = v; - v = d.getTime(); - ticks.push(v); - - if (unit == "month" || unit == "quarter") { - if (tickSize < 1) { - - // a bit complicated - we'll divide the - // month/quarter up but we need to take - // care of fractions so we don't end up in - // the middle of a day - - d.setDate(1); - var start = d.getTime(); - d.setMonth(d.getMonth() + - (unit == "quarter" ? 3 : 1)); - var end = d.getTime(); - d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); - carry = d.getHours(); - d.setHours(0); - } else { - d.setMonth(d.getMonth() + - tickSize * (unit == "quarter" ? 3 : 1)); - } - } else if (unit == "year") { - d.setFullYear(d.getFullYear() + tickSize); - } else { - d.setTime(v + step); - } - } while (v < axis.max && v != prev); - - return ticks; - }; - - axis.tickFormatter = function (v, axis) { - - var d = dateGenerator(v, axis.options); - - // first check global format - - if (opts.timeformat != null) { - return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); - } - - // possibly use quarters if quarters are mentioned in - // any of these places - - var useQuarters = (axis.options.tickSize && - axis.options.tickSize[1] == "quarter") || - (axis.options.minTickSize && - axis.options.minTickSize[1] == "quarter"); - - var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; - var span = axis.max - axis.min; - var suffix = (opts.twelveHourClock) ? " %p" : ""; - var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; - var fmt; - - if (t < timeUnitSize.minute) { - fmt = hourCode + ":%M:%S" + suffix; - } else if (t < timeUnitSize.day) { - if (span < 2 * timeUnitSize.day) { - fmt = hourCode + ":%M" + suffix; - } else { - fmt = "%b %d " + hourCode + ":%M" + suffix; - } - } else if (t < timeUnitSize.month) { - fmt = "%b %d"; - } else if ((useQuarters && t < timeUnitSize.quarter) || - (!useQuarters && t < timeUnitSize.year)) { - if (span < timeUnitSize.year) { - fmt = "%b"; - } else { - fmt = "%b %Y"; - } - } else if (useQuarters && t < timeUnitSize.year) { - if (span < timeUnitSize.year) { - fmt = "Q%q"; - } else { - fmt = "Q%q %Y"; - } - } else { - fmt = "%Y"; - } - - var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); - - return rt; - }; - } - }); - }); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'time', - version: '1.0' - }); - - // Time-axis support used to be in Flot core, which exposed the - // formatDate function on the plot object. Various plugins depend - // on the function, so we need to re-expose it here. - - $.plot.formatDate = formatDate; - $.plot.dateGenerator = dateGenerator; - -})(jQuery); diff --git a/frontend/express/public/javascripts/visualization/gauge.min.js b/frontend/express/public/javascripts/visualization/gauge.min.js deleted file mode 100644 index 07d5b84ee15..00000000000 --- a/frontend/express/public/javascripts/visualization/gauge.min.js +++ /dev/null @@ -1,49 +0,0 @@ - -(function(){var AnimatedText,AnimatedTextFactory,Bar,BaseDonut,BaseGauge,Donut,Gauge,GaugePointer,TextRenderer,ValueUpdater,addCommas,formatNumber,mergeObjects,secondsToString,updateObjectValues,__hasProp={}.hasOwnProperty,__extends=function(child,parent){for(var key in parent){if(__hasProp.call(parent,key))child[key]=parent[key];}function ctor(){this.constructor=child;}ctor.prototype=parent.prototype;child.prototype=new ctor();child.__super__=parent.prototype;return child;};(function(){var browserRequestAnimationFrame,isCancelled,lastId,vendor,vendors,_i,_len;vendors=['ms','moz','webkit','o'];for(_i=0,_len=vendors.length;_i<_len;_i++){vendor=vendors[_i];if(window.requestAnimationFrame){break;} -window.requestAnimationFrame=window[vendor+'RequestAnimationFrame'];window.cancelAnimationFrame=window[vendor+'CancelAnimationFrame']||window[vendor+'CancelRequestAnimationFrame'];} -browserRequestAnimationFrame=null;lastId=0;isCancelled={};if(!requestAnimationFrame){window.requestAnimationFrame=function(callback,element){var currTime,id,lastTime,timeToCall;currTime=new Date().getTime();timeToCall=Math.max(0,16-(currTime-lastTime));id=window.setTimeout(function(){return callback(currTime+timeToCall);},timeToCall);lastTime=currTime+timeToCall;return id;};return window.cancelAnimationFrame=function(id){return clearTimeout(id);};}else if(!window.cancelAnimationFrame){browserRequestAnimationFrame=window.requestAnimationFrame;window.requestAnimationFrame=function(callback,element){var myId;myId=++lastId;browserRequestAnimationFrame(function(){if(!isCancelled[myId]){return callback();}},element);return myId;};return window.cancelAnimationFrame=function(id){return isCancelled[id]=true;};}})();String.prototype.hashCode=function(){var charMod,hash,i,_i,_ref;hash=0;if(this.length===0){return hash;} -for(i=_i=0,_ref=this.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){charMod=this.charCodeAt(i);hash=((hash<<5)-hash)+charMod;hash=hash&hash;} -return hash;};secondsToString=function(sec){var hr,min;hr=Math.floor(sec/3600);min=Math.floor((sec-(hr*3600))/60);sec-=(hr*3600)+(min*60);sec+='';min+='';while(min.length<2){min='0'+min;} -while(sec.length<2){sec='0'+sec;} -hr=hr?hr+':':'';return hr+min+':'+sec;};formatNumber=function(num){return addCommas(num.toFixed(0));};updateObjectValues=function(obj1,obj2){var key,val;for(key in obj2){if(!__hasProp.call(obj2,key))continue;val=obj2[key];obj1[key]=val;} -return obj1;};mergeObjects=function(obj1,obj2){var key,out,val;out={};for(key in obj1){if(!__hasProp.call(obj1,key))continue;val=obj1[key];out[key]=val;} -for(key in obj2){if(!__hasProp.call(obj2,key))continue;val=obj2[key];out[key]=val;} -return out;};addCommas=function(nStr){var rgx,x,x1,x2;nStr+='';x=nStr.split('.');x1=x[0];x2='';if(x.length>1){x2='.'+x[1];} -rgx=/(\d+)(\d{3})/;while(rgx.test(x1)){x1=x1.replace(rgx,'$1'+','+'$2');} -return x1+x2;};ValueUpdater=(function(){ValueUpdater.prototype.animationSpeed=32;function ValueUpdater(addToAnimationQueue,clear){if(addToAnimationQueue==null){addToAnimationQueue=true;} -this.clear=clear!=null?clear:true;if(addToAnimationQueue){AnimationUpdater.add(this);}} -ValueUpdater.prototype.update=function(force){var diff;if(force==null){force=false;} -if(force||this.displayedValue!==this.value){if(this.ctx&&this.clear){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);} -diff=this.value-this.displayedValue;if(Math.abs(diff/this.animationSpeed)<=0.001){this.displayedValue=this.value;}else{this.displayedValue=this.displayedValue+diff/this.animationSpeed;} -this.render();return true;} -return false;};return ValueUpdater;})();BaseGauge=(function(_super){__extends(BaseGauge,_super);function BaseGauge(){return BaseGauge.__super__.constructor.apply(this,arguments);} -BaseGauge.prototype.setTextField=function(textField){return this.textField=textField instanceof TextRenderer?textField:new TextRenderer(textField);};BaseGauge.prototype.setOptions=function(options){if(options==null){options=null;} -this.options=mergeObjects(this.options,options);if(this.textField){this.textField.el.style.fontSize=options.fontSize+'px';} -return this;};return BaseGauge;})(ValueUpdater);TextRenderer=(function(){function TextRenderer(el){this.el=el;} -TextRenderer.prototype.render=function(gauge){return this.el.innerHTML=formatNumber(gauge.displayedValue);};return TextRenderer;})();AnimatedText=(function(_super){__extends(AnimatedText,_super);AnimatedText.prototype.displayedValue=0;AnimatedText.prototype.value=0;AnimatedText.prototype.setVal=function(value){return this.value=1*value;};function AnimatedText(elem,text){this.elem=elem;this.text=text!=null?text:false;this.value=1*this.elem.innerHTML;if(this.text){this.value=0;}} -AnimatedText.prototype.render=function(){var textVal;if(this.text){textVal=secondsToString(this.displayedValue.toFixed(0));}else{textVal=addCommas(formatNumber(this.displayedValue));} -return this.elem.innerHTML=textVal;};return AnimatedText;})(ValueUpdater);AnimatedTextFactory={create:function(objList){var elem,out,_i,_len;out=[];for(_i=0,_len=objList.length;_i<_len;_i++){elem=objList[_i];out.push(new AnimatedText(elem));} -return out;}};GaugePointer=(function(_super){__extends(GaugePointer,_super);GaugePointer.prototype.displayedValue=0;GaugePointer.prototype.value=0;GaugePointer.prototype.options={strokeWidth:0.035,length:0.1,color:"#000000"};function GaugePointer(gauge){this.gauge=gauge;this.ctx=this.gauge.ctx;this.canvas=this.gauge.canvas;GaugePointer.__super__.constructor.call(this,false,false);this.setOptions();} -GaugePointer.prototype.setOptions=function(options){if(options==null){options=null;} -updateObjectValues(this.options,options);this.length=this.canvas.height*this.options.length;this.strokeWidth=this.canvas.height*this.options.strokeWidth;this.maxValue=this.gauge.maxValue;return this.animationSpeed=this.gauge.animationSpeed;};GaugePointer.prototype.render=function(){var angle,centerX,centerY,endX,endY,startX,startY,x,y;angle=this.gauge.getAngle.call(this,this.displayedValue);centerX=this.canvas.width/2;centerY=this.canvas.height*0.9;x=Math.round(centerX+this.length*Math.cos(angle));y=Math.round(centerY+this.length*Math.sin(angle));startX=Math.round(centerX+this.strokeWidth*Math.cos(angle-Math.PI/2));startY=Math.round(centerY+this.strokeWidth*Math.sin(angle-Math.PI/2));endX=Math.round(centerX+this.strokeWidth*Math.cos(angle+Math.PI/2));endY=Math.round(centerY+this.strokeWidth*Math.sin(angle+Math.PI/2));this.ctx.fillStyle=this.options.color;this.ctx.beginPath();this.ctx.arc(centerX,centerY,this.strokeWidth,0,Math.PI*2,true);this.ctx.fill();this.ctx.beginPath();this.ctx.moveTo(startX,startY);this.ctx.lineTo(x,y);this.ctx.lineTo(endX,endY);return this.ctx.fill();};return GaugePointer;})(ValueUpdater);Bar=(function(){function Bar(elem){this.elem=elem;} -Bar.prototype.updateValues=function(arrValues){this.value=arrValues[0];this.maxValue=arrValues[1];this.avgValue=arrValues[2];return this.render();};Bar.prototype.render=function(){var avgPercent,valPercent;if(this.textField){this.textField.text(formatNumber(this.value));} -if(this.maxValue===0){this.maxValue=this.avgValue*2;} -valPercent=(this.value/this.maxValue)*100;avgPercent=(this.avgValue/this.maxValue)*100;$(".bar-value",this.elem).css({"width":valPercent+"%"});return $(".typical-value",this.elem).css({"width":avgPercent+"%"});};return Bar;})();Gauge=(function(_super){__extends(Gauge,_super);Gauge.prototype.elem=null;Gauge.prototype.value=[20];Gauge.prototype.maxValue=80;Gauge.prototype.displayedAngle=0;Gauge.prototype.displayedValue=0;Gauge.prototype.lineWidth=40;Gauge.prototype.paddingBottom=0.1;Gauge.prototype.options={colorStart:"#6fadcf",colorStop:void 0,strokeColor:"#e0e0e0",pointer:{length:0.8,strokeWidth:0.035},angle:0.15,lineWidth:0.44,fontSize:40};function Gauge(canvas){this.canvas=canvas;Gauge.__super__.constructor.call(this);this.ctx=this.canvas.getContext('2d');this.gp=[new GaugePointer(this)];this.setOptions();this.render();} -Gauge.prototype.setOptions=function(options){var gauge,_i,_len,_ref;if(options==null){options=null;} -Gauge.__super__.setOptions.call(this,options);this.lineWidth=this.canvas.height*(1-this.paddingBottom)*this.options.lineWidth;this.radius=this.canvas.height*(1-this.paddingBottom)-this.lineWidth;_ref=this.gp;for(_i=0,_len=_ref.length;_i<_len;_i++){gauge=_ref[_i];gauge.setOptions(this.options.pointer);} -return this;};Gauge.prototype.set=function(value){var i,val,_i,_j,_len,_ref;if(!(value instanceof Array)){value=[value];} -if(value.length>this.gp.length){for(i=_i=0,_ref=value.length-this.gp.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){this.gp.push(new GaugePointer(this));}} -i=0;for(_j=0,_len=value.length;_j<_len;_j++){val=value[_j];if(val>this.maxValue){this.maxValue=this.value*1.1;} -this.gp[i].value=val;this.gp[i++].setOptions({maxValue:this.maxValue,angle:this.options.angle});} -this.value=value[value.length-1];return AnimationUpdater.run();};Gauge.prototype.getAngle=function(value){return(1+this.options.angle)*Math.PI+(value/this.maxValue)*(1-this.options.angle*2)*Math.PI;};Gauge.prototype.render=function(){var displayedAngle,fillStyle,gauge,h,w,_i,_len,_ref,_results;w=this.canvas.width/2;h=this.canvas.height*(1-this.paddingBottom);displayedAngle=this.getAngle(this.displayedValue);if(this.textField){this.textField.render(this);} -this.ctx.lineCap="butt";if(this.options.colorStop!==void 0){fillStyle=this.ctx.createRadialGradient(w,h,9,w,h,70);fillStyle.addColorStop(0,this.options.colorStart);fillStyle.addColorStop(1,this.options.colorStop);}else{fillStyle=this.options.colorStart;} -this.ctx.strokeStyle=fillStyle;this.ctx.beginPath();this.ctx.arc(w,h,this.radius,(1+this.options.angle)*Math.PI,displayedAngle,false);this.ctx.lineWidth=this.lineWidth;this.ctx.stroke();this.ctx.strokeStyle=this.options.strokeColor;this.ctx.beginPath();this.ctx.arc(w,h,this.radius,displayedAngle,(2-this.options.angle)*Math.PI,false);this.ctx.stroke();_ref=this.gp;_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++){gauge=_ref[_i];_results.push(gauge.update(true));} -return _results;};return Gauge;})(BaseGauge);BaseDonut=(function(_super){__extends(BaseDonut,_super);BaseDonut.prototype.lineWidth=15;BaseDonut.prototype.displayedValue=0;BaseDonut.prototype.value=33;BaseDonut.prototype.maxValue=80;BaseDonut.prototype.options={lineWidth:0.10,colorStart:"#6f6ea0",colorStop:"#c0c0db",strokeColor:"#eeeeee",shadowColor:"#d5d5d5",angle:0.35};function BaseDonut(canvas){this.canvas=canvas;BaseDonut.__super__.constructor.call(this);this.ctx=this.canvas.getContext('2d');this.setOptions();this.render();} -BaseDonut.prototype.getAngle=function(value){return(1-this.options.angle)*Math.PI+(value/this.maxValue)*((2+this.options.angle)-(1-this.options.angle))*Math.PI;};BaseDonut.prototype.setOptions=function(options){if(options==null){options=null;} -BaseDonut.__super__.setOptions.call(this,options);this.lineWidth=this.canvas.height*this.options.lineWidth;this.radius=this.canvas.height/2-this.lineWidth/2;return this;};BaseDonut.prototype.set=function(value){this.value=value;if(this.value>this.maxValue){this.maxValue=this.value*1.1;} -return AnimationUpdater.run();};BaseDonut.prototype.render=function(){var displayedAngle,grdFill,h,start,stop,w;displayedAngle=this.getAngle(this.displayedValue);w=this.canvas.width/2;h=this.canvas.height/2;if(this.textField){this.textField.render(this);} -grdFill=this.ctx.createRadialGradient(w,h,39,w,h,70);grdFill.addColorStop(0,this.options.colorStart);grdFill.addColorStop(1,this.options.colorStop);start=this.radius-this.lineWidth/2;stop=this.radius+this.lineWidth/2;this.ctx.strokeStyle=this.options.strokeColor;this.ctx.beginPath();this.ctx.arc(w,h,this.radius,(1-this.options.angle)*Math.PI,(2+this.options.angle)*Math.PI,false);this.ctx.lineWidth=this.lineWidth;this.ctx.lineCap="round";this.ctx.stroke();this.ctx.strokeStyle=grdFill;this.ctx.beginPath();this.ctx.arc(w,h,this.radius,(1-this.options.angle)*Math.PI,displayedAngle,false);return this.ctx.stroke();};return BaseDonut;})(BaseGauge);Donut=(function(_super){__extends(Donut,_super);function Donut(){return Donut.__super__.constructor.apply(this,arguments);} -Donut.prototype.strokeGradient=function(w,h,start,stop){var grd;grd=this.ctx.createRadialGradient(w,h,start,w,h,stop);grd.addColorStop(0,this.options.shadowColor);grd.addColorStop(0.12,this.options._orgStrokeColor);grd.addColorStop(0.88,this.options._orgStrokeColor);grd.addColorStop(1,this.options.shadowColor);return grd;};Donut.prototype.setOptions=function(options){var h,start,stop,w;if(options==null){options=null;} -Donut.__super__.setOptions.call(this,options);w=this.canvas.width/2;h=this.canvas.height/2;start=this.radius-this.lineWidth/2;stop=this.radius+this.lineWidth/2;this.options._orgStrokeColor=this.options.strokeColor;this.options.strokeColor=this.strokeGradient(w,h,start,stop);return this;};return Donut;})(BaseDonut);window.AnimationUpdater={elements:[],animId:null,addAll:function(list){var elem,_i,_len,_results;_results=[];for(_i=0,_len=list.length;_i<_len;_i++){elem=list[_i];_results.push(AnimationUpdater.elements.push(elem));} -return _results;},add:function(object){return AnimationUpdater.elements.push(object);},run:function(){var animationFinished,elem,_i,_len,_ref;animationFinished=true;_ref=AnimationUpdater.elements;for(_i=0,_len=_ref.length;_i<_len;_i++){elem=_ref[_i];if(elem.update()){animationFinished=false;}} -if(!animationFinished){return AnimationUpdater.animId=requestAnimationFrame(AnimationUpdater.run);}else{return cancelAnimationFrame(AnimationUpdater.animId);}}};window.Gauge=Gauge;window.Donut=Donut;window.BaseDonut=BaseDonut;window.TextRenderer=TextRenderer;}).call(this); \ No newline at end of file diff --git a/frontend/express/public/javascripts/visualization/jquery.peity.min.js b/frontend/express/public/javascripts/visualization/jquery.peity.min.js deleted file mode 100644 index 6476a4ac8d7..00000000000 --- a/frontend/express/public/javascripts/visualization/jquery.peity.min.js +++ /dev/null @@ -1,283 +0,0 @@ -// Peity jQuery plugin version 0.6.0 -// (c) 2011 Ben Pickles -// -// http://benpickles.github.com/peity/ -// -// Released under MIT license. -(function ($, document) { - var peity = $.fn.peity = function (type, options) { - if (document.createElement("canvas").getContext) { - this.each(function () { - $(this).change(function () { - var opts = $.extend({}, options) - var self = this - - $.each(opts, function (name, value) { - if ($.isFunction(value)) - opts[name] = value.call(self) - }) - - var value = $(this).html(); - peity.graphers[type].call(this, $.extend({}, peity.defaults[type], opts)); - $(this).trigger("chart:changed", value); - - }).trigger("change"); - }); - } - - return this; - }; - - peity.graphers = {}; - peity.defaults = {}; - - peity.add = function (type, defaults, grapher) { - peity.graphers[type] = grapher; - peity.defaults[type] = defaults; - }; - - var devicePixelRatio = window.devicePixelRatio || 1 - - function createCanvas(width, height) { - var canvas = document.createElement("canvas") - canvas.setAttribute("width", width * devicePixelRatio) - canvas.setAttribute("height", height * devicePixelRatio) - - if (devicePixelRatio != 4) { - var style = "width:" + width + "px;height:" + height + "px" - canvas.setAttribute("style", style) - } - - return canvas - } - - peity.add( - 'pie', - { - colours : ['#FFF4DD', '#FF9900'], - delimeter : '/', - diameter : 16 - }, - function (opts) { - var $this = $(this), - values = $this.text().split(opts.delimeter), - v1 = parseFloat(values[0]), - v2 = parseFloat(values[1]), - adjust = -Math.PI / 2, - slice = (v1 / v2) * Math.PI * 2; - - var canvas = createCanvas(opts.diameter, opts.diameter) - var context = canvas.getContext("2d"); - var centre = canvas.width / 2; - - // Plate. - context.beginPath(); - context.moveTo(centre, centre); - context.arc(centre, centre, centre, slice + adjust, (slice == 0) ? Math.PI * 2 : adjust, false); - context.fillStyle = opts.colours[0]; - context.fill(); - - // Slice of pie. - context.beginPath(); - context.moveTo(centre, centre); - context.arc(centre, centre, centre, adjust, slice + adjust, false); - context.fillStyle = opts.colours[1]; - context.fill(); - - $this.wrapInner($("").hide()).append(canvas) - }); - - peity.add( - "line", - { - colour : "#c6d9fd", - strokeColour : "#4d89f9", - strokeWidth : 1, - delimeter : ",", - height : 16, - max : null, - min : 0, - width : $(this).parent().outerWidth() - (($(this).parent().outerWidth()) * 0.1), - useMinAsBase : false, - opaqueGradient : false - }, - function (opts) { - opts.width = $(this).parent().outerWidth() - (($(this).parent().outerWidth()) * 0.1) - - var $this = $(this) - var canvas = createCanvas(opts.width, opts.height) - var values = $this.text().split(opts.delimeter) - - if (values.length == 1) - values.push(values[0]) - - var max = Math.max.apply(Math, values.concat([opts.max])); - var min = Math.min.apply(Math, values.concat([opts.min])) - - var context = canvas.getContext("2d"); - var gradient = canvas.getContext("2d").createLinearGradient(0, 0, 0, 30); - var width = canvas.width - var height = canvas.height - var xQuotient = width / (values.length - 1) - var yQuotient = height / (max - min) - - var coords = []; - var i; - - context.beginPath(); - context.moveTo(0, height + (min * yQuotient)) - - var valueBase = 0; - - if (opts.useMinAsBase) { - valueBase = (values.length) ? values[0] : 0; - - for (i = 0; i < values.length; i++) { - if (values[i] < valueBase) { - valueBase = values[i]; - } - } - } - - for (i = 0; i < values.length; i++) { - var x = i * xQuotient - var y = height - (yQuotient * (values[i] - min - valueBase)) - - coords.push({ - x : x, - y : y - }); - context.lineTo(x, y); - } - - context.lineTo(width, height + (min * yQuotient)) - - if (opts.opaqueGradient) { - - function hexToRgb(hexColor) { - hexColor = hexColor.replace(/^\s*#|\s*$/g, ''); - - if (hexColor.length == 3) { - hexColor = hexColor.replace(/(.)/g, '$1$1'); - } - - r = parseInt(hexColor.substr(0, 2), 16); - g = parseInt(hexColor.substr(2, 2), 16); - b = parseInt(hexColor.substr(4, 2), 16); - - return { - r : r, - g : g, - b : b - }; - } - - var rgbColor = hexToRgb(opts.colour); - - gradient.addColorStop(0.3, 'rgba(' + rgbColor.r + ', ' + rgbColor.g + ', ' + rgbColor.b + ', 0.4)'); - gradient.addColorStop(0.7, 'rgba(' + rgbColor.r + ', ' + rgbColor.g + ', ' + rgbColor.b + ', 0.2)'); - gradient.addColorStop(1, 'rgba(' + rgbColor.r + ', ' + rgbColor.g + ', ' + rgbColor.b + ', 0)'); - } else { - context.globalAlpha = 0.3; - gradient.addColorStop(1, opts.colour); - } - - context.fillStyle = gradient; - context.fill(); - - context.globalAlpha = 1; - - if (opts.strokeWidth) { - context.beginPath(); - context.moveTo(0, coords[0].y); - - for (i = 0; i < coords.length; i++) { - context.lineTo(coords[i].x, coords[i].y); - } - - context.lineWidth = opts.strokeWidth * devicePixelRatio; - context.strokeStyle = opts.strokeColour; - context.stroke(); - } - - $this.wrapInner($("").hide()).append(canvas) - }); - - peity.add( - 'bar', - { - colour : "#4D89F9", - delimeter : ",", - height : 16, - max : null, - min : 0, - width : 120,//$(this).parent().outerWidth() - (($(this).parent().outerWidth()) * 0.2), - maxBars : 16, - padding : 10, - borderBottom : 1 - }, - function (opts) { - opts.width = 120//$(this).parent().outerWidth() - (($(this).parent().outerWidth()) * 0.2) - opts.height = 25; - - var $this = $(this) - var values = $this.text().split(opts.delimeter) - - if (values.length > opts.maxBars) { - var reduceEach = Math.ceil(values.length / opts.maxBars), - reduceCount = 0, - reduceIndex = 0, - newValues = [], - reduceTotal = 0; - - for (var i = 0; i < values.length; i++) { - reduceTotal += parseInt(values[i]); - reduceCount++; - - if (reduceCount % reduceEach == 0) { - newValues[reduceIndex] = reduceTotal / reduceEach; - reduceIndex++; - - reduceTotal = 0; - } - } - - if (reduceCount != values.length) { - for (var i = reduceCount; i < values.length; i++) { - reduceTotal += values[i]; - } - - newValues[reduceIndex] = reduceTotal / reduceEach; - } - - values = newValues; - } - - var max = Math.max.apply(Math, values.concat([opts.max])); - var min = Math.min.apply(Math, values.concat([opts.min])) - - var canvas = createCanvas(opts.width, opts.height) - var context = canvas.getContext("2d"); - - var width = canvas.width - opts.padding - var height = canvas.height - var yQuotient = height / (max - min) - var space = 2 //devicePixelRatio / 2 - var xQuotient = (width + space) / values.length - - context.fillStyle = opts.colour; - - for (var i = 0; i < values.length; i++) { - var x = (i * xQuotient) + Math.floor(opts.padding / 2) - var y = height - (yQuotient * (values[i] - min)) - opts.borderBottom - - context.fillRect(x, y, xQuotient - space, yQuotient * values[i]) - } - - if (opts.borderBottom) { - context.fillRect(0 + (opts.padding / 2), (height - opts.borderBottom), width, opts.borderBottom); - } - - $this.wrapInner($("").hide()).append(canvas) - }); -})(jQuery, document); \ No newline at end of file diff --git a/frontend/express/public/javascripts/visualization/jquery.sparkline.js b/frontend/express/public/javascripts/visualization/jquery.sparkline.js deleted file mode 100644 index 721e03b76b9..00000000000 --- a/frontend/express/public/javascripts/visualization/jquery.sparkline.js +++ /dev/null @@ -1,3054 +0,0 @@ -/** -* -* jquery.sparkline.js -* -* v2.1.2 -* (c) Splunk, Inc -* Contact: Gareth Watts (gareth@splunk.com) -* http://omnipotent.net/jquery.sparkline/ -* -* Generates inline sparkline charts from data supplied either to the method -* or inline in HTML -* -* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag -* (Firefox 2.0+, Safari, Opera, etc) -* -* License: New BSD License -* -* Copyright (c) 2012, Splunk Inc. -* All rights reserved. -* -* 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. -* * Neither the name of Splunk Inc nor the names of its contributors may -* be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. -* -* -* Usage: -* $(selector).sparkline(values, options) -* -* If values is undefined or set to 'html' then the data values are read from the specified tag: -*

      Sparkline: 1,4,6,6,8,5,3,5

      -* $('.sparkline').sparkline(); -* There must be no spaces in the enclosed data set -* -* Otherwise values must be an array of numbers or null values -*

      Sparkline: This text replaced if the browser is compatible

      -* $('#sparkline1').sparkline([1,4,6,6,8,5,3,5]) -* $('#sparkline2').sparkline([1,4,6,null,null,5,3,5]) -* -* Values can also be specified in an HTML comment, or as a values attribute: -*

      Sparkline:

      -*

      Sparkline:

      -* $('.sparkline').sparkline(); -* -* For line charts, x values can also be specified: -*

      Sparkline: 1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5

      -* $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ]) -* -* By default, options should be passed in as teh second argument to the sparkline function: -* $('.sparkline').sparkline([1,2,3,4], {type: 'bar'}) -* -* Options can also be set by passing them on the tag itself. This feature is disabled by default though -* as there's a slight performance overhead: -* $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true}) -*

      Sparkline: loading

      -* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionPrefix) -* -* Supported options: -* lineColor - Color of the line used for the chart -* fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart -* width - Width of the chart - Defaults to 3 times the number of values in pixels -* height - Height of the chart - Defaults to the height of the containing element -* chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied -* chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied -* chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax -* chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied -* chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied -* composite - If true then don't erase any existing chart attached to the tag, but draw -* another chart over the top - Note that width and height are ignored if an -* existing chart is detected. -* tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values' -* enableTagOptions - Whether to check tags for sparkline options -* tagOptionPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark' -* disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a -* hidden dom element, avoding a browser reflow -* disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled, -* making the plugin perform much like it did in 1.x -* disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled) -* disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled -* defaults to false (highlights enabled) -* highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase -* tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body -* tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied -* tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis -* tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis -* tooltipFormatter - Optional callback that allows you to override the HTML displayed in the tooltip -* callback is given arguments of (sparkline, options, fields) -* tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title -* tooltipFormat - A format string or SPFormat object (or an array thereof for multiple entries) -* to control the format of the tooltip -* tooltipPrefix - A string to prepend to each field displayed in a tooltip -* tooltipSuffix - A string to append to each field displayed in a tooltip -* tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true) -* tooltipValueLookups - An object or range map to map field values to tooltip strings -* (eg. to map -1 to "Lost", 0 to "Draw", and 1 to "Win") -* numberFormatter - Optional callback for formatting numbers in tooltips -* numberDigitGroupSep - Character to use for group separator in numbers "1,234" - Defaults to "," -* numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to "." -* numberDigitGroupCount - Number of digits between group separator - Defaults to 3 -* -* There are 7 types of sparkline, selected by supplying a "type" option of 'line' (default), -* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box' -* line - Line chart. Options: -* spotColor - Set to '' to not end each line in a circular spot -* minSpotColor - If set, color of spot at minimum value -* maxSpotColor - If set, color of spot at maximum value -* spotRadius - Radius in pixels -* lineWidth - Width of line in pixels -* normalRangeMin -* normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal" -* or expected range of values -* normalRangeColor - Color to use for the above bar -* drawNormalOnTop - Draw the normal range above the chart fill color if true -* defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart -* highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable -* highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable -* valueSpots - Specify which points to draw spots on, and in which color. Accepts a range map -* -* bar - Bar chart. Options: -* barColor - Color of bars for postive values -* negBarColor - Color of bars for negative values -* zeroColor - Color of bars with zero values -* nullColor - Color of bars with null values - Defaults to omitting the bar entirely -* barWidth - Width of bars in pixels -* colorMap - Optional mappnig of values to colors to override the *BarColor values above -* can be an Array of values to control the color of individual bars or a range map -* to specify colors for individual ranges of values -* barSpacing - Gap between bars in pixels -* zeroAxis - Centers the y-axis around zero if true -* -* tristate - Charts values of win (>0), lose (<0) or draw (=0) -* posBarColor - Color of win values -* negBarColor - Color of lose values -* zeroBarColor - Color of draw values -* barWidth - Width of bars in pixels -* barSpacing - Gap between bars in pixels -* colorMap - Optional mappnig of values to colors to override the *BarColor values above -* can be an Array of values to control the color of individual bars or a range map -* to specify colors for individual ranges of values -* -* discrete - Options: -* lineHeight - Height of each line in pixels - Defaults to 30% of the graph height -* thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor -* thresholdColor -* -* bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ... -* options: -* targetColor - The color of the vertical target marker -* targetWidth - The width of the target marker in pixels -* performanceColor - The color of the performance measure horizontal bar -* rangeColors - Colors to use for each qualitative range background color -* -* pie - Pie chart. Options: -* sliceColors - An array of colors to use for pie slices -* offset - Angle in degrees to offset the first slice - Try -90 or +90 -* borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border) -* borderColor - Color to use for the pie chart border - Defaults to #000 -* -* box - Box plot. Options: -* raw - Set to true to supply pre-computed plot points as values -* values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier -* When set to false you can supply any number of values and the box plot will -* be computed for you. Default is false. -* showOutliers - Set to true (default) to display outliers as circles -* outlierIQR - Interquartile range used to determine outliers. Default 1.5 -* boxLineColor - Outline color of the box -* boxFillColor - Fill color for the box -* whiskerColor - Line color used for whiskers -* outlierLineColor - Outline color of outlier circles -* outlierFillColor - Fill color of the outlier circles -* spotRadius - Radius of outlier circles -* medianColor - Line color of the median line -* target - Draw a target cross hair at the supplied value (default undefined) -* -* -* -* Examples: -* $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false }); -* $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 }); -* $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }): -* $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' }); -* $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' }); -* $('#pie').sparkline([1,1,2], { type:'pie' }); -*/ - -/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */ - -(function(document, Math, undefined) { // performance/minified-size optimization -(function(factory) { - if(typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } else if (jQuery && !jQuery.fn.sparkline) { - factory(jQuery); - } -} -(function($) { - 'use strict'; - - var UNSET_OPTION = {}, - getDefaults, createClass, SPFormat, clipval, quartile, normalizeValue, normalizeValues, - remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap, - MouseHandler, Tooltip, barHighlightMixin, - line, bar, tristate, discrete, bullet, pie, box, defaultStyles, initStyles, - VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0; - - /** - * Default configuration settings - */ - getDefaults = function () { - return { - // Settings common to most/all chart types - common: { - type: 'line', - lineColor: '#00f', - fillColor: '#cdf', - defaultPixelsPerValue: 3, - width: 'auto', - height: 'auto', - composite: false, - tagValuesAttribute: 'values', - tagOptionsPrefix: 'spark', - enableTagOptions: false, - enableHighlight: true, - highlightLighten: 1.4, - tooltipSkipNull: true, - tooltipPrefix: '', - tooltipSuffix: '', - disableHiddenCheck: false, - numberFormatter: false, - numberDigitGroupCount: 3, - numberDigitGroupSep: ',', - numberDecimalMark: '.', - disableTooltips: false, - disableInteraction: false - }, - // Defaults for line charts - line: { - spotColor: '#f80', - highlightSpotColor: '#5f5', - highlightLineColor: '#f22', - spotRadius: 1.5, - minSpotColor: '#f80', - maxSpotColor: '#f80', - lineWidth: 1, - normalRangeMin: undefined, - normalRangeMax: undefined, - normalRangeColor: '#ccc', - drawNormalOnTop: false, - chartRangeMin: undefined, - chartRangeMax: undefined, - chartRangeMinX: undefined, - chartRangeMaxX: undefined, - tooltipFormat: new SPFormat(' {{prefix}}{{y}}{{suffix}}') - }, - // Defaults for bar charts - bar: { - barColor: '#3366cc', - negBarColor: '#f44', - stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', - '#dd4477', '#0099c6', '#990099'], - zeroColor: undefined, - nullColor: undefined, - zeroAxis: true, - barWidth: 4, - barSpacing: 1, - chartRangeMax: undefined, - chartRangeMin: undefined, - chartRangeClip: false, - colorMap: undefined, - tooltipFormat: new SPFormat(' {{prefix}}{{value}}{{suffix}}') - }, - // Defaults for tristate charts - tristate: { - barWidth: 4, - barSpacing: 1, - posBarColor: '#6f6', - negBarColor: '#f44', - zeroBarColor: '#999', - colorMap: {}, - tooltipFormat: new SPFormat(' {{value:map}}'), - tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } } - }, - // Defaults for discrete charts - discrete: { - lineHeight: 'auto', - thresholdColor: undefined, - thresholdValue: 0, - chartRangeMax: undefined, - chartRangeMin: undefined, - chartRangeClip: false, - tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}') - }, - // Defaults for bullet charts - bullet: { - targetColor: '#f33', - targetWidth: 3, // width of the target bar in pixels - performanceColor: '#33f', - rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'], - base: undefined, // set this to a number to change the base start number - tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'), - tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} } - }, - // Defaults for pie charts - pie: { - offset: 0, - sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', - '#dd4477', '#0099c6', '#990099'], - borderWidth: 0, - borderColor: '#000', - tooltipFormat: new SPFormat(' {{value}} ({{percent.1}}%)') - }, - // Defaults for box plots - box: { - raw: false, - boxLineColor: '#000', - boxFillColor: '#cdf', - whiskerColor: '#000', - outlierLineColor: '#333', - outlierFillColor: '#fff', - medianColor: '#f00', - showOutliers: true, - outlierIQR: 1.5, - spotRadius: 1.5, - target: undefined, - targetColor: '#4a2', - chartRangeMax: undefined, - chartRangeMin: undefined, - tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'), - tooltipFormatFieldlistKey: 'field', - tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median', - uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier', - lw: 'Left Whisker', rw: 'Right Whisker'} } - } - }; - }; - - // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname - defaultStyles = '.jqstooltip { ' + - 'position: absolute;' + - 'left: 0px;' + - 'top: 0px;' + - 'visibility: hidden;' + - 'background: rgb(0, 0, 0) transparent;' + - 'background-color: rgba(0,0,0,0.6);' + - 'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' + - '-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";' + - 'color: white;' + - 'font: 10px arial, san serif;' + - 'text-align: left;' + - 'white-space: nowrap;' + - 'padding: 5px;' + - 'border: 1px solid white;' + - 'z-index: 10000;' + - '}' + - '.jqsfield { ' + - 'color: white;' + - 'font: 10px arial, san serif;' + - 'text-align: left;' + - '}'; - - /** - * Utilities - */ - - createClass = function (/* [baseclass, [mixin, ...]], definition */) { - var Class, args; - Class = function () { - this.init.apply(this, arguments); - }; - if (arguments.length > 1) { - if (arguments[0]) { - Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]); - Class._super = arguments[0].prototype; - } else { - Class.prototype = arguments[arguments.length - 1]; - } - if (arguments.length > 2) { - args = Array.prototype.slice.call(arguments, 1, -1); - args.unshift(Class.prototype); - $.extend.apply($, args); - } - } else { - Class.prototype = arguments[0]; - } - Class.prototype.cls = Class; - return Class; - }; - - /** - * Wraps a format string for tooltips - * {{x}} - * {{x.2} - * {{x:months}} - */ - $.SPFormatClass = SPFormat = createClass({ - fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g, - precre: /(\w+)\.(\d+)/, - - init: function (format, fclass) { - this.format = format; - this.fclass = fclass; - }, - - render: function (fieldset, lookups, options) { - var self = this, - fields = fieldset, - match, token, lookupkey, fieldvalue, prec; - return this.format.replace(this.fre, function () { - var lookup; - token = arguments[1]; - lookupkey = arguments[3]; - match = self.precre.exec(token); - if (match) { - prec = match[2]; - token = match[1]; - } else { - prec = false; - } - fieldvalue = fields[token]; - if (fieldvalue === undefined) { - return ''; - } - if (lookupkey && lookups && lookups[lookupkey]) { - lookup = lookups[lookupkey]; - if (lookup.get) { // RangeMap - return lookups[lookupkey].get(fieldvalue) || fieldvalue; - } else { - return lookups[lookupkey][fieldvalue] || fieldvalue; - } - } - if (isNumber(fieldvalue)) { - if (options.get('numberFormatter')) { - fieldvalue = options.get('numberFormatter')(fieldvalue); - } else { - fieldvalue = formatNumber(fieldvalue, prec, - options.get('numberDigitGroupCount'), - options.get('numberDigitGroupSep'), - options.get('numberDecimalMark')); - } - } - return fieldvalue; - }); - } - }); - - // convience method to avoid needing the new operator - $.spformat = function(format, fclass) { - return new SPFormat(format, fclass); - }; - - clipval = function (val, min, max) { - if (val < min) { - return min; - } - if (val > max) { - return max; - } - return val; - }; - - quartile = function (values, q) { - var vl; - if (q === 2) { - vl = Math.floor(values.length / 2); - return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2; - } else { - if (values.length % 2 ) { // odd - vl = (values.length * q + q) / 4; - return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1]; - } else { //even - vl = (values.length * q + 2) / 4; - return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1]; - - } - } - }; - - normalizeValue = function (val) { - var nf; - switch (val) { - case 'undefined': - val = undefined; - break; - case 'null': - val = null; - break; - case 'true': - val = true; - break; - case 'false': - val = false; - break; - default: - nf = parseFloat(val); - if (val == nf) { - val = nf; - } - } - return val; - }; - - normalizeValues = function (vals) { - var i, result = []; - for (i = vals.length; i--;) { - result[i] = normalizeValue(vals[i]); - } - return result; - }; - - remove = function (vals, filter) { - var i, vl, result = []; - for (i = 0, vl = vals.length; i < vl; i++) { - if (vals[i] !== filter) { - result.push(vals[i]); - } - } - return result; - }; - - isNumber = function (num) { - return !isNaN(parseFloat(num)) && isFinite(num); - }; - - formatNumber = function (num, prec, groupsize, groupsep, decsep) { - var p, i; - num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split(''); - p = (p = $.inArray('.', num)) < 0 ? num.length : p; - if (p < num.length) { - num[p] = decsep; - } - for (i = p - groupsize; i > 0; i -= groupsize) { - num.splice(i, 0, groupsep); - } - return num.join(''); - }; - - // determine if all values of an array match a value - // returns true if the array is empty - all = function (val, arr, ignoreNull) { - var i; - for (i = arr.length; i--; ) { - if (ignoreNull && arr[i] === null) continue; - if (arr[i] !== val) { - return false; - } - } - return true; - }; - - // sums the numeric values in an array, ignoring other values - sum = function (vals) { - var total = 0, i; - for (i = vals.length; i--;) { - total += typeof vals[i] === 'number' ? vals[i] : 0; - } - return total; - }; - - ensureArray = function (val) { - return $.isArray(val) ? val : [val]; - }; - - // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/ - addCSS = function(css) { - var tag; - //if ('\v' == 'v') /* ie only */ { - if (document.createStyleSheet) { - document.createStyleSheet().cssText = css; - } else { - tag = document.createElement('style'); - tag.type = 'text/css'; - document.getElementsByTagName('head')[0].appendChild(tag); - tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css; - } - }; - - // Provide a cross-browser interface to a few simple drawing primitives - $.fn.simpledraw = function (width, height, useExisting, interact) { - var target, mhandler; - if (useExisting && (target = this.data('_jqs_vcanvas'))) { - return target; - } - - if ($.fn.sparkline.canvas === false) { - // We've already determined that neither Canvas nor VML are available - return false; - - } else if ($.fn.sparkline.canvas === undefined) { - // No function defined yet -- need to see if we support Canvas or VML - var el = document.createElement('canvas'); - if (!!(el.getContext && el.getContext('2d'))) { - // Canvas is available - $.fn.sparkline.canvas = function(width, height, target, interact) { - return new VCanvas_canvas(width, height, target, interact); - }; - } else if (document.namespaces && !document.namespaces.v) { - // VML is available - document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML'); - $.fn.sparkline.canvas = function(width, height, target, interact) { - return new VCanvas_vml(width, height, target); - }; - } else { - // Neither Canvas nor VML are available - $.fn.sparkline.canvas = false; - return false; - } - } - - if (width === undefined) { - width = $(this).innerWidth(); - } - if (height === undefined) { - height = $(this).innerHeight(); - } - - target = $.fn.sparkline.canvas(width, height, this, interact); - - mhandler = $(this).data('_jqs_mhandler'); - if (mhandler) { - mhandler.registerCanvas(target); - } - return target; - }; - - $.fn.cleardraw = function () { - var target = this.data('_jqs_vcanvas'); - if (target) { - target.reset(); - } - }; - - $.RangeMapClass = RangeMap = createClass({ - init: function (map) { - var key, range, rangelist = []; - for (key in map) { - if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) { - range = key.split(':'); - range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]); - range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]); - range[2] = map[key]; - rangelist.push(range); - } - } - this.map = map; - this.rangelist = rangelist || false; - }, - - get: function (value) { - var rangelist = this.rangelist, - i, range, result; - if ((result = this.map[value]) !== undefined) { - return result; - } - if (rangelist) { - for (i = rangelist.length; i--;) { - range = rangelist[i]; - if (range[0] <= value && range[1] >= value) { - return range[2]; - } - } - } - return undefined; - } - }); - - // Convenience function - $.range_map = function(map) { - return new RangeMap(map); - }; - - MouseHandler = createClass({ - init: function (el, options) { - var $el = $(el); - this.$el = $el; - this.options = options; - this.currentPageX = 0; - this.currentPageY = 0; - this.el = el; - this.splist = []; - this.tooltip = null; - this.over = false; - this.displayTooltips = !options.get('disableTooltips'); - this.highlightEnabled = !options.get('disableHighlight'); - }, - - registerSparkline: function (sp) { - this.splist.push(sp); - if (this.over) { - this.updateDisplay(); - } - }, - - registerCanvas: function (canvas) { - var $canvas = $(canvas.canvas); - this.canvas = canvas; - this.$canvas = $canvas; - $canvas.mouseenter($.proxy(this.mouseenter, this)); - $canvas.mouseleave($.proxy(this.mouseleave, this)); - $canvas.click($.proxy(this.mouseclick, this)); - }, - - reset: function (removeTooltip) { - this.splist = []; - if (this.tooltip && removeTooltip) { - this.tooltip.remove(); - this.tooltip = undefined; - } - }, - - mouseclick: function (e) { - var clickEvent = $.Event('sparklineClick'); - clickEvent.originalEvent = e; - clickEvent.sparklines = this.splist; - this.$el.trigger(clickEvent); - }, - - mouseenter: function (e) { - $(document.body).unbind('mousemove.jqs'); - $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this)); - this.over = true; - this.currentPageX = e.pageX; - this.currentPageY = e.pageY; - this.currentEl = e.target; - if (!this.tooltip && this.displayTooltips) { - this.tooltip = new Tooltip(this.options); - this.tooltip.updatePosition(e.pageX, e.pageY); - } - this.updateDisplay(); - }, - - mouseleave: function () { - $(document.body).unbind('mousemove.jqs'); - var splist = this.splist, - spcount = splist.length, - needsRefresh = false, - sp, i; - this.over = false; - this.currentEl = null; - - if (this.tooltip) { - this.tooltip.remove(); - this.tooltip = null; - } - - for (i = 0; i < spcount; i++) { - sp = splist[i]; - if (sp.clearRegionHighlight()) { - needsRefresh = true; - } - } - - if (needsRefresh) { - this.canvas.render(); - } - }, - - mousemove: function (e) { - this.currentPageX = e.pageX; - this.currentPageY = e.pageY; - this.currentEl = e.target; - if (this.tooltip) { - this.tooltip.updatePosition(e.pageX, e.pageY); - } - this.updateDisplay(); - }, - - updateDisplay: function () { - var splist = this.splist, - spcount = splist.length, - needsRefresh = false, - offset = this.$canvas.offset(), - localX = this.currentPageX - offset.left, - localY = this.currentPageY - offset.top, - tooltiphtml, sp, i, result, changeEvent; - if (!this.over) { - return; - } - for (i = 0; i < spcount; i++) { - sp = splist[i]; - result = sp.setRegionHighlight(this.currentEl, localX, localY); - if (result) { - needsRefresh = true; - } - } - if (needsRefresh) { - changeEvent = $.Event('sparklineRegionChange'); - changeEvent.sparklines = this.splist; - this.$el.trigger(changeEvent); - if (this.tooltip) { - tooltiphtml = ''; - for (i = 0; i < spcount; i++) { - sp = splist[i]; - tooltiphtml += sp.getCurrentRegionTooltip(); - } - this.tooltip.setContent(tooltiphtml); - } - if (!this.disableHighlight) { - this.canvas.render(); - } - } - if (result === null) { - this.mouseleave(); - } - } - }); - - - Tooltip = createClass({ - sizeStyle: 'position: static !important;' + - 'display: block !important;' + - 'visibility: hidden !important;' + - 'float: left !important;', - - init: function (options) { - var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'), - sizetipStyle = this.sizeStyle, - offset; - this.container = options.get('tooltipContainer') || document.body; - this.tooltipOffsetX = options.get('tooltipOffsetX', 10); - this.tooltipOffsetY = options.get('tooltipOffsetY', 12); - // remove any previous lingering tooltip - $('#jqssizetip').remove(); - $('#jqstooltip').remove(); - this.sizetip = $('
      ', { - id: 'jqssizetip', - style: sizetipStyle, - 'class': tooltipClassname - }); - this.tooltip = $('
      ', { - id: 'jqstooltip', - 'class': tooltipClassname - }).appendTo(this.container); - // account for the container's location - offset = this.tooltip.offset(); - this.offsetLeft = offset.left; - this.offsetTop = offset.top; - this.hidden = true; - $(window).unbind('resize.jqs scroll.jqs'); - $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this)); - this.updateWindowDims(); - }, - - updateWindowDims: function () { - this.scrollTop = $(window).scrollTop(); - this.scrollLeft = $(window).scrollLeft(); - this.scrollRight = this.scrollLeft + $(window).width(); - this.updatePosition(); - }, - - getSize: function (content) { - this.sizetip.html(content).appendTo(this.container); - this.width = this.sizetip.width() + 1; - this.height = this.sizetip.height(); - this.sizetip.remove(); - }, - - setContent: function (content) { - if (!content) { - this.tooltip.css('visibility', 'hidden'); - this.hidden = true; - return; - } - this.getSize(content); - this.tooltip.html(content) - .css({ - 'width': this.width, - 'height': this.height, - 'visibility': 'visible' - }); - if (this.hidden) { - this.hidden = false; - this.updatePosition(); - } - }, - - updatePosition: function (x, y) { - if (x === undefined) { - if (this.mousex === undefined) { - return; - } - x = this.mousex - this.offsetLeft; - y = this.mousey - this.offsetTop; - - } else { - this.mousex = x = x - this.offsetLeft; - this.mousey = y = y - this.offsetTop; - } - if (!this.height || !this.width || this.hidden) { - return; - } - - y -= this.height + this.tooltipOffsetY; - x += this.tooltipOffsetX; - - if (y < this.scrollTop) { - y = this.scrollTop; - } - if (x < this.scrollLeft) { - x = this.scrollLeft; - } else if (x + this.width > this.scrollRight) { - x = this.scrollRight - this.width; - } - - this.tooltip.css({ - 'left': x, - 'top': y - }); - }, - - remove: function () { - this.tooltip.remove(); - this.sizetip.remove(); - this.sizetip = this.tooltip = undefined; - $(window).unbind('resize.jqs scroll.jqs'); - } - }); - - initStyles = function() { - addCSS(defaultStyles); - }; - - $(initStyles); - - pending = []; - $.fn.sparkline = function (userValues, userOptions) { - return this.each(function () { - var options = new $.fn.sparkline.options(this, userOptions), - $this = $(this), - render, i; - render = function () { - var values, width, height, tmp, mhandler, sp, vals; - if (userValues === 'html' || userValues === undefined) { - vals = this.getAttribute(options.get('tagValuesAttribute')); - if (vals === undefined || vals === null) { - vals = $this.html(); - } - values = vals.replace(/(^\s*\s*$)|\s+/g, '').split(','); - } else { - values = userValues; - } - - width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width'); - if (options.get('height') === 'auto') { - if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) { - // must be a better way to get the line height - tmp = document.createElement('span'); - tmp.innerHTML = 'a'; - $this.html(tmp); - height = $(tmp).innerHeight() || $(tmp).height(); - $(tmp).remove(); - tmp = null; - } - } else { - height = options.get('height'); - } - - if (!options.get('disableInteraction')) { - mhandler = $.data(this, '_jqs_mhandler'); - if (!mhandler) { - mhandler = new MouseHandler(this, options); - $.data(this, '_jqs_mhandler', mhandler); - } else if (!options.get('composite')) { - mhandler.reset(); - } - } else { - mhandler = false; - } - - if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) { - if (!$.data(this, '_jqs_errnotify')) { - alert('Attempted to attach a composite sparkline to an element with no existing sparkline'); - $.data(this, '_jqs_errnotify', true); - } - return; - } - - sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height); - - sp.render(); - - if (mhandler) { - mhandler.registerSparkline(sp); - } - }; - if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || !$(this).parents('body').length) { - if (!options.get('composite') && $.data(this, '_jqs_pending')) { - // remove any existing references to the element - for (i = pending.length; i; i--) { - if (pending[i - 1][0] == this) { - pending.splice(i - 1, 1); - } - } - } - pending.push([this, render]); - $.data(this, '_jqs_pending', true); - } else { - render.call(this); - } - }); - }; - - $.fn.sparkline.defaults = getDefaults(); - - - $.sparkline_display_visible = function () { - var el, i, pl; - var done = []; - for (i = 0, pl = pending.length; i < pl; i++) { - el = pending[i][0]; - if ($(el).is(':visible') && !$(el).parents().is(':hidden')) { - pending[i][1].call(el); - $.data(pending[i][0], '_jqs_pending', false); - done.push(i); - } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) { - // element has been inserted and removed from the DOM - // If it was not yet inserted into the dom then the .data request - // will return true. - // removing from the dom causes the data to be removed. - $.data(pending[i][0], '_jqs_pending', false); - done.push(i); - } - } - for (i = done.length; i; i--) { - pending.splice(done[i - 1], 1); - } - }; - - - /** - * User option handler - */ - $.fn.sparkline.options = createClass({ - init: function (tag, userOptions) { - var extendedOptions, defaults, base, tagOptionType; - this.userOptions = userOptions = userOptions || {}; - this.tag = tag; - this.tagValCache = {}; - defaults = $.fn.sparkline.defaults; - base = defaults.common; - this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix); - - tagOptionType = this.getTagSetting('type'); - if (tagOptionType === UNSET_OPTION) { - extendedOptions = defaults[userOptions.type || base.type]; - } else { - extendedOptions = defaults[tagOptionType]; - } - this.mergedOptions = $.extend({}, base, extendedOptions, userOptions); - }, - - - getTagSetting: function (key) { - var prefix = this.tagOptionsPrefix, - val, i, pairs, keyval; - if (prefix === false || prefix === undefined) { - return UNSET_OPTION; - } - if (this.tagValCache.hasOwnProperty(key)) { - val = this.tagValCache.key; - } else { - val = this.tag.getAttribute(prefix + key); - if (val === undefined || val === null) { - val = UNSET_OPTION; - } else if (val.substr(0, 1) === '[') { - val = val.substr(1, val.length - 2).split(','); - for (i = val.length; i--;) { - val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, '')); - } - } else if (val.substr(0, 1) === '{') { - pairs = val.substr(1, val.length - 2).split(','); - val = {}; - for (i = pairs.length; i--;) { - keyval = pairs[i].split(':', 2); - val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, '')); - } - } else { - val = normalizeValue(val); - } - this.tagValCache.key = val; - } - return val; - }, - - get: function (key, defaultval) { - var tagOption = this.getTagSetting(key), - result; - if (tagOption !== UNSET_OPTION) { - return tagOption; - } - return (result = this.mergedOptions[key]) === undefined ? defaultval : result; - } - }); - - - $.fn.sparkline._base = createClass({ - disabled: false, - - init: function (el, values, options, width, height) { - this.el = el; - this.$el = $(el); - this.values = values; - this.options = options; - this.width = width; - this.height = height; - this.currentRegion = undefined; - }, - - /** - * Setup the canvas - */ - initTarget: function () { - var interactive = !this.options.get('disableInteraction'); - if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) { - this.disabled = true; - } else { - this.canvasWidth = this.target.pixelWidth; - this.canvasHeight = this.target.pixelHeight; - } - }, - - /** - * Actually render the chart to the canvas - */ - render: function () { - if (this.disabled) { - this.el.innerHTML = ''; - return false; - } - return true; - }, - - /** - * Return a region id for a given x/y co-ordinate - */ - getRegion: function (x, y) { - }, - - /** - * Highlight an item based on the moused-over x,y co-ordinate - */ - setRegionHighlight: function (el, x, y) { - var currentRegion = this.currentRegion, - highlightEnabled = !this.options.get('disableHighlight'), - newRegion; - if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) { - return null; - } - newRegion = this.getRegion(el, x, y); - if (currentRegion !== newRegion) { - if (currentRegion !== undefined && highlightEnabled) { - this.removeHighlight(); - } - this.currentRegion = newRegion; - if (newRegion !== undefined && highlightEnabled) { - this.renderHighlight(); - } - return true; - } - return false; - }, - - /** - * Reset any currently highlighted item - */ - clearRegionHighlight: function () { - if (this.currentRegion !== undefined) { - this.removeHighlight(); - this.currentRegion = undefined; - return true; - } - return false; - }, - - renderHighlight: function () { - this.changeHighlight(true); - }, - - removeHighlight: function () { - this.changeHighlight(false); - }, - - changeHighlight: function (highlight) {}, - - /** - * Fetch the HTML to display as a tooltip - */ - getCurrentRegionTooltip: function () { - var options = this.options, - header = '', - entries = [], - fields, formats, formatlen, fclass, text, i, - showFields, showFieldsKey, newFields, fv, - formatter, format, fieldlen, j; - if (this.currentRegion === undefined) { - return ''; - } - fields = this.getCurrentRegionFields(); - formatter = options.get('tooltipFormatter'); - if (formatter) { - return formatter(this, options, fields); - } - if (options.get('tooltipChartTitle')) { - header += '
      ' + options.get('tooltipChartTitle') + '
      \n'; - } - formats = this.options.get('tooltipFormat'); - if (!formats) { - return ''; - } - if (!$.isArray(formats)) { - formats = [formats]; - } - if (!$.isArray(fields)) { - fields = [fields]; - } - showFields = this.options.get('tooltipFormatFieldlist'); - showFieldsKey = this.options.get('tooltipFormatFieldlistKey'); - if (showFields && showFieldsKey) { - // user-selected ordering of fields - newFields = []; - for (i = fields.length; i--;) { - fv = fields[i][showFieldsKey]; - if ((j = $.inArray(fv, showFields)) != -1) { - newFields[j] = fields[i]; - } - } - fields = newFields; - } - formatlen = formats.length; - fieldlen = fields.length; - for (i = 0; i < formatlen; i++) { - format = formats[i]; - if (typeof format === 'string') { - format = new SPFormat(format); - } - fclass = format.fclass || 'jqsfield'; - for (j = 0; j < fieldlen; j++) { - if (!fields[j].isNull || !options.get('tooltipSkipNull')) { - $.extend(fields[j], { - prefix: options.get('tooltipPrefix'), - suffix: options.get('tooltipSuffix') - }); - text = format.render(fields[j], options.get('tooltipValueLookups'), options); - entries.push('
      ' + text + '
      '); - } - } - } - if (entries.length) { - return header + entries.join('\n'); - } - return ''; - }, - - getCurrentRegionFields: function () {}, - - calcHighlightColor: function (color, options) { - var highlightColor = options.get('highlightColor'), - lighten = options.get('highlightLighten'), - parse, mult, rgbnew, i; - if (highlightColor) { - return highlightColor; - } - if (lighten) { - // extract RGB values - parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color); - if (parse) { - rgbnew = []; - mult = color.length === 4 ? 16 : 1; - for (i = 0; i < 3; i++) { - rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255); - } - return 'rgb(' + rgbnew.join(',') + ')'; - } - - } - return color; - } - - }); - - barHighlightMixin = { - changeHighlight: function (highlight) { - var currentRegion = this.currentRegion, - target = this.target, - shapeids = this.regionShapes[currentRegion], - newShapes; - // will be null if the region value was null - if (shapeids) { - newShapes = this.renderRegion(currentRegion, highlight); - if ($.isArray(newShapes) || $.isArray(shapeids)) { - target.replaceWithShapes(shapeids, newShapes); - this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) { - return newShape.id; - }); - } else { - target.replaceWithShape(shapeids, newShapes); - this.regionShapes[currentRegion] = newShapes.id; - } - } - }, - - render: function () { - var values = this.values, - target = this.target, - regionShapes = this.regionShapes, - shapes, ids, i, j; - - if (!this.cls._super.render.call(this)) { - return; - } - for (i = values.length; i--;) { - shapes = this.renderRegion(i); - if (shapes) { - if ($.isArray(shapes)) { - ids = []; - for (j = shapes.length; j--;) { - shapes[j].append(); - ids.push(shapes[j].id); - } - regionShapes[i] = ids; - } else { - shapes.append(); - regionShapes[i] = shapes.id; // store just the shapeid - } - } else { - // null value - regionShapes[i] = null; - } - } - target.render(); - } - }; - - /** - * Line charts - */ - $.fn.sparkline.line = line = createClass($.fn.sparkline._base, { - type: 'line', - - init: function (el, values, options, width, height) { - line._super.init.call(this, el, values, options, width, height); - this.vertices = []; - this.regionMap = []; - this.xvalues = []; - this.yvalues = []; - this.yminmax = []; - this.hightlightSpotId = null; - this.lastShapeId = null; - this.initTarget(); - }, - - getRegion: function (el, x, y) { - var i, - regionMap = this.regionMap; // maps regions to value positions - for (i = regionMap.length; i--;) { - if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) { - return regionMap[i][2]; - } - } - return undefined; - }, - - getCurrentRegionFields: function () { - var currentRegion = this.currentRegion; - return { - isNull: this.yvalues[currentRegion] === null, - x: this.xvalues[currentRegion], - y: this.yvalues[currentRegion], - color: this.options.get('lineColor'), - fillColor: this.options.get('fillColor'), - offset: currentRegion - }; - }, - - renderHighlight: function () { - var currentRegion = this.currentRegion, - target = this.target, - vertex = this.vertices[currentRegion], - options = this.options, - spotRadius = options.get('spotRadius'), - highlightSpotColor = options.get('highlightSpotColor'), - highlightLineColor = options.get('highlightLineColor'), - highlightSpot, highlightLine; - - if (!vertex) { - return; - } - if (spotRadius && highlightSpotColor) { - highlightSpot = target.drawCircle(vertex[0], vertex[1], - spotRadius, undefined, highlightSpotColor); - this.highlightSpotId = highlightSpot.id; - target.insertAfterShape(this.lastShapeId, highlightSpot); - } - if (highlightLineColor) { - highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0], - this.canvasTop + this.canvasHeight, highlightLineColor); - this.highlightLineId = highlightLine.id; - target.insertAfterShape(this.lastShapeId, highlightLine); - } - }, - - removeHighlight: function () { - var target = this.target; - if (this.highlightSpotId) { - target.removeShapeId(this.highlightSpotId); - this.highlightSpotId = null; - } - if (this.highlightLineId) { - target.removeShapeId(this.highlightLineId); - this.highlightLineId = null; - } - }, - - scanValues: function () { - var values = this.values, - valcount = values.length, - xvalues = this.xvalues, - yvalues = this.yvalues, - yminmax = this.yminmax, - i, val, isStr, isArray, sp; - for (i = 0; i < valcount; i++) { - val = values[i]; - isStr = typeof(values[i]) === 'string'; - isArray = typeof(values[i]) === 'object' && values[i] instanceof Array; - sp = isStr && values[i].split(':'); - if (isStr && sp.length === 2) { // x:y - xvalues.push(Number(sp[0])); - yvalues.push(Number(sp[1])); - yminmax.push(Number(sp[1])); - } else if (isArray) { - xvalues.push(val[0]); - yvalues.push(val[1]); - yminmax.push(val[1]); - } else { - xvalues.push(i); - if (values[i] === null || values[i] === 'null') { - yvalues.push(null); - } else { - yvalues.push(Number(val)); - yminmax.push(Number(val)); - } - } - } - if (this.options.get('xvalues')) { - xvalues = this.options.get('xvalues'); - } - - this.maxy = this.maxyorg = Math.max.apply(Math, yminmax); - this.miny = this.minyorg = Math.min.apply(Math, yminmax); - - this.maxx = Math.max.apply(Math, xvalues); - this.minx = Math.min.apply(Math, xvalues); - - this.xvalues = xvalues; - this.yvalues = yvalues; - this.yminmax = yminmax; - - }, - - processRangeOptions: function () { - var options = this.options, - normalRangeMin = options.get('normalRangeMin'), - normalRangeMax = options.get('normalRangeMax'); - - if (normalRangeMin !== undefined) { - if (normalRangeMin < this.miny) { - this.miny = normalRangeMin; - } - if (normalRangeMax > this.maxy) { - this.maxy = normalRangeMax; - } - } - if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) { - this.miny = options.get('chartRangeMin'); - } - if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) { - this.maxy = options.get('chartRangeMax'); - } - if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) { - this.minx = options.get('chartRangeMinX'); - } - if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) { - this.maxx = options.get('chartRangeMaxX'); - } - - }, - - drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) { - var normalRangeMin = this.options.get('normalRangeMin'), - normalRangeMax = this.options.get('normalRangeMax'), - ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))), - height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey); - this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append(); - }, - - render: function () { - var options = this.options, - target = this.target, - canvasWidth = this.canvasWidth, - canvasHeight = this.canvasHeight, - vertices = this.vertices, - spotRadius = options.get('spotRadius'), - regionMap = this.regionMap, - rangex, rangey, yvallast, - canvasTop, canvasLeft, - vertex, path, paths, x, y, xnext, xpos, xposnext, - last, next, yvalcount, lineShapes, fillShapes, plen, - valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i; - - if (!line._super.render.call(this)) { - return; - } - - this.scanValues(); - this.processRangeOptions(); - - xvalues = this.xvalues; - yvalues = this.yvalues; - - if (!this.yminmax.length || this.yvalues.length < 2) { - // empty or all null valuess - return; - } - - canvasTop = canvasLeft = 0; - - rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx; - rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny; - yvallast = this.yvalues.length - 1; - - if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) { - spotRadius = 0; - } - if (spotRadius) { - // adjust the canvas size as required so that spots will fit - hlSpotsEnabled = options.get('highlightSpotColor') && !options.get('disableInteraction'); - if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) { - canvasHeight -= Math.ceil(spotRadius); - } - if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) { - canvasHeight -= Math.ceil(spotRadius); - canvasTop += Math.ceil(spotRadius); - } - if (hlSpotsEnabled || - ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) { - canvasLeft += Math.ceil(spotRadius); - canvasWidth -= Math.ceil(spotRadius); - } - if (hlSpotsEnabled || options.get('spotColor') || - (options.get('minSpotColor') || options.get('maxSpotColor') && - (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) { - canvasWidth -= Math.ceil(spotRadius); - } - } - - - canvasHeight--; - - if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) { - this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey); - } - - path = []; - paths = [path]; - last = next = null; - yvalcount = yvalues.length; - for (i = 0; i < yvalcount; i++) { - x = xvalues[i]; - xnext = xvalues[i + 1]; - y = yvalues[i]; - xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)); - xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth; - next = xpos + ((xposnext - xpos) / 2); - regionMap[i] = [last || 0, next, i]; - last = next; - if (y === null) { - if (i) { - if (yvalues[i - 1] !== null) { - path = []; - paths.push(path); - } - vertices.push(null); - } - } else { - if (y < this.miny) { - y = this.miny; - } - if (y > this.maxy) { - y = this.maxy; - } - if (!path.length) { - // previous value was null - path.push([xpos, canvasTop + canvasHeight]); - } - vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))]; - path.push(vertex); - vertices.push(vertex); - } - } - - lineShapes = []; - fillShapes = []; - plen = paths.length; - for (i = 0; i < plen; i++) { - path = paths[i]; - if (path.length) { - if (options.get('fillColor')) { - path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]); - fillShapes.push(path.slice(0)); - path.pop(); - } - // if there's only a single point in this path, then we want to display it - // as a vertical line which means we keep path[0] as is - if (path.length > 2) { - // else we want the first value - path[0] = [path[0][0], path[1][1]]; - } - lineShapes.push(path); - } - } - - // draw the fill first, then optionally the normal range, then the line on top of that - plen = fillShapes.length; - for (i = 0; i < plen; i++) { - target.drawShape(fillShapes[i], - options.get('fillColor'), options.get('fillColor')).append(); - } - - if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) { - this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey); - } - - plen = lineShapes.length; - for (i = 0; i < plen; i++) { - target.drawShape(lineShapes[i], options.get('lineColor'), undefined, - options.get('lineWidth')).append(); - } - - if (spotRadius && options.get('valueSpots')) { - valueSpots = options.get('valueSpots'); - if (valueSpots.get === undefined) { - valueSpots = new RangeMap(valueSpots); - } - for (i = 0; i < yvalcount; i++) { - color = valueSpots.get(yvalues[i]); - if (color) { - target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)), - canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))), - spotRadius, undefined, - color).append(); - } - } - - } - if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) { - target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)), - canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))), - spotRadius, undefined, - options.get('spotColor')).append(); - } - if (this.maxy !== this.minyorg) { - if (spotRadius && options.get('minSpotColor')) { - x = xvalues[$.inArray(this.minyorg, yvalues)]; - target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)), - canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))), - spotRadius, undefined, - options.get('minSpotColor')).append(); - } - if (spotRadius && options.get('maxSpotColor')) { - x = xvalues[$.inArray(this.maxyorg, yvalues)]; - target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)), - canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))), - spotRadius, undefined, - options.get('maxSpotColor')).append(); - } - } - - this.lastShapeId = target.getLastShapeId(); - this.canvasTop = canvasTop; - target.render(); - } - }); - - /** - * Bar charts - */ - $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, { - type: 'bar', - - init: function (el, values, options, width, height) { - var barWidth = parseInt(options.get('barWidth'), 10), - barSpacing = parseInt(options.get('barSpacing'), 10), - chartRangeMin = options.get('chartRangeMin'), - chartRangeMax = options.get('chartRangeMax'), - chartRangeClip = options.get('chartRangeClip'), - stackMin = Infinity, - stackMax = -Infinity, - isStackString, groupMin, groupMax, stackRanges, - numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax, - stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf; - bar._super.init.call(this, el, values, options, width, height); - - // scan values to determine whether to stack bars - for (i = 0, vlen = values.length; i < vlen; i++) { - val = values[i]; - isStackString = typeof(val) === 'string' && val.indexOf(':') > -1; - if (isStackString || $.isArray(val)) { - stacked = true; - if (isStackString) { - val = values[i] = normalizeValues(val.split(':')); - } - val = remove(val, null); // min/max will treat null as zero - groupMin = Math.min.apply(Math, val); - groupMax = Math.max.apply(Math, val); - if (groupMin < stackMin) { - stackMin = groupMin; - } - if (groupMax > stackMax) { - stackMax = groupMax; - } - } - } - - this.stacked = stacked; - this.regionShapes = {}; - this.barWidth = barWidth; - this.barSpacing = barSpacing; - this.totalBarWidth = barWidth + barSpacing; - this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing); - - this.initTarget(); - - if (chartRangeClip) { - clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin; - clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax; - } - - numValues = []; - stackRanges = stacked ? [] : numValues; - var stackTotals = []; - var stackRangesNeg = []; - for (i = 0, vlen = values.length; i < vlen; i++) { - if (stacked) { - vlist = values[i]; - values[i] = svals = []; - stackTotals[i] = 0; - stackRanges[i] = stackRangesNeg[i] = 0; - for (j = 0, slen = vlist.length; j < slen; j++) { - val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j]; - if (val !== null) { - if (val > 0) { - stackTotals[i] += val; - } - if (stackMin < 0 && stackMax > 0) { - if (val < 0) { - stackRangesNeg[i] += Math.abs(val); - } else { - stackRanges[i] += val; - } - } else { - stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin)); - } - numValues.push(val); - } - } - } else { - val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i]; - val = values[i] = normalizeValue(val); - if (val !== null) { - numValues.push(val); - } - } - } - this.max = max = Math.max.apply(Math, numValues); - this.min = min = Math.min.apply(Math, numValues); - this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max; - this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min; - - if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) { - min = options.get('chartRangeMin'); - } - if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) { - max = options.get('chartRangeMax'); - } - - this.zeroAxis = zeroAxis = options.get('zeroAxis', true); - if (min <= 0 && max >= 0 && zeroAxis) { - xaxisOffset = 0; - } else if (zeroAxis == false) { - xaxisOffset = min; - } else if (min > 0) { - xaxisOffset = min; - } else { - xaxisOffset = max; - } - this.xaxisOffset = xaxisOffset; - - range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min; - - // as we plot zero/min values a single pixel line, we add a pixel to all other - // values - Reduce the effective canvas size to suit - this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1; - - if (min < xaxisOffset) { - yMaxCalc = (stacked && max >= 0) ? stackMax : max; - yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight; - if (yoffset !== Math.ceil(yoffset)) { - this.canvasHeightEf -= 2; - yoffset = Math.ceil(yoffset); - } - } else { - yoffset = this.canvasHeight; - } - this.yoffset = yoffset; - - if ($.isArray(options.get('colorMap'))) { - this.colorMapByIndex = options.get('colorMap'); - this.colorMapByValue = null; - } else { - this.colorMapByIndex = null; - this.colorMapByValue = options.get('colorMap'); - if (this.colorMapByValue && this.colorMapByValue.get === undefined) { - this.colorMapByValue = new RangeMap(this.colorMapByValue); - } - } - - this.range = range; - }, - - getRegion: function (el, x, y) { - var result = Math.floor(x / this.totalBarWidth); - return (result < 0 || result >= this.values.length) ? undefined : result; - }, - - getCurrentRegionFields: function () { - var currentRegion = this.currentRegion, - values = ensureArray(this.values[currentRegion]), - result = [], - value, i; - for (i = values.length; i--;) { - value = values[i]; - result.push({ - isNull: value === null, - value: value, - color: this.calcColor(i, value, currentRegion), - offset: currentRegion - }); - } - return result; - }, - - calcColor: function (stacknum, value, valuenum) { - var colorMapByIndex = this.colorMapByIndex, - colorMapByValue = this.colorMapByValue, - options = this.options, - color, newColor; - if (this.stacked) { - color = options.get('stackedBarColor'); - } else { - color = (value < 0) ? options.get('negBarColor') : options.get('barColor'); - } - if (value === 0 && options.get('zeroColor') !== undefined) { - color = options.get('zeroColor'); - } - if (colorMapByValue && (newColor = colorMapByValue.get(value))) { - color = newColor; - } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { - color = colorMapByIndex[valuenum]; - } - return $.isArray(color) ? color[stacknum % color.length] : color; - }, - - /** - * Render bar(s) for a region - */ - renderRegion: function (valuenum, highlight) { - var vals = this.values[valuenum], - options = this.options, - xaxisOffset = this.xaxisOffset, - result = [], - range = this.range, - stacked = this.stacked, - target = this.target, - x = valuenum * this.totalBarWidth, - canvasHeightEf = this.canvasHeightEf, - yoffset = this.yoffset, - y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin; - - vals = $.isArray(vals) ? vals : [vals]; - valcount = vals.length; - val = vals[0]; - isNull = all(null, vals); - allMin = all(xaxisOffset, vals, true); - - if (isNull) { - if (options.get('nullColor')) { - color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options); - y = (yoffset > 0) ? yoffset - 1 : yoffset; - return target.drawRect(x, y, this.barWidth - 1, 0, color, color); - } else { - return undefined; - } - } - yoffsetNeg = yoffset; - for (i = 0; i < valcount; i++) { - val = vals[i]; - - if (stacked && val === xaxisOffset) { - if (!allMin || minPlotted) { - continue; - } - minPlotted = true; - } - - if (range > 0) { - height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1; - } else { - height = 1; - } - if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) { - y = yoffsetNeg; - yoffsetNeg += height; - } else { - y = yoffset - height; - yoffset -= height; - } - color = this.calcColor(i, val, valuenum); - if (highlight) { - color = this.calcHighlightColor(color, options); - } - result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color)); - } - if (result.length === 1) { - return result[0]; - } - return result; - } - }); - - /** - * Tristate charts - */ - $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, { - type: 'tristate', - - init: function (el, values, options, width, height) { - var barWidth = parseInt(options.get('barWidth'), 10), - barSpacing = parseInt(options.get('barSpacing'), 10); - tristate._super.init.call(this, el, values, options, width, height); - - this.regionShapes = {}; - this.barWidth = barWidth; - this.barSpacing = barSpacing; - this.totalBarWidth = barWidth + barSpacing; - this.values = $.map(values, Number); - this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing); - - if ($.isArray(options.get('colorMap'))) { - this.colorMapByIndex = options.get('colorMap'); - this.colorMapByValue = null; - } else { - this.colorMapByIndex = null; - this.colorMapByValue = options.get('colorMap'); - if (this.colorMapByValue && this.colorMapByValue.get === undefined) { - this.colorMapByValue = new RangeMap(this.colorMapByValue); - } - } - this.initTarget(); - }, - - getRegion: function (el, x, y) { - return Math.floor(x / this.totalBarWidth); - }, - - getCurrentRegionFields: function () { - var currentRegion = this.currentRegion; - return { - isNull: this.values[currentRegion] === undefined, - value: this.values[currentRegion], - color: this.calcColor(this.values[currentRegion], currentRegion), - offset: currentRegion - }; - }, - - calcColor: function (value, valuenum) { - var values = this.values, - options = this.options, - colorMapByIndex = this.colorMapByIndex, - colorMapByValue = this.colorMapByValue, - color, newColor; - - if (colorMapByValue && (newColor = colorMapByValue.get(value))) { - color = newColor; - } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { - color = colorMapByIndex[valuenum]; - } else if (values[valuenum] < 0) { - color = options.get('negBarColor'); - } else if (values[valuenum] > 0) { - color = options.get('posBarColor'); - } else { - color = options.get('zeroBarColor'); - } - return color; - }, - - renderRegion: function (valuenum, highlight) { - var values = this.values, - options = this.options, - target = this.target, - canvasHeight, height, halfHeight, - x, y, color; - - canvasHeight = target.pixelHeight; - halfHeight = Math.round(canvasHeight / 2); - - x = valuenum * this.totalBarWidth; - if (values[valuenum] < 0) { - y = halfHeight; - height = halfHeight - 1; - } else if (values[valuenum] > 0) { - y = 0; - height = halfHeight - 1; - } else { - y = halfHeight - 1; - height = 2; - } - color = this.calcColor(values[valuenum], valuenum); - if (color === null) { - return; - } - if (highlight) { - color = this.calcHighlightColor(color, options); - } - return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color); - } - }); - - /** - * Discrete charts - */ - $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, { - type: 'discrete', - - init: function (el, values, options, width, height) { - discrete._super.init.call(this, el, values, options, width, height); - - this.regionShapes = {}; - this.values = values = $.map(values, Number); - this.min = Math.min.apply(Math, values); - this.max = Math.max.apply(Math, values); - this.range = this.max - this.min; - this.width = width = options.get('width') === 'auto' ? values.length * 2 : this.width; - this.interval = Math.floor(width / values.length); - this.itemWidth = width / values.length; - if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) { - this.min = options.get('chartRangeMin'); - } - if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) { - this.max = options.get('chartRangeMax'); - } - this.initTarget(); - if (this.target) { - this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight'); - } - }, - - getRegion: function (el, x, y) { - return Math.floor(x / this.itemWidth); - }, - - getCurrentRegionFields: function () { - var currentRegion = this.currentRegion; - return { - isNull: this.values[currentRegion] === undefined, - value: this.values[currentRegion], - offset: currentRegion - }; - }, - - renderRegion: function (valuenum, highlight) { - var values = this.values, - options = this.options, - min = this.min, - max = this.max, - range = this.range, - interval = this.interval, - target = this.target, - canvasHeight = this.canvasHeight, - lineHeight = this.lineHeight, - pheight = canvasHeight - lineHeight, - ytop, val, color, x; - - val = clipval(values[valuenum], min, max); - x = valuenum * interval; - ytop = Math.round(pheight - pheight * ((val - min) / range)); - color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor'); - if (highlight) { - color = this.calcHighlightColor(color, options); - } - return target.drawLine(x, ytop, x, ytop + lineHeight, color); - } - }); - - /** - * Bullet charts - */ - $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, { - type: 'bullet', - - init: function (el, values, options, width, height) { - var min, max, vals; - bullet._super.init.call(this, el, values, options, width, height); - - // values: target, performance, range1, range2, range3 - this.values = values = normalizeValues(values); - // target or performance could be null - vals = values.slice(); - vals[0] = vals[0] === null ? vals[2] : vals[0]; - vals[1] = values[1] === null ? vals[2] : vals[1]; - min = Math.min.apply(Math, values); - max = Math.max.apply(Math, values); - if (options.get('base') === undefined) { - min = min < 0 ? min : 0; - } else { - min = options.get('base'); - } - this.min = min; - this.max = max; - this.range = max - min; - this.shapes = {}; - this.valueShapes = {}; - this.regiondata = {}; - this.width = width = options.get('width') === 'auto' ? '4.0em' : width; - this.target = this.$el.simpledraw(width, height, options.get('composite')); - if (!values.length) { - this.disabled = true; - } - this.initTarget(); - }, - - getRegion: function (el, x, y) { - var shapeid = this.target.getShapeAt(el, x, y); - return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; - }, - - getCurrentRegionFields: function () { - var currentRegion = this.currentRegion; - return { - fieldkey: currentRegion.substr(0, 1), - value: this.values[currentRegion.substr(1)], - region: currentRegion - }; - }, - - changeHighlight: function (highlight) { - var currentRegion = this.currentRegion, - shapeid = this.valueShapes[currentRegion], - shape; - delete this.shapes[shapeid]; - switch (currentRegion.substr(0, 1)) { - case 'r': - shape = this.renderRange(currentRegion.substr(1), highlight); - break; - case 'p': - shape = this.renderPerformance(highlight); - break; - case 't': - shape = this.renderTarget(highlight); - break; - } - this.valueShapes[currentRegion] = shape.id; - this.shapes[shape.id] = currentRegion; - this.target.replaceWithShape(shapeid, shape); - }, - - renderRange: function (rn, highlight) { - var rangeval = this.values[rn], - rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)), - color = this.options.get('rangeColors')[rn - 2]; - if (highlight) { - color = this.calcHighlightColor(color, this.options); - } - return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color); - }, - - renderPerformance: function (highlight) { - var perfval = this.values[1], - perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)), - color = this.options.get('performanceColor'); - if (highlight) { - color = this.calcHighlightColor(color, this.options); - } - return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1, - Math.round(this.canvasHeight * 0.4) - 1, color, color); - }, - - renderTarget: function (highlight) { - var targetval = this.values[0], - x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)), - targettop = Math.round(this.canvasHeight * 0.10), - targetheight = this.canvasHeight - (targettop * 2), - color = this.options.get('targetColor'); - if (highlight) { - color = this.calcHighlightColor(color, this.options); - } - return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color); - }, - - render: function () { - var vlen = this.values.length, - target = this.target, - i, shape; - if (!bullet._super.render.call(this)) { - return; - } - for (i = 2; i < vlen; i++) { - shape = this.renderRange(i).append(); - this.shapes[shape.id] = 'r' + i; - this.valueShapes['r' + i] = shape.id; - } - if (this.values[1] !== null) { - shape = this.renderPerformance().append(); - this.shapes[shape.id] = 'p1'; - this.valueShapes.p1 = shape.id; - } - if (this.values[0] !== null) { - shape = this.renderTarget().append(); - this.shapes[shape.id] = 't0'; - this.valueShapes.t0 = shape.id; - } - target.render(); - } - }); - - /** - * Pie charts - */ - $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, { - type: 'pie', - - init: function (el, values, options, width, height) { - var total = 0, i; - - pie._super.init.call(this, el, values, options, width, height); - - this.shapes = {}; // map shape ids to value offsets - this.valueShapes = {}; // maps value offsets to shape ids - this.values = values = $.map(values, Number); - - if (options.get('width') === 'auto') { - this.width = this.height; - } - - if (values.length > 0) { - for (i = values.length; i--;) { - total += values[i]; - } - } - this.total = total; - this.initTarget(); - this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2); - }, - - getRegion: function (el, x, y) { - var shapeid = this.target.getShapeAt(el, x, y); - return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; - }, - - getCurrentRegionFields: function () { - var currentRegion = this.currentRegion; - return { - isNull: this.values[currentRegion] === undefined, - value: this.values[currentRegion], - percent: this.values[currentRegion] / this.total * 100, - color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length], - offset: currentRegion - }; - }, - - changeHighlight: function (highlight) { - var currentRegion = this.currentRegion, - newslice = this.renderSlice(currentRegion, highlight), - shapeid = this.valueShapes[currentRegion]; - delete this.shapes[shapeid]; - this.target.replaceWithShape(shapeid, newslice); - this.valueShapes[currentRegion] = newslice.id; - this.shapes[newslice.id] = currentRegion; - }, - - renderSlice: function (valuenum, highlight) { - var target = this.target, - options = this.options, - radius = this.radius, - borderWidth = options.get('borderWidth'), - offset = options.get('offset'), - circle = 2 * Math.PI, - values = this.values, - total = this.total, - next = offset ? (2*Math.PI)*(offset/360) : 0, - start, end, i, vlen, color; - - vlen = values.length; - for (i = 0; i < vlen; i++) { - start = next; - end = next; - if (total > 0) { // avoid divide by zero - end = next + (circle * (values[i] / total)); - } - if (valuenum === i) { - color = options.get('sliceColors')[i % options.get('sliceColors').length]; - if (highlight) { - color = this.calcHighlightColor(color, options); - } - - return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color); - } - next = end; - } - }, - - render: function () { - var target = this.target, - values = this.values, - options = this.options, - radius = this.radius, - borderWidth = options.get('borderWidth'), - shape, i; - - if (!pie._super.render.call(this)) { - return; - } - if (borderWidth) { - target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)), - options.get('borderColor'), undefined, borderWidth).append(); - } - for (i = values.length; i--;) { - if (values[i]) { // don't render zero values - shape = this.renderSlice(i).append(); - this.valueShapes[i] = shape.id; // store just the shapeid - this.shapes[shape.id] = i; - } - } - target.render(); - } - }); - - /** - * Box plots - */ - $.fn.sparkline.box = box = createClass($.fn.sparkline._base, { - type: 'box', - - init: function (el, values, options, width, height) { - box._super.init.call(this, el, values, options, width, height); - this.values = $.map(values, Number); - this.width = options.get('width') === 'auto' ? '4.0em' : width; - this.initTarget(); - if (!this.values.length) { - this.disabled = 1; - } - }, - - /** - * Simulate a single region - */ - getRegion: function () { - return 1; - }, - - getCurrentRegionFields: function () { - var result = [ - { field: 'lq', value: this.quartiles[0] }, - { field: 'med', value: this.quartiles[1] }, - { field: 'uq', value: this.quartiles[2] } - ]; - if (this.loutlier !== undefined) { - result.push({ field: 'lo', value: this.loutlier}); - } - if (this.routlier !== undefined) { - result.push({ field: 'ro', value: this.routlier}); - } - if (this.lwhisker !== undefined) { - result.push({ field: 'lw', value: this.lwhisker}); - } - if (this.rwhisker !== undefined) { - result.push({ field: 'rw', value: this.rwhisker}); - } - return result; - }, - - render: function () { - var target = this.target, - values = this.values, - vlen = values.length, - options = this.options, - canvasWidth = this.canvasWidth, - canvasHeight = this.canvasHeight, - minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'), - maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'), - canvasLeft = 0, - lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i, - size, unitSize; - - if (!box._super.render.call(this)) { - return; - } - - if (options.get('raw')) { - if (options.get('showOutliers') && values.length > 5) { - loutlier = values[0]; - lwhisker = values[1]; - q1 = values[2]; - q2 = values[3]; - q3 = values[4]; - rwhisker = values[5]; - routlier = values[6]; - } else { - lwhisker = values[0]; - q1 = values[1]; - q2 = values[2]; - q3 = values[3]; - rwhisker = values[4]; - } - } else { - values.sort(function (a, b) { return a - b; }); - q1 = quartile(values, 1); - q2 = quartile(values, 2); - q3 = quartile(values, 3); - iqr = q3 - q1; - if (options.get('showOutliers')) { - lwhisker = rwhisker = undefined; - for (i = 0; i < vlen; i++) { - if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) { - lwhisker = values[i]; - } - if (values[i] < q3 + (iqr * options.get('outlierIQR'))) { - rwhisker = values[i]; - } - } - loutlier = values[0]; - routlier = values[vlen - 1]; - } else { - lwhisker = values[0]; - rwhisker = values[vlen - 1]; - } - } - this.quartiles = [q1, q2, q3]; - this.lwhisker = lwhisker; - this.rwhisker = rwhisker; - this.loutlier = loutlier; - this.routlier = routlier; - - unitSize = canvasWidth / (maxValue - minValue + 1); - if (options.get('showOutliers')) { - canvasLeft = Math.ceil(options.get('spotRadius')); - canvasWidth -= 2 * Math.ceil(options.get('spotRadius')); - unitSize = canvasWidth / (maxValue - minValue + 1); - if (loutlier < lwhisker) { - target.drawCircle((loutlier - minValue) * unitSize + canvasLeft, - canvasHeight / 2, - options.get('spotRadius'), - options.get('outlierLineColor'), - options.get('outlierFillColor')).append(); - } - if (routlier > rwhisker) { - target.drawCircle((routlier - minValue) * unitSize + canvasLeft, - canvasHeight / 2, - options.get('spotRadius'), - options.get('outlierLineColor'), - options.get('outlierFillColor')).append(); - } - } - - // box - target.drawRect( - Math.round((q1 - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight * 0.1), - Math.round((q3 - q1) * unitSize), - Math.round(canvasHeight * 0.8), - options.get('boxLineColor'), - options.get('boxFillColor')).append(); - // left whisker - target.drawLine( - Math.round((lwhisker - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight / 2), - Math.round((q1 - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight / 2), - options.get('lineColor')).append(); - target.drawLine( - Math.round((lwhisker - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight / 4), - Math.round((lwhisker - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight - canvasHeight / 4), - options.get('whiskerColor')).append(); - // right whisker - target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight / 2), - Math.round((q3 - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight / 2), - options.get('lineColor')).append(); - target.drawLine( - Math.round((rwhisker - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight / 4), - Math.round((rwhisker - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight - canvasHeight / 4), - options.get('whiskerColor')).append(); - // median line - target.drawLine( - Math.round((q2 - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight * 0.1), - Math.round((q2 - minValue) * unitSize + canvasLeft), - Math.round(canvasHeight * 0.9), - options.get('medianColor')).append(); - if (options.get('target')) { - size = Math.ceil(options.get('spotRadius')); - target.drawLine( - Math.round((options.get('target') - minValue) * unitSize + canvasLeft), - Math.round((canvasHeight / 2) - size), - Math.round((options.get('target') - minValue) * unitSize + canvasLeft), - Math.round((canvasHeight / 2) + size), - options.get('targetColor')).append(); - target.drawLine( - Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size), - Math.round(canvasHeight / 2), - Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size), - Math.round(canvasHeight / 2), - options.get('targetColor')).append(); - } - target.render(); - } - }); - - // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier - // This is accessible as $(foo).simpledraw() - - VShape = createClass({ - init: function (target, id, type, args) { - this.target = target; - this.id = id; - this.type = type; - this.args = args; - }, - append: function () { - this.target.appendShape(this); - return this; - } - }); - - VCanvas_base = createClass({ - _pxregex: /(\d+)(px)?\s*$/i, - - init: function (width, height, target) { - if (!width) { - return; - } - this.width = width; - this.height = height; - this.target = target; - this.lastShapeId = null; - if (target[0]) { - target = target[0]; - } - $.data(target, '_jqs_vcanvas', this); - }, - - drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) { - return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth); - }, - - drawShape: function (path, lineColor, fillColor, lineWidth) { - return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]); - }, - - drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) { - return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]); - }, - - drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) { - return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]); - }, - - drawRect: function (x, y, width, height, lineColor, fillColor) { - return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]); - }, - - getElement: function () { - return this.canvas; - }, - - /** - * Return the most recently inserted shape id - */ - getLastShapeId: function () { - return this.lastShapeId; - }, - - /** - * Clear and reset the canvas - */ - reset: function () { - alert('reset not implemented'); - }, - - _insert: function (el, target) { - $(target).html(el); - }, - - /** - * Calculate the pixel dimensions of the canvas - */ - _calculatePixelDims: function (width, height, canvas) { - // XXX This should probably be a configurable option - var match; - match = this._pxregex.exec(height); - if (match) { - this.pixelHeight = match[1]; - } else { - this.pixelHeight = $(canvas).height(); - } - match = this._pxregex.exec(width); - if (match) { - this.pixelWidth = match[1]; - } else { - this.pixelWidth = $(canvas).width(); - } - }, - - /** - * Generate a shape object and id for later rendering - */ - _genShape: function (shapetype, shapeargs) { - var id = shapeCount++; - shapeargs.unshift(id); - return new VShape(this, id, shapetype, shapeargs); - }, - - /** - * Add a shape to the end of the render queue - */ - appendShape: function (shape) { - alert('appendShape not implemented'); - }, - - /** - * Replace one shape with another - */ - replaceWithShape: function (shapeid, shape) { - alert('replaceWithShape not implemented'); - }, - - /** - * Insert one shape after another in the render queue - */ - insertAfterShape: function (shapeid, shape) { - alert('insertAfterShape not implemented'); - }, - - /** - * Remove a shape from the queue - */ - removeShapeId: function (shapeid) { - alert('removeShapeId not implemented'); - }, - - /** - * Find a shape at the specified x/y co-ordinates - */ - getShapeAt: function (el, x, y) { - alert('getShapeAt not implemented'); - }, - - /** - * Render all queued shapes onto the canvas - */ - render: function () { - alert('render not implemented'); - } - }); - - VCanvas_canvas = createClass(VCanvas_base, { - init: function (width, height, target, interact) { - VCanvas_canvas._super.init.call(this, width, height, target); - this.canvas = document.createElement('canvas'); - if (target[0]) { - target = target[0]; - } - $.data(target, '_jqs_vcanvas', this); - $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' }); - this._insert(this.canvas, target); - this._calculatePixelDims(width, height, this.canvas); - this.canvas.width = this.pixelWidth; - this.canvas.height = this.pixelHeight; - this.interact = interact; - this.shapes = {}; - this.shapeseq = []; - this.currentTargetShapeId = undefined; - $(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight}); - }, - - _getContext: function (lineColor, fillColor, lineWidth) { - var context = this.canvas.getContext('2d'); - if (lineColor !== undefined) { - context.strokeStyle = lineColor; - } - context.lineWidth = lineWidth === undefined ? 1 : lineWidth; - if (fillColor !== undefined) { - context.fillStyle = fillColor; - } - return context; - }, - - reset: function () { - var context = this._getContext(); - context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); - this.shapes = {}; - this.shapeseq = []; - this.currentTargetShapeId = undefined; - }, - - _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { - var context = this._getContext(lineColor, fillColor, lineWidth), - i, plen; - context.beginPath(); - context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5); - for (i = 1, plen = path.length; i < plen; i++) { - context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines - } - if (lineColor !== undefined) { - context.stroke(); - } - if (fillColor !== undefined) { - context.fill(); - } - if (this.targetX !== undefined && this.targetY !== undefined && - context.isPointInPath(this.targetX, this.targetY)) { - this.currentTargetShapeId = shapeid; - } - }, - - _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { - var context = this._getContext(lineColor, fillColor, lineWidth); - context.beginPath(); - context.arc(x, y, radius, 0, 2 * Math.PI, false); - if (this.targetX !== undefined && this.targetY !== undefined && - context.isPointInPath(this.targetX, this.targetY)) { - this.currentTargetShapeId = shapeid; - } - if (lineColor !== undefined) { - context.stroke(); - } - if (fillColor !== undefined) { - context.fill(); - } - }, - - _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { - var context = this._getContext(lineColor, fillColor); - context.beginPath(); - context.moveTo(x, y); - context.arc(x, y, radius, startAngle, endAngle, false); - context.lineTo(x, y); - context.closePath(); - if (lineColor !== undefined) { - context.stroke(); - } - if (fillColor) { - context.fill(); - } - if (this.targetX !== undefined && this.targetY !== undefined && - context.isPointInPath(this.targetX, this.targetY)) { - this.currentTargetShapeId = shapeid; - } - }, - - _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { - return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor); - }, - - appendShape: function (shape) { - this.shapes[shape.id] = shape; - this.shapeseq.push(shape.id); - this.lastShapeId = shape.id; - return shape.id; - }, - - replaceWithShape: function (shapeid, shape) { - var shapeseq = this.shapeseq, - i; - this.shapes[shape.id] = shape; - for (i = shapeseq.length; i--;) { - if (shapeseq[i] == shapeid) { - shapeseq[i] = shape.id; - } - } - delete this.shapes[shapeid]; - }, - - replaceWithShapes: function (shapeids, shapes) { - var shapeseq = this.shapeseq, - shapemap = {}, - sid, i, first; - - for (i = shapeids.length; i--;) { - shapemap[shapeids[i]] = true; - } - for (i = shapeseq.length; i--;) { - sid = shapeseq[i]; - if (shapemap[sid]) { - shapeseq.splice(i, 1); - delete this.shapes[sid]; - first = i; - } - } - for (i = shapes.length; i--;) { - shapeseq.splice(first, 0, shapes[i].id); - this.shapes[shapes[i].id] = shapes[i]; - } - - }, - - insertAfterShape: function (shapeid, shape) { - var shapeseq = this.shapeseq, - i; - for (i = shapeseq.length; i--;) { - if (shapeseq[i] === shapeid) { - shapeseq.splice(i + 1, 0, shape.id); - this.shapes[shape.id] = shape; - return; - } - } - }, - - removeShapeId: function (shapeid) { - var shapeseq = this.shapeseq, - i; - for (i = shapeseq.length; i--;) { - if (shapeseq[i] === shapeid) { - shapeseq.splice(i, 1); - break; - } - } - delete this.shapes[shapeid]; - }, - - getShapeAt: function (el, x, y) { - this.targetX = x; - this.targetY = y; - this.render(); - return this.currentTargetShapeId; - }, - - render: function () { - var shapeseq = this.shapeseq, - shapes = this.shapes, - shapeCount = shapeseq.length, - context = this._getContext(), - shapeid, shape, i; - context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); - for (i = 0; i < shapeCount; i++) { - shapeid = shapeseq[i]; - shape = shapes[shapeid]; - this['_draw' + shape.type].apply(this, shape.args); - } - if (!this.interact) { - // not interactive so no need to keep the shapes array - this.shapes = {}; - this.shapeseq = []; - } - } - - }); - - VCanvas_vml = createClass(VCanvas_base, { - init: function (width, height, target) { - var groupel; - VCanvas_vml._super.init.call(this, width, height, target); - if (target[0]) { - target = target[0]; - } - $.data(target, '_jqs_vcanvas', this); - this.canvas = document.createElement('span'); - $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'}); - this._insert(this.canvas, target); - this._calculatePixelDims(width, height, this.canvas); - this.canvas.width = this.pixelWidth; - this.canvas.height = this.pixelHeight; - groupel = ''; - this.canvas.insertAdjacentHTML('beforeEnd', groupel); - this.group = $(this.canvas).children()[0]; - this.rendered = false; - this.prerender = ''; - }, - - _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { - var vpath = [], - initial, stroke, fill, closed, vel, plen, i; - for (i = 0, plen = path.length; i < plen; i++) { - vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]); - } - initial = vpath.splice(0, 1); - lineWidth = lineWidth === undefined ? 1 : lineWidth; - stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; - fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; - closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : ''; - vel = '' + - ' '; - return vel; - }, - - _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { - var stroke, fill, vel; - x -= radius; - y -= radius; - stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; - fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; - vel = ''; - return vel; - - }, - - _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { - var vpath, startx, starty, endx, endy, stroke, fill, vel; - if (startAngle === endAngle) { - return ''; // VML seems to have problem when start angle equals end angle. - } - if ((endAngle - startAngle) === (2 * Math.PI)) { - startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0 - endAngle = (2 * Math.PI); - } - - startx = x + Math.round(Math.cos(startAngle) * radius); - starty = y + Math.round(Math.sin(startAngle) * radius); - endx = x + Math.round(Math.cos(endAngle) * radius); - endy = y + Math.round(Math.sin(endAngle) * radius); - - if (startx === endx && starty === endy) { - if ((endAngle - startAngle) < Math.PI) { - // Prevent very small slices from being mistaken as a whole pie - return ''; - } - // essentially going to be the entire circle, so ignore startAngle - startx = endx = x + radius; - starty = endy = y; - } - - if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) { - return ''; - } - - vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy]; - stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" '; - fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; - vel = '' + - ' '; - return vel; - }, - - _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { - return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor); - }, - - reset: function () { - this.group.innerHTML = ''; - }, - - appendShape: function (shape) { - var vel = this['_draw' + shape.type].apply(this, shape.args); - if (this.rendered) { - this.group.insertAdjacentHTML('beforeEnd', vel); - } else { - this.prerender += vel; - } - this.lastShapeId = shape.id; - return shape.id; - }, - - replaceWithShape: function (shapeid, shape) { - var existing = $('#jqsshape' + shapeid), - vel = this['_draw' + shape.type].apply(this, shape.args); - existing[0].outerHTML = vel; - }, - - replaceWithShapes: function (shapeids, shapes) { - // replace the first shapeid with all the new shapes then toast the remaining old shapes - var existing = $('#jqsshape' + shapeids[0]), - replace = '', - slen = shapes.length, - i; - for (i = 0; i < slen; i++) { - replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args); - } - existing[0].outerHTML = replace; - for (i = 1; i < shapeids.length; i++) { - $('#jqsshape' + shapeids[i]).remove(); - } - }, - - insertAfterShape: function (shapeid, shape) { - var existing = $('#jqsshape' + shapeid), - vel = this['_draw' + shape.type].apply(this, shape.args); - existing[0].insertAdjacentHTML('afterEnd', vel); - }, - - removeShapeId: function (shapeid) { - var existing = $('#jqsshape' + shapeid); - this.group.removeChild(existing[0]); - }, - - getShapeAt: function (el, x, y) { - var shapeid = el.id.substr(8); - return shapeid; - }, - - render: function () { - if (!this.rendered) { - // batch the intial render into a single repaint - this.group.innerHTML = this.prerender; - this.rendered = true; - } - } - }); - -}))}(document, Math)); diff --git a/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.css b/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.css deleted file mode 100644 index 51a0d4443c4..00000000000 --- a/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.css +++ /dev/null @@ -1 +0,0 @@ -.rickshaw_graph .detail{pointer-events:none;position:absolute;top:0;z-index:2;background:rgba(0,0,0,.1);bottom:0;width:1px;transition:opacity .25s linear;-moz-transition:opacity .25s linear;-o-transition:opacity .25s linear;-webkit-transition:opacity .25s linear}.rickshaw_graph .detail.inactive{opacity:0}.rickshaw_graph .detail .item.active{opacity:1}.rickshaw_graph .detail .x_label{font-family:Arial,sans-serif;border-radius:3px;padding:6px;opacity:.5;border:1px solid #e0e0e0;font-size:12px;position:absolute;background:#fff;white-space:nowrap}.rickshaw_graph .detail .item{position:absolute;z-index:2;border-radius:3px;padding:.25em;font-size:12px;font-family:Arial,sans-serif;opacity:0;background:rgba(0,0,0,.4);color:#fff;border:1px solid rgba(0,0,0,.4);margin-left:1em;margin-top:-1em;white-space:nowrap}.rickshaw_graph .detail .item.active{opacity:1;background:rgba(0,0,0,.8)}.rickshaw_graph .detail .item:before{content:"\25c2";position:absolute;left:-.5em;color:rgba(0,0,0,.7);width:0}.rickshaw_graph .detail .dot{width:4px;height:4px;margin-left:-4px;margin-top:-3px;border-radius:5px;position:absolute;box-shadow:0 0 2px rgba(0,0,0,.6);background:#fff;border-width:2px;border-style:solid;display:none;background-clip:padding-box}.rickshaw_graph .detail .dot.active{display:block}.rickshaw_graph{position:relative}.rickshaw_graph svg{display:block;overflow:hidden}.rickshaw_graph .x_tick{position:absolute;top:0;bottom:0;width:0;border-left:1px dotted rgba(0,0,0,.2);pointer-events:none}.rickshaw_graph .x_tick .title{position:absolute;font-size:12px;font-family:Arial,sans-serif;opacity:.5;white-space:nowrap;margin-left:3px;bottom:1px}.rickshaw_annotation_timeline{height:1px;border-top:1px solid #e0e0e0;margin-top:10px;position:relative}.rickshaw_annotation_timeline .annotation{position:absolute;height:6px;width:6px;margin-left:-2px;top:-3px;border-radius:5px;background-color:rgba(0,0,0,.25)}.rickshaw_graph .annotation_line{position:absolute;top:0;bottom:-6px;width:0;border-left:2px solid rgba(0,0,0,.3);display:none}.rickshaw_graph .annotation_line.active{display:block}.rickshaw_graph .annotation_range{background:rgba(0,0,0,.1);display:none;position:absolute;top:0;bottom:-6px;z-index:-10}.rickshaw_graph .annotation_range.active{display:block}.rickshaw_graph .annotation_range.active.offscreen{display:none}.rickshaw_annotation_timeline .annotation .content{background:#fff;color:#000;opacity:.9;padding:5px 5px;box-shadow:0 0 2px rgba(0,0,0,.8);border-radius:3px;position:relative;z-index:20;font-size:12px;padding:6px 8px 8px;top:18px;left:-11px;width:160px;display:none;cursor:pointer}.rickshaw_annotation_timeline .annotation .content:before{content:"\25b2";position:absolute;top:-11px;color:#fff;text-shadow:0 -1px 1px rgba(0,0,0,.8)}.rickshaw_annotation_timeline .annotation.active,.rickshaw_annotation_timeline .annotation:hover{background-color:rgba(0,0,0,.8);cursor:none}.rickshaw_annotation_timeline .annotation .content:hover{z-index:50}.rickshaw_annotation_timeline .annotation.active .content{display:block}.rickshaw_annotation_timeline .annotation:hover .content{display:block;z-index:50}.rickshaw_graph .y_axis{fill:none}.rickshaw_graph .y_ticks .tick{stroke:rgba(0,0,0,.16);stroke-width:2px;shape-rendering:crisp-edges;pointer-events:none}.rickshaw_graph .y_grid .tick{z-index:-1;stroke:rgba(0,0,0,.20);stroke-width:1px;stroke-dasharray:1 1}.rickshaw_graph .y_grid path{fill:none;stroke:none}.rickshaw_graph .y_ticks path{fill:none;stroke:#808080}.rickshaw_graph .y_ticks text{opacity:.5;font-size:12px;pointer-events:none}.rickshaw_graph .x_tick.glow .title,.rickshaw_graph .y_ticks.glow text{fill:black;color:#000;text-shadow:-1px 1px 0 rgba(255,255,255,.1),1px -1px 0 rgba(255,255,255,.1),1px 1px 0 rgba(255,255,255,.1),0px 1px 0 rgba(255,255,255,.1),0px -1px 0 rgba(255,255,255,.1),1px 0 0 rgba(255,255,255,.1),-1px 0 0 rgba(255,255,255,.1),-1px -1px 0 rgba(255,255,255,.1)}.rickshaw_graph .x_tick.inverse .title,.rickshaw_graph .y_ticks.inverse text{fill:white;color:#fff;text-shadow:-1px 1px 0 rgba(0,0,0,.8),1px -1px 0 rgba(0,0,0,.8),1px 1px 0 rgba(0,0,0,.8),0px 1px 0 rgba(0,0,0,.8),0px -1px 0 rgba(0,0,0,.8),1px 0 0 rgba(0,0,0,.8),-1px 0 0 rgba(0,0,0,.8),-1px -1px 0 rgba(0,0,0,.8)}.rickshaw_legend{font-family:Arial;font-size:12px;color:#fff;background:#404040;display:inline-block;padding:12px 5px;border-radius:2px;position:relative}.rickshaw_legend:hover{z-index:10}.rickshaw_legend .swatch{width:10px;height:10px;border:1px solid rgba(0,0,0,.2)}.rickshaw_legend .line{clear:both;line-height:140%;padding-right:15px}.rickshaw_legend .line .swatch{display:inline-block;margin-right:3px;border-radius:2px}.rickshaw_legend .label{white-space:nowrap;display:inline}.rickshaw_legend .action:hover{opacity:.6}.rickshaw_legend .action{margin-right:.2em;font-size:10px;opacity:.2;cursor:pointer;font-size:14px}.rickshaw_legend .line.disabled{opacity:.4}.rickshaw_legend ul{list-style-type:none;margin:0;padding:0;margin:2px;cursor:pointer}.rickshaw_legend li{padding:0 0 0 2px;min-width:80px;white-space:nowrap}.rickshaw_legend li:hover{background:rgba(255,255,255,.08);border-radius:3px}.rickshaw_legend li:active{background:rgba(255,255,255,.2);border-radius:3px} \ No newline at end of file diff --git a/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js b/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js deleted file mode 100644 index 0a1dc4b5464..00000000000 --- a/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js +++ /dev/null @@ -1,2 +0,0 @@ -var Rickshaw={namespace:function(a,b){var c=a.split("."),d=Rickshaw;for(var e=1,f=c.length;ethis.window.xMax&&(b=!1),b}return!0},this.onUpdate=function(a){this.updateCallbacks.push(a)},this.registerRenderer=function(a){this._renderers=this._renderers||{},this._renderers[a.name]=a},this.configure=function(a){(a.width||a.height)&&this.setSize(a),Rickshaw.keys(this.defaults).forEach(function(b){this[b]=b in a?a[b]:b in this?this[b]:this.defaults[b]},this),this.setRenderer(a.renderer||this.renderer.name,a)},this.setRenderer=function(a,b){if(!this._renderers[a])throw"couldn't find renderer "+a;this.renderer=this._renderers[a],typeof b=="object"&&this.renderer.configure(b)},this.setSize=function(a){a=a||{};if(typeof window!==undefined)var b=window.getComputedStyle(this.element,null),c=parseInt(b.getPropertyValue("width")),d=parseInt(b.getPropertyValue("height"));this.width=a.width||c||400,this.height=a.height||d||250,this.vis&&this.vis.attr("width",this.width).attr("height",this.height)},this.initialize(a)},Rickshaw.namespace("Rickshaw.Fixtures.Color"),Rickshaw.Fixtures.Color=function(){this.schemes={},this.schemes.spectrum14=["#ecb796","#dc8f70","#b2a470","#92875a","#716c49","#d2ed82","#bbe468","#a1d05d","#e7cbe6","#d8aad6","#a888c2","#9dc2d3","#649eb9","#387aa3"].reverse(),this.schemes.spectrum2000=["#57306f","#514c76","#646583","#738394","#6b9c7d","#84b665","#a7ca50","#bfe746","#e2f528","#fff726","#ecdd00","#d4b11d","#de8800","#de4800","#c91515","#9a0000","#7b0429","#580839","#31082b"],this.schemes.spectrum2001=["#2f243f","#3c2c55","#4a3768","#565270","#6b6b7c","#72957f","#86ad6e","#a1bc5e","#b8d954","#d3e04e","#ccad2a","#cc8412","#c1521d","#ad3821","#8a1010","#681717","#531e1e","#3d1818","#320a1b"],this.schemes.classic9=["#423d4f","#4a6860","#848f39","#a2b73c","#ddcb53","#c5a32f","#7d5836","#963b20","#7c2626","#491d37","#2f254a"].reverse(),this.schemes.httpStatus={503:"#ea5029",502:"#d23f14",500:"#bf3613",410:"#efacea",409:"#e291dc",403:"#f457e8",408:"#e121d2",401:"#b92dae",405:"#f47ceb",404:"#a82a9f",400:"#b263c6",301:"#6fa024",302:"#87c32b",307:"#a0d84c",304:"#28b55c",200:"#1a4f74",206:"#27839f",201:"#52adc9",202:"#7c979f",203:"#a5b8bd",204:"#c1cdd1"},this.schemes.colorwheel=["#b5b6a9","#858772","#785f43","#96557e","#4682b4","#65b9ac","#73c03a","#cb513a"].reverse(),this.schemes.cool=["#5e9d2f","#73c03a","#4682b4","#7bc3b8","#a9884e","#c1b266","#a47493","#c09fb5"],this.schemes.munin=["#00cc00","#0066b3","#ff8000","#ffcc00","#330099","#990099","#ccff00","#ff0000","#808080","#008f00","#00487d","#b35a00","#b38f00","#6b006b","#8fb300","#b30000","#bebebe","#80ff80","#80c9ff","#ffc080","#ffe680","#aa80ff","#ee00cc","#ff8080","#666600","#ffbfff","#00ffcc","#cc6699","#999900"]},Rickshaw.namespace("Rickshaw.Fixtures.RandomData"),Rickshaw.Fixtures.RandomData=function(a){var b;a=a||1;var c=200,d=Math.floor((new Date).getTime()/1e3);this.addData=function(b){var e=Math.random()*100+15+c,f=b[0].length,g=1;b.forEach(function(b){var c=Math.random()*20,h=e/25+g++ +(Math.cos(f*g*11/960)+2)*15+(Math.cos(f/7)+2)*7+(Math.cos(f/17)+2)*1;b.push({x:f*a+d,y:h+c})}),c=e*.85}},Rickshaw.namespace("Rickshaw.Fixtures.Time"),Rickshaw.Fixtures.Time=function(){var a=(new Date).getTimezoneOffset()*60,b=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],this.units=[{name:"decade",seconds:315576e3,formatter:function(a){return parseInt(a.getUTCFullYear()/10)*10}},{name:"year",seconds:31557600,formatter:function(a){return a.getUTCFullYear()}},{name:"month",seconds:2635200,formatter:function(a){return b.months[a.getUTCMonth()]}},{name:"week",seconds:604800,formatter:function(a){return b.formatDate(a)}},{name:"day",seconds:86400,formatter:function(a){return a.getUTCDate()}},{name:"6 hour",seconds:21600,formatter:function(a){return b.formatTime(a)}},{name:"hour",seconds:3600,formatter:function(a){return b.formatTime(a)}},{name:"15 minute",seconds:900,formatter:function(a){return b.formatTime(a)}},{name:"minute",seconds:60,formatter:function(a){return a.getUTCMinutes()}},{name:"15 second",seconds:15,formatter:function(a){return a.getUTCSeconds()+"s"}},{name:"second",seconds:1,formatter:function(a){return a.getUTCSeconds()+"s"}}],this.unit=function(a){return this.units.filter(function(b){return a==b.name}).shift()},this.formatDate=function(a){return a.toUTCString().match(/, (\w+ \w+ \w+)/)[1]},this.formatTime=function(a){return a.toUTCString().match(/(\d+:\d+):/)[1]},this.ceil=function(a,b){if(b.name=="month"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(c.getUTCMonth()),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}if(b.name=="year"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(0),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}return Math.ceil(a/b.seconds)*b.seconds}},Rickshaw.namespace("Rickshaw.Fixtures.Number"),Rickshaw.Fixtures.Number.formatKMBT=function(a){return a>=1e12?a/1e12+"T":a>=1e9?a/1e9+"B":a>=1e6?a/1e6+"M":a>=1e3?a/1e3+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.Fixtures.Number.formatBase1024KMGTP=function(a){return a>=0x4000000000000?a/0x4000000000000+"P":a>=1099511627776?a/1099511627776+"T":a>=1073741824?a/1073741824+"G":a>=1048576?a/1048576+"M":a>=1024?a/1024+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.namespace("Rickshaw.Color.Palette"),Rickshaw.Color.Palette=function(a){var b=new Rickshaw.Fixtures.Color;a=a||{},this.schemes={},this.scheme=b.schemes[a.scheme]||a.scheme||b.schemes.colorwheel,this.runningIndex=0,this.generatorIndex=0;if(a.interpolatedStopCount){var c=this.scheme.length-1,d,e,f=[];for(d=0;dc.graph.x.range()[1]){b.element&&(b.line.classList.add("offscreen"),b.element.style.display="none"),b.boxes.forEach(function(a){a.rangeElement&&a.rangeElement.classList.add("offscreen")});return}if(!b.element){var e=b.element=document.createElement("div");e.classList.add("annotation"),this.elements.timeline.appendChild(e),e.addEventListener("click",function(a){e.classList.toggle("active"),b.line.classList.toggle("active"),b.boxes.forEach(function(a){a.rangeElement&&a.rangeElement.classList.toggle("active")})},!1)}b.element.style.left=d+"px",b.element.style.display="block",b.boxes.forEach(function(a){var e=a.element;e||(e=a.element=document.createElement("div"),e.classList.add("content"),e.innerHTML=a.content,b.element.appendChild(e),b.line=document.createElement("div"),b.line.classList.add("annotation_line"),c.graph.element.appendChild(b.line),a.end&&(a.rangeElement=document.createElement("div"),a.rangeElement.classList.add("annotation_range"),c.graph.element.appendChild(a.rangeElement)));if(a.end){var f=d,g=Math.min(c.graph.x(a.end),c.graph.x.range()[1]);f>g&&(g=d,f=Math.max(c.graph.x(a.end),c.graph.x.range()[0]));var h=g-f;a.rangeElement.style.left=f+"px",a.rangeElement.style.width=h+"px",a.rangeElement.classList.remove("offscreen")}b.line.classList.remove("offscreen"),b.line.style.left=d+"px"})},this)},this.graph.onUpdate(function(){c.update()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Time"),Rickshaw.Graph.Axis.Time=function(a){var b=this;this.graph=a.graph,this.elements=[],this.ticksTreatment=a.ticksTreatment||"plain",this.fixedTimeUnit=a.timeUnit;var c=new Rickshaw.Fixtures.Time;this.appropriateTimeUnit=function(){var a,b=c.units,d=this.graph.x.domain(),e=d[1]-d[0];return b.forEach(function(b){Math.floor(e/b.seconds)>=2&&(a=a||b)}),a||c.units[c.units.length-1]},this.tickOffsets=function(){var a=this.graph.x.domain(),b=this.fixedTimeUnit||this.appropriateTimeUnit(),d=Math.ceil((a[1]-a[0])/b.seconds),e=a[0],f=[];for(var g=0;gb.graph.x.range()[1])return;var c=document.createElement("div");c.style.left=b.graph.x(a.value)+"px",c.classList.add("x_tick"),c.classList.add(b.ticksTreatment);var d=document.createElement("div");d.classList.add("title"),d.innerHTML=a.unit.formatter(new Date(a.value*1e3)),c.appendChild(d),b.graph.element.appendChild(c),b.elements.push(c)})},this.graph.onUpdate(function(){b.render()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Y"),Rickshaw.Graph.Axis.Y=function(a){var b=this,c=.1;this.initialize=function(a){this.graph=a.graph,this.orientation=a.orientation||"right";var c=a.pixelsPerTick||75;this.ticks=a.ticks||Math.floor(this.graph.height/c),this.tickSize=a.tickSize||4,this.ticksTreatment=a.ticksTreatment||"plain",a.element?(this.element=a.element,this.vis=d3.select(a.element).append("svg:svg").attr("class","rickshaw_graph y_axis"),this.element=this.vis[0][0],this.element.style.position="relative",this.setSize({width:a.width,height:a.height})):this.vis=this.graph.vis,this.graph.onUpdate(function(){b.render()})},this.setSize=function(a){a=a||{};if(!this.element)return;if(typeof window!="undefined"){var b=window.getComputedStyle(this.element.parentNode,null),d=parseInt(b.getPropertyValue("width"));if(!a.auto)var e=parseInt(b.getPropertyValue("height"))}this.width=a.width||d||this.graph.width*c,this.height=a.height||e||this.graph.height,this.vis.attr("width",this.width).attr("height",this.height*(1+c));var f=this.height*c;this.element.style.top=-1*f+"px"},this.render=function(){this.graph.height!==this._renderHeight&&this.setSize({auto:!0});var b=d3.svg.axis().scale(this.graph.y).orient(this.orientation);b.tickFormat(a.tickFormat||function(a){return a});if(this.orientation=="left")var d=this.height*c,e="translate("+this.width+", "+d+")";this.element&&this.vis.selectAll("*").remove(),this.vis.append("svg:g").attr("class",["y_ticks",this.ticksTreatment].join(" ")).attr("transform",e).call(b.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));var f=(this.orientation=="right"?1:-1)*this.graph.width;this.graph.vis.append("svg:g").attr("class","y_grid").call(b.ticks(this.ticks).tickSubdivide(0).tickSize(f)),this._renderHeight=this.graph.height},this.initialize(a)},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Highlight"),Rickshaw.Graph.Behavior.Series.Highlight=function(a){this.graph=a.graph,this.legend=a.legend;var b=this,c={};this.addHighlightEvents=function(a){a.element.addEventListener("mouseover",function(d){b.legend.lines.forEach(function(b){if(a===b)return;c[b.series.name]=c[b.series.name]||b.series.color,b.series.color=d3.interpolateRgb(b.series.color,d3.rgb("#d8d8d8"))(.8).toString()}),b.graph.update()},!1),a.element.addEventListener("mouseout",function(a){b.legend.lines.forEach(function(a){c[a.series.name]&&(a.series.color=c[a.series.name])}),b.graph.update()},!1)},this.legend&&this.legend.lines.forEach(function(a){b.addHighlightEvents(a)})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Order"),Rickshaw.Graph.Behavior.Series.Order=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;$(function(){$(b.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(a,c){var d=[];$(b.legend.list).find("li").each(function(a,b){if(!b.series)return;d.push(b.series)});for(var e=b.graph.series.length-1;e>=0;e--)b.graph.series[e]=d.shift();b.graph.update()}}),$(b.legend.list).disableSelection()}),this.graph.onUpdate(function(){var a=window.getComputedStyle(b.legend.element).height;b.legend.element.style.height=a})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Toggle"),Rickshaw.Graph.Behavior.Series.Toggle=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;this.addAnchor=function(a){var c=document.createElement("a");c.innerHTML="✔",c.classList.add("action"),a.element.insertBefore(c,a.element.firstChild),c.onclick=function(b){a.series.disabled?(a.series.enable(),a.element.classList.remove("disabled")):(a.series.disable(),a.element.classList.add("disabled"))};var d=a.element.getElementsByTagName("span")[0];d.onclick=function(c){var d=a.series.disabled;if(!d)for(var e=0;ee){j=k;break}f[0][k+1]<=e?k++:k--}var e=f[0][j].x,l=this.xFormatter(e),m=b.x(e),n=0,o=b.series.active().map(function(a){return{order:n++,series:a,name:a.name,value:a.stack[j]}}),p,q=function(a,b){return a.value.y0+a.value.y-(b.value.y0+b.value.y)},r=b.y.magnitude.invert(b.element.offsetHeight-d);o.sort(q).forEach(function(a){a.formattedYValue=this.yFormatter.constructor==Array?this.yFormatter[o.indexOf(a)](a.value.y):this.yFormatter(a.value.y),a.graphX=m,a.graphY=b.y(a.value.y0+a.value.y),r>a.value.y0&&r0?this[0].data.forEach(function(b){a.data.push({x:b.x,y:0})}):a.data.length==0&&a.data.push({x:this.timeBase-(this.timeInterval||0),y:0}),this.push(a),this.legend&&this.legend.addLine(this.itemByName(a.name))},addData:function(a){var b=this.getIndex();Rickshaw.keys(a).forEach(function(a){this.itemByName(a)||this.addItem({name:a})},this),this.forEach(function(c){c.data.push({x:(b*this.timeInterval||1)+this.timeBase,y:a[c.name]||0})},this)},getIndex:function(){return this[0]&&this[0].data&&this[0].data.length?this[0].data.length:0},itemByName:function(a){for(var b=0;b0;d--)this.currentSize+=1,this.currentIndex+=1,this.forEach(function(a){a.data.unshift({x:((d-1)*this.timeInterval||1)+this.timeBase,y:0,i:d})},this)},addData:function($super,a){$super(a),this.currentSize+=1,this.currentIndex+=1;if(this.maxDataPoints!==undefined)while(this.currentSize>this.maxDataPoints)this.dropData()},dropData:function(){this.forEach(function(a){a.data.splice(0,1)}),this.currentSize-=1},getIndex:function(){return this.currentIndex}}); \ No newline at end of file diff --git a/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.x.axis.js b/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.x.axis.js deleted file mode 100644 index 33e7e9a339e..00000000000 --- a/frontend/express/public/javascripts/visualization/rickshaw/rickshaw.x.axis.js +++ /dev/null @@ -1,124 +0,0 @@ -Rickshaw.namespace('Rickshaw.Graph.Axis.X'); - -Rickshaw.Graph.Axis.X = function(args) { - - var self = this; - var berthRate = 0.10; - - this.initialize = function(args) { - - this.graph = args.graph; - this.orientation = args.orientation || 'top'; - - this.pixelsPerTick = args.pixelsPerTick || 75; - if (args.ticks) this.staticTicks = args.ticks; - if (args.tickValues) this.tickValues = args.tickValues; - - this.tickSize = args.tickSize || 4; - this.ticksTreatment = args.ticksTreatment || 'plain'; - if (args.gridBeforeRender) { - this.gridBeforeRender = args.gridBeforeRender; - } - if (args.element) { - - this.element = args.element; - this._discoverSize(args.element, args); - - this.vis = d3.select(args.element) - .append("svg:svg") - .attr('height', this.height) - .attr('width', this.width) - .attr('class', 'rickshaw_graph x_axis_d3'); - - this.element = this.vis[0][0]; - this.element.style.position = 'relative'; - - this.setSize({ width: args.width, height: args.height }); - - } else { - this.vis = this.graph.vis; - } - - this.graph.onUpdate( function() { self.render() } ); - }; - - this.setSize = function(args) { - - args = args || {}; - if (!this.element) return; - - this._discoverSize(this.element.parentNode, args); - - this.vis - .attr('height', this.height) - .attr('width', this.width * (1 + berthRate)); - - var berth = Math.floor(this.width * berthRate / 2); - this.element.style.left = -1 * berth + 'px'; - }; - - this.render = function() { - - if (this._renderWidth !== undefined && this.graph.width !== this._renderWidth) this.setSize({ auto: true }); - - var axis = d3.svg.axis().scale(this.graph.x).orient(this.orientation); - axis.tickFormat( args.tickFormat || function(x) { return x } ); - if (this.tickValues) axis.tickValues(this.tickValues); - - this.ticks = this.staticTicks || Math.floor(this.graph.width / this.pixelsPerTick); - - var berth = Math.floor(this.width * berthRate / 2) || 0; - var bar_offset = this.graph.renderer.name == "bar" && Math.ceil(this.graph.width * 0.95 / this.graph.series[0].data.length / 2) || 0; - - var transform; - - if (this.orientation == 'top') { - var yOffset = this.height || this.graph.height; - transform = 'translate(' + (berth + bar_offset) + ',' + yOffset + ')'; - } else { - transform = 'translate(' + (berth + bar_offset) + ', 0)'; - } - - if (this.element) { - this.vis.selectAll('*').remove(); - } - - this.vis - .append("svg:g") - .attr("class", ["x_ticks_d3", this.ticksTreatment].join(" ")) - .attr("transform", transform) - .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize)); - - var gridSize = (this.orientation == 'bottom' ? 1 : -1) * this.graph.height; - - var intermediate = this.graph.vis - .append("svg:g") - .attr("class", "x_grid_d3"); - - intermediate = this.gridBeforeRender(this.graph.width, intermediate); - - intermediate.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize)) - .selectAll('text') - .each(function() { this.parentNode.setAttribute('data-x-value', this.textContent) }); - - this._renderHeight = this.graph.height; - }; - - this._discoverSize = function(element, args) { - - if (typeof window !== 'undefined') { - - var style = window.getComputedStyle(element, null); - var elementHeight = parseInt(style.getPropertyValue('height'), 10); - - if (!args.auto) { - var elementWidth = parseInt(style.getPropertyValue('width'), 10); - } - } - - this.width = (args.width || elementWidth || this.graph.width) * (1 + berthRate); - this.height = args.height || elementHeight || 40; - }; - - this.initialize(args); -}; diff --git a/frontend/express/public/localization/dashboard/dashboard.properties b/frontend/express/public/localization/dashboard/dashboard.properties index d40c7050c0b..c9b1bfece9e 100644 --- a/frontend/express/public/localization/dashboard/dashboard.properties +++ b/frontend/express/public/localization/dashboard/dashboard.properties @@ -1,10 +1,10 @@ #common common.total-sessions = Total Sessions -common.total-sessions-description = Number of times your application is opened, by new or returning users, in the selected time period. +common.total-sessions-description = The number of times your application is opened by new or returning users within the selected time period. common.new-sessions = New Sessions -common.new-sessions-description = Number of times your application is opened by a new user, in the selected time period. It is equal to the number of New Users and it only counts the first session the user had. +common.new-sessions-description = The number of times your application is opened by a new user within the selected time period. This is equal to the number of New Users and only counts the user's first session. common.unique-sessions = Unique Sessions -common.unique-sessions-description = Number of times your application is opened by a new or returning user from a unique device, in the selected time period. It is equal to the number of Total Users. +common.unique-sessions-description = The number of times your application is opened by a new or returning user from a unique device within the selected time period. This is equal to the number of Total Users. common.total-users = TOTAL USERS common.new-users = NEW USERS common.returning-users = RETURNING USERS @@ -18,15 +18,15 @@ common.table.no-data = No data common.search.no-match-found = No match found common.table.total-users = Total Users common.selected-users = Some specific users -common.table.total-users-desc = The number of users (unique devices/IDs) who have opened your application in the selected time period. +common.table.total-users-desc = The number of users (unique devices/IDs) who have opened your application within the selected time period. web.common.table.total-users = Total Visitors -web.common.table.total-users-desc = The number of visitors (unique devices/IDs) who have visited your website in the selected time period. +web.common.table.total-users-desc = The number of visitors (unique devices/IDs) who have visited your website within the selected time period. common.table.new-users = New Users -common.table.new-users-desc = The number of first-time users (unique devices/IDs) in the selected time period. +common.table.new-users-desc = The number of first-time users (unique devices/IDs) within the selected time period. common.table.returning-users = Returning Users -common.table.returning-users-desc = Number of users using your application for the second or later time, in the selected time period, calculated as Total Users (less) New Users. +common.table.returning-users-desc = The number of users using your application for the second or later time within the selected time period, calculated as Total Users minus New Users. web.common.table.returning-users = Returning Visitors -web.common.table.returning-users-desc = Number of visitors using your website for the second or later time, in the selected time period, calculated as Total Visitors (less) New Visitors. +web.common.table.returning-users-desc = The number of visitors using your website for the second or later time within the selected time period, calculated as Total Visitors minus New Visitors. common.table.total-sessions = Total Sessions common.table.new-sessions = New Sessions common.table.unique-sessions = Unique Sessions @@ -47,27 +47,27 @@ common.yesterday = Yesterday common.previous-period = Previous period common.previous-year = Same period in previous year common.bar.top-resolution = Top Resolutions -common.bar.top-resolution.description = Top 5 resolution settings of the devices used your users' sessions, in the selected time period. -web.common.bar.top-resolution.description = Top 5 resolution settings of the devices used your visitors' sessions, in the selected time period. +common.bar.top-resolution.description = The top 5 resolution settings of the devices used in your users' sessions within the selected time period. +web.common.bar.top-resolution.description = The top 5 resolution settings of the devices used in your visitors' sessions within the selected time period. common.bar.top-carrier = Top Carriers common.bar.top-users = TOP USERS common.bar.top-platform = Top Platforms -common.bar.top-platform.description = Top 5 versions of the platforms of your users’ sessions, in the selected time period. -web.common.bar.top-platform.description = Top 5 versions of the platforms of your visitors’ sessions, in the selected time period. +common.bar.top-platform.description = The top 5 platform versions of your users’ sessions within the selected time period. +web.common.bar.top-platform.description = The top 5 platform versions of your visitors’ sessions within the selected time period. common.bar.top-platform-version = Top Platform Versions -common.bar.top-platform-version.description = Top 3 versions of the platforms of your users' sessions, in the selected time period. -web.common.bar.top-platform-version.description = Top 3 versions of the platforms of your visitors' sessions, in the selected time period. +common.bar.top-platform-version.description = The top 3 platform versions of your users' sessions within the selected time period. +web.common.bar.top-platform-version.description = The top 3 platform versions of your visitors' sessions within the selected time period. common.bar.top-devices = Top Devices -common.bar.top-devices.description = Top 5 devices of your users’ based on their sessions, in the selected time period. -web.common.bar.top-devices.description = Top 5 devices of your visitors’ based on their sessions, in the selected time period. +common.bar.top-devices.description = The top 5 devices of your users based on their sessions within the selected time period. +web.common.bar.top-devices.description = The top 5 devices of your visitors based on their sessions within the selected time period. common.bar.top-device-types = Top Device types -common.bar.top-device-types.description = Top 5 device types of your users’ based on their sessions, in the selected time period. -web.common.bar.top-device-types.description = Top 5 device types of your visitors’ based on their sessions, in the selected time period. +common.bar.top-device-types.description = The top 5 device types of your users based on their sessions within the selected time period. +web.common.bar.top-device-types.description = The top 5 device types of your visitors based on their sessions within the selected time period. common.bar.top-browsers = Top Browsers -common.bar.top-browsers.description = Top 5 browsers of your users’ based on their sessions, in the selected time period +common.bar.top-browsers.description = The top 5 browsers of your users based on their sessions within the selected time period. common.bar.top-app-versions = Top App Versions -common.bar.top-app-versions.description = Top 5 App versions of your users’ based on their sessions, in the selected time period. -web.common.bar.top-app-versions.description = Top 5 App versions of your visitors’ based on their sessions, in the selected time period. +common.bar.top-app-versions.description = The top 5 app versions of your users based on their sessions within the selected time period. +web.common.bar.top-app-versions.description = The top 5 app versions of your visitors based on their sessions within the selected time period. common.bar.no-data = No Data common.apply = Apply common.apply-changes = Apply changes @@ -106,7 +106,7 @@ common.started = Started common.info = Information common.save-changes = Save changes common.graph-max = Maximum {0} {1} reached on {2} -common.graph-min = Minumum {0} {1} on {2} +common.graph-min = Minimum {0} {1} on {2} common.graph.time-spent = Time Spent (min) common.graph.average-time = Avg. Time Spent (min) common.graph.reqs-received = Requests Received @@ -161,7 +161,7 @@ common.search = Search common.unknown = Unknown common.eu = European Union common.integrate-sdks = Need some help with SDK integration? -common.integrate-sdks-text = helps you generate personalized code snippets and SDK integration tutorials based on your platforms and Countly features you want to use. +common.integrate-sdks-text = Helps you generate personalized code snippets and SDK integration tutorials based on your platforms and Countly features you want to use. common.integrate-sdks-platforms = Select a platform to get started common.go-to-countries = Go to Countries common.show = Show @@ -251,7 +251,7 @@ common.copy-error-message = Something went wrong, please copy it again. common.created-at-by = Created {0} by {1} common.updated = Updated common.manage = Manage -common.selected-with-count ={0} Selected +common.selected-with-count = {0} Selected common.selected = Selected common.select-all-with-count = Select all {0} common.deselect = Deselect @@ -348,7 +348,7 @@ taskmanager.recalculating = Recalculating #task manager assistent notification strings assistant.taskmanager.longTaskTooLong.title = This request is running for too long. -assistant.taskmanager.longTaskTooLong.message = We have switched it to report manager and will notify you when it is finished. +assistant.taskmanager.longTaskTooLong.message = We have switched it to the report manager and will notify you when it is finished. assistant.taskmanager.longTaskTooLong.info = Check its status in Utilities -> Report Manager assistant.taskmanager.longTaskAlreadyRunning.title = A similar report is already running. assistant.taskmanager.longTaskAlreadyRunning.message = Looks like report with same parameters already running in report manager @@ -409,7 +409,7 @@ sidebar.analytics.carriers = Carriers sidebar.analytics.platforms = Platforms sidebar.analytics.resolutions = Resolutions sidebar.analytics.technology = Technology -sidebar.analytics.technology-description = Overview details of your app or website traffic by your users’ technology, such as platform, device, resolution, browsers and app version. +sidebar.analytics.technology-description = Overview details of your app or website traffic based on your users’ technology, such as platform, device, resolution, browsers, and app version. sidebar.analytics.geo = Geo sidebar.engagement = Engagement sidebar.events = Events @@ -440,15 +440,14 @@ sidebar.dashboard-tooltip = Dashboards sidebar.main-menu = Main Menu sidebar.my-profile = My Profile sidebar.copy-api-key-success-message = Api Key has been copied to clipboard! -sidebar.banner.text = You are using a free plan. -sidebar.banner.upgrade = Upgrade and get more. -sidebar.banner.upgrade-button = Manage your plan +sidebar.banner.text = Countly’s self-service product analytics offering. +sidebar.banner.upgrade-button = Create a free server #dashboard dashboard.apply = Apply dashboard.home-desc = Overview of collected data dashboard.empty-title = Nothing to show -dashboard.empty-text = There are no data to show. Enable features or Customize this page to see data about choosen features. +dashboard.empty-text = There is no data to show. Enable features or customize this page to see data about chosen features. dashboard.audience = Audience dashboard.customize-home = Customize Home dashboard.avg-time-spent = Avg. Session Duration @@ -457,7 +456,7 @@ dashboard.time-spent = Time Spent dashboard.time-spent-desc = Total time spent for this period dashboard.reqs-received = REQUESTS RECEIVED dashboard.avg-reqs-received = Avg. Requests Received -dashboard.avg-reqs-received-desc = Number of write API requests Countly Server receives for each session (includes sessions, session extensions, events, etc) +dashboard.avg-reqs-received-desc = The number of write API requests the Countly Server receives for each session (includes sessions, session extensions, events, etc.). dashboard.bounce-rate = BOUNCE RATE dashboard.pages-per-visit = PAGES PER VISIT dashboard.note-title-remaining = Remaining @@ -469,8 +468,8 @@ users.title = USERS #user-activity user-activity.title = User Activity web.user-activity.title = Visitor Activity -user-activity.description = Overview of the total number of users who started a session on your application, distributed in pre-set categories of numbers of sessions. -web.user-activity.description = Overview of the total number of visitors who started a session on your website, distributed in pre-set categories of numbers of sessions. +user-activity.description = An overview of the total number of users who started a session on your application, distributed in pre-set categories based on the number of sessions. +web.user-activity.description = An overview of the total number of visitors who started a session on your website, distributed in pre-set categories based on the number of sessions. user-activity.barchart-all-users = All Users web.user-activity.barchart-all-users = All Visitors user-activity.barchart-thirty-days = Active Users (30 days) @@ -501,7 +500,7 @@ session-durations.description = Time period(s) for which users have opened your #session-frequency session-frequency.title = Session Frequency -session-frequency.description = Number of times users open your application, in the selected time period, distributed into frequency ranges. +session-frequency.description = The number of times users open your application within the selected time period, distributed into frequency ranges. session-frequency.table.frequency = Time since last session #notes @@ -533,8 +532,8 @@ session-duration.table.duration = Session duration #countries countries.title = Countries -countries.description = An overview of the geographical distribution of your users and their sessions in the selected time period. -web.countries.description = An overview of the geographical distribution of your visitors and their sessions in the selected time period. +countries.description = An overview of the geographical distribution of your users and their sessions within the selected time period. +web.countries.description = An overview of the geographical distribution of your visitors and their sessions within the selected time period. countries.table.country = Country countries.table.city = City countries.back-to-list = Back to Country List @@ -556,8 +555,8 @@ web.user-analytics.overview-title = Visitors Overview #resolutions resolutions.title = Resolutions -resolutions.description = Detailed information on the resolution settings of the devices through which your users access your application, in the selected time period. -web.resolutions.description = Detailed information on the resolution settings of the devices through which your visitors access your website, in the selected time period. +resolutions.description = Detailed information on the resolution settings of the devices through which your users access your application within the selected time period. +web.resolutions.description = Detailed information on the resolution settings of the devices through which your visitors access your website within the selected time period. resolutions.table.resolution = Resolution resolutions.table.width = Width @@ -566,22 +565,22 @@ resolutions.table.height = Height #device_type device_type.title = Devices and Types -device_type.description = Details of the device models and types from which your users access your application, in the selected time period. -web.device_type.description = Details of the device models and types from which your visitors access your website, in the selected time period. +device_type.description = Details of the device models and types from which your users access your application within the selected time period. +web.device_type.description = Details of the device models and types from which your visitors access your website within the selected time period. device_type.table.device_type = Device Type device_type.types = Types device_type.devices = Devices #app-versions app-versions.title = App Versions -app-versions.description = Detailed information on the application versions of your application accessed by your users, in the selected time period. -web.app-versions.description = Detailed information on the website versions of your website accessed by your visitors, in the selected time period. +app-versions.description = Detailed information on the application versions of your application accessed by your users within the selected time period. +web.app-versions.description = Detailed information on the website versions of your website accessed by your visitors within the selected time period. app-versions.table.app-version = App Version #carriers carriers.title = Carriers carriers.table.carrier = Carrier -carriers.description = Detailed information on the network carriers of the devices through which your users access your application, in the selected time period. +carriers.description = Detailed information on the network carriers of the devices through which your users access your application within the selected time period. #platforms platforms.title = Platforms @@ -589,8 +588,8 @@ platforms.pie-right = PLATFORM VERSIONS platforms.table.platform = Platform platforms.table.platform-version = Platform Version platforms.table.platform-version-for = Platform Versions for -platforms.description = Details of the platforms on which yours users access your application, in the selected time period. -web.platforms.description = Details of the platforms on which yours visitors access your website, in the selected time period. +platforms.description = Details of the platforms on which your users access your application within the selected time period. +web.platforms.description = Details of the platforms on which your visitors access your website within the selected time period. platforms.platforms-for = Platforms for platforms.version-distribution = Platforms version distribution platforms.versions = Versions @@ -611,7 +610,7 @@ events.blueprint-events-show.visible = Visible Events events.go-to-events = Go to Events events.blueprint-events-properties-tooltip = Edited properties of this event will be updated on All Events and other plugins. -events.blueprint-event-groups-include-events-tooltip = Select at least 2 events to create an Event Group. New Event Groups will automatically sum all the selected event properties and report them. +events.blueprint-event-groups-include-events-tooltip = Select at least 2 events to create an Event Group. New Event Groups will automatically sum all the selected event properties and report them. events.blueprint-event-groups-properties-tooltip = Edited properties in this Event Group will be updated across All Events and other plugins. events.blueprint-event-group-included-events = INCLUDED EVENTS @@ -646,7 +645,7 @@ events.general.yes-delete-event = Yes, delete event events.general.yes-delete-events = Yes, delete events events.general.want-to-discard = You have made changes to this event. Do you want to leave and discard those changes? events.general.want-to-discard-title = Discard changes? -events.general.events-deleted = Selected events deleted sucessfully +events.general.events-deleted = Selected events deleted successfully events.general.no-hidden-events = There are no hidden events events.general.no-visible-events = There are no visible events events.back-to-events = Back to all events @@ -678,7 +677,7 @@ events.edit.display-sum-description = A display name for the optional sum proper events.edit.display-duration = Display name for duration events.edit.display-duration-description = A display name for the optional duration property of this event. events.edit.event-properties = Event properties -events.no-event = There are no events tracked for this application\! +events.no-event = There are no events tracked for this application! events.delete-confirm = You are about to delete all data associated with event "{0}". Do you want to continue? events.delete-confirm-many = You are about to delete all data associated with these events. Do you want to continue? events.delete.multiple-events = {0} events @@ -687,7 +686,7 @@ events.edit.omit-event-segments-description = Choose which segments of this cust events.edit.omit-event-segments-description-drill = Data for these segments will still be stored in Drill. events.edit.omit-event-segments-to-omit = Segments to omit events.edit.omit-event-select-segments = Select segments -event.edit.omitt-warning = You are about to omit data for some segments of this event. Omitted segments will not be saved in the future and past data for these segments will be purged immediately after you save these settings. Do you want to continue? +event.edit.omitt-warning = You are about to omit data for some segments of this event. Omitted segments will not be saved in the future, and past data for these segments will be purged immediately after you save these settings. Do you want to continue? events.overview.title = Overview events.overview.drawer-title = Configure overview events.overview.empty = You don't have any items in overview @@ -698,15 +697,15 @@ events.overview.choose-event = Choose event events.overview.choose-property = Choose property events.overview.table.title-event = Event events.overview.table.title-property = Property -events.overview.max-c = You can add maximum 12 previews in overview. Please delete some of previously added to add new. -events.overview.have-already-one = You have already one item with the same event and propery in overview. +events.overview.max-c = You can add a maximum of 12 previews in the overview. Please delete some of the previously added items to add new ones. +events.overview.have-already-one = You already have one item with the same event and property in the overview. events.overview.empty-title = Events overview is empty -events.overview.empty-text-admin = Configure events overview to visualise your most important custom events at a glance. -events.overview.empty-text-user = Request an admin of this application to configure events overview to visualise most important custom events at a glance. +events.overview.empty-text-admin = Configure the events overview to visualise your most important custom events at a glance. +events.overview.empty-text-user = Request an admin of this application to configure the events overview to visualise the most important custom events at a glance. events.overview.save-changes = Save changes events.overview.unknown = NA -events.all.empty-title = This application doesn't have any custom events -events.all.empty-text = Log some custom events inside your application's code using the SDKs and visit this section later +events.all.empty-title = This application does not have any custom events. +events.all.empty-text = Log some custom events inside your application's code using the SDKs and visit this section later. events.top-events.title = Top Events By Count events.top-events.24hours = 24-Hours events.top-events.30days = 30-Days @@ -717,7 +716,7 @@ events.max-segmentation-limit = Maximum limit of segmentations ({0}) in current events.max-unique-value-limit = Maximum limit of unique values ({0}) in current event segmentation "{1}" has been reached. Limit can be adjusted. events.event-group-drawer-create = Create new Event Group -events.event-group-name = Event Group name +events.event-group-name = Event Group name events.group-use-description = Use description events.group-include-events = Include events events.group-select-events = Select events to include @@ -729,9 +728,9 @@ events.group-invisibility-checkbox = Event Group is invisible events.group-properties = Event Group Properties events.event-group-count = Display name for count events.event-group-count-description = A display name for the count property of this event -events.event-group-sum= Display name for sum +events.event-group-sum = Display name for sum events.event-group-sum-description = A display name for the sum property of this event -events.event-group-duration = Display name for duration +events.event-group-duration = Display name for duration events.event-group-duration-description = A display name for the duration property of this event events.create-group = Create Event Group events.save-group = Save Event Group @@ -748,8 +747,8 @@ export.documents = documents export.export-columns-selected-count = {0}/{1} selected export.format-if-possible = Format timestamps to readable date export.format-if-possible-explain = Fields which are saved in data base as timestamps will be converted to show as date string like in table. For example: "Mon, 29 Jun 2020 17:14:15" -export.export-started = Export file is being generated. When ready you will see notification or can download it in report manager. -export.export-failed = Error upon attempting to export table data. +export.export-started = The export file is being generated. When ready, you will see a notification or can download it in the report manager. +export.export-failed = An error occurred while attempting to export table data. export.export-finished = Export completed. export.export-finished-click = Click to download exported file. export.file-name = File name @@ -759,9 +758,9 @@ management-applications.title = Application Management management-applications.my-new-app = My new app management-applications.clear-data = Clear data management-applications.clear-reset-data = Reset application -management-applications.clear-reset-explanation = Resets app to initial clean state like right after creation +management-applications.clear-reset-explanation = Resets the app to its initial clean state, as it was right after creation. management-applications.clear-all-data = Clear all data -management-applications.clear-all-explanation = Removes collected data but keeps configurations +management-applications.clear-all-explanation = Removes collected data but keeps the configurations. management-applications.clear-1month-data = Clear data older than 1 month management-applications.clear-3month-data = Clear data older than 3 months management-applications.clear-6month-data = Clear data older than 6 months @@ -784,7 +783,7 @@ management-applications.category.tip = Select a category management-applications.app-id = App ID management-applications.app-id.hint = This ID is used for the read API management-applications.app-key = App Key -management-applications.app-key.hint = You'll need this key for SDK integration +management-applications.app-key.hint = You will need this key for SDK integration. management-applications.app-key.generate = Will generate automatically management-applications.app-key-unique = This App Key is already in use management-applications.time-zone = Time Zone @@ -795,23 +794,23 @@ management-applications.icon = App Icon management-applications.add-application = Add application management-applications.clear-confirm-all = You are about to clear all the collected data stored for your application. Do you want to continue? management-applications.clear-confirm-period = You are about to clear all the collected data stored for your application within a selected period of time. Do you want to continue? -management-applications.clear-confirm-reset = You are about to reset your app to initial clean state. Do you want to continue? +management-applications.clear-confirm-reset = You are about to reset your app to its initial clean state. Do you want to continue? management-applications.clear-admin = Only administrators of an application can clear it's data. management-applications.clear-success = Application data is successfully cleared. management-applications.reset-success = Application is successfully reset. management-applications.delete-confirm = You are about to delete all the data associated with your application. Do you want to continue? management-applications.delete-admin = Only administrators of an application can delete it. management-applications.app-locked = Application is locked. -management-applications.icon-error = Only jpg, png and gif image formats are allowed +management-applications.icon-error = Only JPG, PNG, and GIF image formats are allowed. management-applications.no-app-warning = In order to start collecting data you need to add an application to your account. management-applications.app-key-change-warning-title = Changing the App key management-applications.app-key-change-warning = Changing the app key will cause all users from this point on to be recorded as new users even if they used your application before. This action is only recommended if you are migrating an application from another server or changing the app key of a new application. management-applications.app-key-change-warning-confirm = Continue, change the app key management-applications.app-key-change-warning-EE = Changing the app key will cause all users from this point on to be recorded as new users even if they used your application before. This action is only recommended if you are migrating an application from another server or changing the app key of a new application. If your intention was to change the app key to stop collecting data for this application, recommended way of doing so is using Filtering Rules plugin. -management-applications.first-app-message2 = Great\! You can now embed Countly SDK into your application and start viewing your stats instantly. Don't forget to get your App Key from above. +management-applications.first-app-message2 = Great! You can now embed the Countly SDK into your application and start viewing your stats instantly. Don't forget to get your App Key from above. management-applications.types.mobile = Mobile management-applications.checksum-salt = Salt for checksum -management-applications.checksum-salt.hint = Will only accept requests where checksum is signed with the same salt in SDK +management-applications.checksum-salt.hint = Will only accept requests where the checksum is signed with the same salt in the SDK. management-applications.app-domain = Website Domain management-applications.app-creator = App created by management-applications.app-created-at = Date of creation @@ -831,9 +830,9 @@ management-applications.plugins.saved.title = Plugin configuration management-applications.plugins.saved = Changes saved successfully! management-applications.plugins.error.server = Unknown server error management-applications.create-first-app-title = Let's add your first application. -management-applications.create-first-app-description = After adding your first application you'll be ready to start collecting data. +management-applications.create-first-app-description = After adding your first application, you will be ready to start collecting data. management-applications.contact-an-admin = Please contact an administrator -management-applications.dont-access = You don't access rights to any application. +management-applications.dont-access = You don't have access rights to any application. management-applications.plugins-description = Settings in this section will override global settings for the application management-applications.application-lock-tooltip = Application lock prevents accidental data purge and data population management-applications.application-tooltip-locked-text = App is locked. Unlock it to allow changes. @@ -857,7 +856,7 @@ management-users.apps = Apps management-users.sidebar-title = User Management management-users.users = Users management-users.view-title = Manage Users -management-users.editing-your-account = You\'re about to edit your own account. So you may be logged out automatically if changed something related with your permission. Do you want to contiue? +management-users.editing-your-account = You are about to edit your own account. So you may be logged out automatically if you change something related to your permission. Do you want to continue? management-users.feature = Feature management-users.create = Create management-users.read = Read @@ -869,7 +868,7 @@ management-users.create-new-user = Create new user management-users.remove-permission-set = Remove permission set management-users.create-user = Create user management-users.discard-changes = Discard Changes -management-users.discard-confirm = You will lose all changes that you made. Are you sure to continue? +management-users.discard-confirm = You will lose all the changes that you have made. Are you sure you want to continue? management-users.permission-settings = Permission settings management-users.user-has-access-to = User has access to management-users.role = Role @@ -888,7 +887,7 @@ management-users.drag-and-drop-or = Drag and drop file here or management-users.click-to-upload = click to upload a file management-users.browser = browser management-users.files-to-add-picture = files to add picture -management-users.pp-size-warning = JPG, PNG and GIF files allowed. Maximum size is 5 MB. +management-users.pp-size-warning = JPG, PNG, and GIF files are allowed. The maximum size is 5 MB. management-users.remove-image = Remove image management-users.email = E-mail management-users.enter-email = Enter E-mail address @@ -912,8 +911,8 @@ management-users.disable-2fa-user = Disable 2FA management-users.all-roles = All roles management-users.not-logged-in-yet = Not logged in yet management-users.close = Click to close -management-users.password-change-confirm = You have changed {0}\''s password. Do you want a notification email to be sent? -management-users.delete-confirm = You are about to delete {0}\''s account. Do you want to continue? +management-users.password-change-confirm = You have changed {0}'s password. Do you want a notification email to be sent? +management-users.delete-confirm = You are about to delete {0}'s account. Do you want to continue? management-users.delete-confirm-title = Delete user? management-users.yes-delete-user = Yes, delete user management-users.email.invalid = invalid email @@ -930,12 +929,12 @@ management-users.revoke-confirm = You are about to remove this user's access to management-users.email-tip = User will be notified even if there is not an account for this email... management-users.last_login = Last Login management-users.created = Created -management-users.created-message = User created successfully\! +management-users.created-message = User created successfully! management-users.removed = Removed -management-users.removed-message = User removed successfully\! +management-users.removed-message = User removed successfully! management-users.remove-canceled = User remove canceled management-users.updated = Updated -management-users.updated-message = User informations updated successfully\! +management-users.updated-message = User information updated successfully! management-users.confirm-loss-checkboxes = You will lose all marked permissions below. Are you sure you want to continue? management-users.select-app-first-title = Select app first management-users.select-app-first-message = You need to select app or apps before you mark permission boxes @@ -954,7 +953,7 @@ management-users.group-blank = - management-users.reset-filters = Reset Filters management-users.search-placeholder = Search in Features management-users.reset-failed-logins = Reset failed logins -management-users.reset-failed-logins-success = Failed logins reset successfully\! +management-users.reset-failed-logins-success = Failed logins reset successfully! management-users.reset-failed-logins-failed = Failed to reset logins\! management-users.cannot-delete-own-account = You can not delete your own account management-users.cannot-revoke-own-admin = You can not revoke your own global admin privileges @@ -984,9 +983,9 @@ management.preset.duplicate-preset = Duplicate date preset management.preset.date-range = Date range management.preset.exclude-current-day = Exclude current day management.preset.exclude-current-day.description = By excluding the current day, results may change as the day has not yet ended. -management.preset.created = Preset created successfully\! -management.preset.updated = Preset updated successfully\! -management.preset.deleted = Preset deleted successfully\! +management.preset.created = Preset created successfully! +management.preset.updated = Preset updated successfully! +management.preset.deleted = Preset deleted successfully! management.preset.created.error = Something went wrong while creating preset. management.preset.updated.error = Something went wrong while updating preset. management.preset.deleted.error = Something went wrong while deleting preset. @@ -1008,23 +1007,23 @@ user-settings.old-password = Old password... user-settings.new-password = New password... user-settings.password-again = Again... user-settings.alert = Something is wrong... -user-settings.success = Settings saved successfully\! +user-settings.success = Settings saved successfully! user-settings.api-key = API Key user-settings.password-match = Passwords don't match user-settings.old-password-match = Provide old password to change it user-settings.old-password-not-match = Old password does not match -user-settings.password-not-old = New password must not be the same as old the one +user-settings.password-not-old = New password must not be the same as the old one user-settings.force-password-reset = It is time to change your password. user-settings.please-correct-input = Please fix errors before submitting the form user-settings.api-key-length = API key should be exactly 32 characters long user-settings.api-key-restrict = API key should contain digits and alphabetical characters user-settings.regenerate-api-key = Regenerate API key user-settigs.delete-account = Delete account -user-settings.delete-account-title = Delete account? +user-settings.delete-account-title = Delete account? user-settings.delete-account-confirm = Do you really want to delete your account? You won't be able to recover it. -user-settings.password-mandatory = Password is mandatory! -user-settings.global admin limit = This account is last global admin account. Can't delete last global admin account. -user-settings.password not valid = Given password is not valid +user-settings.password-mandatory = Password is mandatory. +user-settings.global admin limit = This account is the last global admin account. Can't delete the last global admin account. +user-settings.password not valid = The given password is not valid user-settings.profile-picture = Profile Picture user-settings.upload = Upload @@ -1063,12 +1062,12 @@ app-users.download-export = Download user's exported data app-users.delete-export = Purge user's exported data app-users.delete-userdata = Purge selected user's data completely app-users.delete-userdata-confirm = Do you really want to purge all data associated with this user? -app-users.export-started = Exporting has started sucessfully. +app-users.export-started = Exporting has started successfully. app-users.export-finished = User data is exported. You can download it now. app-users.export-finished-click = Click here to download. -app-users.export-failed = There was error during export process. There might be more information in logs. +app-users.export-failed = There was an error during the export process. There might be more information in logs. app-users.export-deleted = Export data was purged -app-users.userdata-deleted = User's data has been purged +app-users.userdata-deleted = User's data has been purged app-users.yes-purge-data = Yes, purge data app-users.no-dont-purge = No, don't purge app-users.purge-confirm-title = Purge user's data completely? @@ -1085,28 +1084,28 @@ token_manager.page-title = Token Manager token_manager.create-token = Create Token token_manager.create-new-token = Create New Token token_manager.table.id = Token ID -token_manager.table.ends =Valid until -token_manager.table.multi = Multiple times +token_manager.table.ends = Valid Until +token_manager.table.multi = Multiple times token_manager.table.owner = Token owner token_manager.table.app = App -token_manager.table.status = Status +token_manager.table.status = Status token_manager.table.endpoint = Endpoint token_manager.table.endpoints = Endpoints token_manager.table.endpoint-name = Endpoint Name token_manager.table.endpoint-detail = ENDPOINT DETAILS -token_manager.table.endpoints-description = Given endpoints are interpreted as regularexpressions +token_manager.table.endpoints-description = Given endpoints are interpreted as regular expressions. token_manager.table.expiration-description = Set expiration time for token token_manager.table.purpose = Description token_manager.table.token-description = Token Description -token_manager.table.purpose-desc = Some information to help user identify created token. -token_manager.table.endpoint-desc = You can limit token to a single or multiple endpoints. Given endpoints are interpreted as regular expressions. -token_manager.table.multi-desc = Token can be used multiple times +token_manager.table.purpose-desc = Some information to help the user identify created token. +token_manager.table.endpoint-desc = You can limit the token to a single or multiple endpoints. Given endpoints are interpreted as regular expressions. +token_manager.table.multi-desc = Token can be used multiple times. token_manager.table.apps-title = Token Usage token_manager.table.apps-limit = Allow token to be used only in some apps token_manager.table.apps-allow = Allow token to be used in all apps -token_manager.table.limit-limit.label = Limited Time +token_manager.table.limit-limit.label = Limited Time token_manager.table.limit-limit.text = Token will expire after the time you set -token_manager.table.limit-allow.label = Unlimited Time +token_manager.table.limit-allow.label = Unlimited Time token_manager.table.limit-allow.text = Token can be used until it is deleted token_manager.table.limit-title = Token Expiration token_manager.table.enter-number = Enter number @@ -1119,24 +1118,24 @@ token_manager.delete-token-confirm = Do you really want to delete this token? token_manager.delete-token-confirm-title = Delete token? token_manager.yes-delete-token = Yes, delete token token_manager.delete-error = Deleting token failed -token_manager.select-apps-error = You have to chose apps or set option to "Allow token to be used in all apps" -token_manager.select-expire-error = You have to choose after how long time token expires or set option to "Token can be used till it is deleted" +token_manager.select-apps-error = You have to choose apps or set option to "Allow token to be used in all apps" +token_manager.select-expire-error = You have to choose after how long time token expires or set option to "Token can be used until it is deleted" token_manager.table.delete-token = Delete token token_manager.table.status-expired = Expired token_manager.table.status-active = Active token_manager.copy-token = Click to copy -token_manager.token-coppied = Token coppied +token_manager.token-coppied = Token Copied token_manager.query-param = Query Parameters token_manager.query-param-value = Value -token_manager.query-param-desc = Limit by some parameter values(for example method=get_events) Value is used as regex when validating. +token_manager.query-param-desc = Limit by some parameter values (for example, method=get_events). The value is used as a regex when validating. token_manager.add-new-endpoint = Add new endpoint token_manager.add-param = Add parameter -token_manager.parameter = Parameter -token_manager.select-apps = Select Apps +token_manager.parameter = Parameter +token_manager.select-apps = Select Apps token_manager.select-time-unit = Select time unit token_manager.token-expiration-time = Expiration Time -token_manager.LoginAuthToken-description = This token is created when creating dashboard screenshots. If you are not currently rendering dashboard images, you can delete this token. -token_manager.LoggedInAuth-description = This token is used for keeping users session. Deleting it will log out user currently using it to keep session. +token_manager.LoginAuthToken-description = This token is created when creating dashboard screenshots. If you are not currently rendering dashboard images, you can delete this token. +token_manager.LoggedInAuth-description = This token is used for keeping the user's session. Deleting it will log out the user currently using it to keep the session. version_history.page-title = Countly version history @@ -1145,7 +1144,7 @@ version_history.package-version = Package version version_history.version = Version version_history.upgraded = Upgraded / installed version_history.alert-title = Version mismatch -version_history.alert-message = There is a version mismatch between version in files and in database. It may indicate that upgrade scripts didn't complete properly. +version_history.alert-message = There is a version mismatch between the version in the files and the version in the database. It may indicate that upgrade scripts did not complete properly. internal-events.[CLY]_session = Session #jobs @@ -1168,11 +1167,11 @@ systemlogs.action.task_manager_task_created = Report created #events-overview events.overview.title.new = Events Overview -events.overview.title.new.tooltip = Complete summary of all Events being tracked. -events.overview.total.event.count = Total number of Events triggered in the last 30 days. -events.overview.event.per.user = Average number of Events triggered per user, in the last 30 days. -events.overview.event.per.session = Average number of Events triggered per session, in the last 30 days. -events.overview.event.metrics = Overview of the metrics calculated by the identified Events, in the last 30 days. +events.overview.title.new.tooltip = A complete summary of all Events being tracked. +events.overview.total.event.count = The total number of Events triggered in the last 30 days. +events.overview.event.per.user = The average number of Events triggered per user in the last 30 days. +events.overview.event.per.session = The average number of Events triggered per session in the last 30 days. +events.overview.event.metrics = An overview of the metrics calculated by the identified Events in the last 30 days. events.overview.event.monitor.events = A quick summary of selected Events that you wish to monitor. To select Events that you want to highlight here, please click on 'Configure Events'. events.overview.metrics = Event Metrics events.overview.monitor = Monitor Events @@ -1196,12 +1195,12 @@ events.overview.manage.items = Manage Items events.overview.last-30days = Last 30 Days #all-events -events.all.title.tooltip = Details of the stats of each Event, in the selected time period, and their comparison where applicable. +events.all.title.tooltip = Details of the stats of each Event within the selected time period, and their comparison where applicable. events.all.title.new = All Events events.all.period = PERIOD events.all.event = EVENT events.all.segmentation = SEGMENTATION BY -events.segment.values = SEGMENT VALUES(S) +events.segment.values = SEGMENT VALUE(S) events.all.search.placeholder = Search in {0} Events events.all.group = GROUP events.all.error = Could not fetch data @@ -1217,24 +1216,24 @@ events.drill-drawer.title = Event Drill events.drill-drawer.save-button = Go to Drill #auto-refresh -auto-refresh.help= Automatically refresh can be adjusted through this switch -auto-refresh.enable= Enable Auto-refresh -auto-refresh.stop= Stop Auto-refresh -auto-refresh.is= Auto-refresh is +auto-refresh.help = Automatic refresh can be adjusted through this switch. +auto-refresh.enable = Enable Auto-refresh +auto-refresh.stop = Stop Auto-refresh +auto-refresh.is = Auto-refresh is auto-refresh.enabled = Enabled initial-setup.application = Application initial-setup.add-first-application-title = Let's add your first application -initial-setup.add-first-application-byline = After adding your first application, you'll be ready to start collecting data +initial-setup.add-first-application-byline = After adding your first application, you will be ready to start collecting data. initial-setup.add-demo-application-title = Let's create a demo app for you! initial-setup.application-type-label = Select your application type initial-setup.time-zone-label = Select your time zone -initial-setup.application-sample-label = We'll populate some demo data for your app, which example sounds the best? +initial-setup.application-sample-label = We will populate some demo data for your app. Which example sounds the best? initial-setup.create-application = Create Application initial-setup.continue-data-population = Continue with data population initial-setup.consent-title = Before we start... -initial-setup.analytics-blurb-1 = We utilize Countly to understand user interactions and collect feedback, helping us enhance our product continuously. However, your privacy remains our priority. -initial-setup.analytics-blurb-2 = This analysis is done on the server level, so we won't see or collect any individual details or any data you record. The data is reported back only to our dedicated Countly server based in Europe. Please note, you can change your mind at any time in the settings. +initial-setup.analytics-blurb-1 = We utilize Countly to understand user interactions and collect feedback, helping us enhance our product continuously. However, your privacy remains our priority. +initial-setup.analytics-blurb-2 = This analysis is done at the server level, so we will not see or collect any individual details or any data you record. The data is reported back only to our dedicated Countly server based in Europe. Please note, you can change your mind at any time in the settings. initial-setup.analytics-question = Considering our commitment to maintaining your privacy and the potential benefits for product enhancement, would you be comfortable enabling Countly on this server? initial-setup.analytics-no = No, maybe later initial-setup.analytics-yes = Yes, enable Countly on this server @@ -1242,4 +1241,4 @@ initial-setup.newsletter-blurb = We offer a newsletter brimming with recent upda initial-setup.newsletter-question = Would you be interested in subscribing to our newsletter? initial-setup.newsletter-no = No, thank you. initial-setup.newsletter-yes = Yes, subscribe me to the newsletter -initial-setup.quickstart-title = Quick Start Guide \ No newline at end of file +initial-setup.quickstart-title = Quick Start Guide diff --git a/frontend/express/public/localization/help/help.properties b/frontend/express/public/localization/help/help.properties index 1ac0fd77d2f..ed31daa5f9d 100644 --- a/frontend/express/public/localization/help/help.properties +++ b/frontend/express/public/localization/help/help.properties @@ -1,48 +1,48 @@ -help.help-mode-welcome = Hover on each item to view a brief explanation.

      While in this mode auto-refreshing of your data is disabled and will be enabled as soon as you turn off the help mode. -help.help-mode-welcome-title = Welcome to the help mode\! +help.help-mode-welcome = Hover over each item to view a brief explanation.

      While in this mode, auto-refreshing of your data is disabled and will be enabled as soon as you turn off help mode. +help.help-mode-welcome-title = Welcome to Help Mode! #dashboard -help.dashboard.total-sessions = Number of times your application is opened. Click this item to see a time series representation of total sessions. -help.dashboard.total-users = Number of unique devices your application is used from. Click this item to see a time series representation of total users. -help.dashboard.new-users = Number of first time users. Click this item to see a time series representation of new users. -help.dashboard.total-time-spent = Total time users spent using your application. -help.dashboard.avg-time-spent2 = Total time spent using your application divided by total session count. Click this item to see a time series representation of average time spent per session. -help.dashboard.reqs-received = Number of write API requests Countly Server received for this application. Click this item to see a time series representation of requests received. -help.dashboard.avg-reqs-received = Number of write API requests Countly Server received for this application divided by total user count. Click this item to see a time series representation of average requests per user. -help.dashboard.top-platforms = Shows at most top three platforms represented by different colors according to the number of sessions from each platform. Hover on each color to see the platform name. -help.dashboard.top-resolutions = Shows at most top three resolutions represented by different colors according to the number of sessions from each resolution. Hover on each color to see the resolution. -help.dashboard.top-carriers = Shows at most top three carriers represented by different colors according to the number of sessions from each carrier. Hover on each color to see the carrier name. -help.dashboard.top-users = Shows at most top three days in which your application reached maximum number of total users. Hover on each color to see the date. -help.dashboard.map = World map shows session counts from each country represented by a tone of green according to the count. Next to the map you can see a table of top ten countries together with the sessions counts (table is shown only if there is any available data). +help.dashboard.total-sessions = The number of times your application is opened. Click this item to see a time series representation of total sessions. +help.dashboard.total-users = The number of unique devices your application is used from. Click this item to see a time series representation of total users. +help.dashboard.new-users = The number of first-time users. Click this item to see a time series representation of new users. +help.dashboard.total-time-spent = The total time users spent using your application. +help.dashboard.avg-time-spent2 = The total time spent using your application divided by the total session count. Click this item to see a time series representation of the average time spent per session. +help.dashboard.reqs-received = The number of write API requests the Countly Server received for this application. Click this item to see a time series representation of requests received. +help.dashboard.avg-reqs-received = The number of write API requests the Countly Server received for this application, divided by the total user count. Click this item to see a time series representation of the average requests per user. +help.dashboard.top-platforms = Shows at most the top three platforms represented by different colors according to the number of sessions from each platform. Hover over each color to see the platform name. +help.dashboard.top-resolutions = Shows at most the top three resolutions represented by different colors according to the number of sessions from each resolution. Hover over each color to see the resolution. +help.dashboard.top-carriers = Shows at most the top three carriers represented by different colors according to the number of sessions from each carrier. Hover over each color to see the carrier name. +help.dashboard.top-users = Shows at most the top three days in which your application reached the maximum number of total users. Hover over each color to see the date. +help.dashboard.map = The world map shows session counts from each country, represented by a tone of green according to the count. Next to the map, you can see a table of the top ten countries together with their session counts (the table is shown only if there is any available data). #sessions view -help.sessions.total-sessions = Number of times your application is opened. Time series representation of this item is identified by the top border color of this block. -help.sessions.new-sessions = Number of times your application is opened by a first time user. Time series representation of this item is identified by the top border color of this block. -help.sessions.unique-sessions = Number of times your application is opened from a unique device. Time series representation of this item is identified by the top border color of this block. +help.sessions.total-sessions = The number of times your application is opened. The time series representation of this item is identified by the top border color of this block. +help.sessions.new-sessions = The number of times your application is opened by a first-time user. The time series representation of this item is identified by the top border color of this block. +help.sessions.unique-sessions = The number of times your application is opened from a unique device. The time series representation of this item is identified by the top border color of this block. #users view -help.users.total-users = Number of unique devices. Time series representation of this item is identified by the top border color of this block. -help.users.new-users = Number of first time users. Time series representation of this item is identified by the top border color of this block. -help.users.returning-users = Number of users that have used your application at least one time before. Time series representation of this item is identified by the top border color of this block. +help.users.total-users = The number of unique devices. The time series representation of this item is identified by the top border color of this block. +help.users.new-users = The number of first-time users. The time series representation of this item is identified by the top border color of this block. +help.users.returning-users = The number of users that have used your application at least one time before. The time series representation of this item is identified by the top border color of this block. #countries view -help.countries.chart = World map shows session counts from each country represented by a tone of green according to the count. -help.countries.table = Country\: Name of the country.
      Total Sessions\: Number of times your application is opened by a user from this country.
      Total Users\: Number of unique devices your application is used from within this country.
      New Users\: Number of first time users from this country.
      -help.countries.total-sessions = Number of times your application is opened. -help.countries.total-users = Number of unique devices. -help.countries.new-users = Number of first time users. +help.countries.chart = The world map shows session counts from each country represented by a tone of green according to the count. +help.countries.table = Country: Name of the country.
      Total Sessions: The number of times your application is opened by a user from this country.
      Total Users: The number of unique devices from which your application is used within this country.
      New Users: The number of first-time users from this country.
      +help.countries.total-sessions = The number of times your application is opened. +help.countries.total-users = The number of unique devices. +help.countries.new-users = The number of first-time users. #devices view -help.devices.chart = Pie chart on the left shows percentage of total users from each device (unique device percentages). Pie chart on the right shows percentage of first time users from each device. -help.devices.platform-versions2 = Shows at most top three platform versions represented by different colors according to the number of sessions from each platform version. Hover on each color to see the platform version. +help.devices.chart = The pie chart on the left shows the percentage of total users from each device (unique device percentages). The pie chart on the right shows the percentage of first-time users from each device. +help.devices.platform-versions2 = Shows at most the top three platform versions represented by different colors according to the number of sessions from each platform version. Hover over each color to see the platform version. #loyalty view -help.loyalty.chart = Total number of users from each session count segment (1, 2, 3-5, 6-9, 10-19, 20-49, 50-99, 100-499, > 500) is visualized using a bar chart. -help.loyalty.table = Session Count\: Session count segment. User is categorized into one of 1, 2, 3-5, 6-9, 10-19, 20-49, 50-99, 100-499, > 500 according to his total session count.
      Number of Users\: Number of users (unique devices) that are in a particular session count segment.
      Percent\: Percentage of users that are in a particular session count segment.
      +help.loyalty.chart = The total number of users from each session count segment (1, 2, 3-5, 6-9, 10-19, 20-49, 50-99, 100-499, > 500) is visualized using a bar chart. +help.loyalty.table = Session Count: Session count segment. A user is categorized into one of 1, 2, 3-5, 6-9, 10-19, 20-49, 50-99, 100-499, > 500 according to their total session count.
      Number of Users: The number of users (unique devices) that are in a particular session count segment.
      Percent: The percentage of users that are in a particular session count segment.
      #frequency view -help.frequency.chart = Total number of users from each session frequency segment (First session, 1-24 hours, 1 day, 2 days, 3 days, 4 days, 5 days, 6 days, 7 days, 8-14 days, 15-30 days, 30+ days) is visualized using a bar chart. -help.frequency.table = Time after previous session\: Time between users' consequent sessions. User is categorized into one of First session, 1-24 hours, 1 day, 2 days, 3 days, 4 days, 5 days, 6 days, 7 days, 8-14 days, 15-30 days or 30+ days according to his session frequency.
      Number of Users\: Number of users (unique devices) in this session frequency segment.
      Percent\: Percentage of users in this session frequency segment.
      +help.frequency.chart = The total number of users from each session frequency segment (First session, 1-24 hours, 1 day, 2 days, 3 days, 4 days, 5 days, 6 days, 7 days, 8-14 days, 15-30 days, 30+ days) is visualized using a bar chart. +help.frequency.table = Time after previous session: Time between users' consequent sessions. A user is categorized into one of First session, 1-24 hours, 1 day, 2 days, 3 days, 4 days, 5 days, 6 days, 7 days, 8-14 days, 15-30 days or 30+ days according to their session frequency.
      Number of Users: Number of users (unique devices) in this session frequency segment.
      Percent: Percentage of users in this session frequency segment.
      #platforms view help.platform-versions.chart = Pie chart on the left shows percentage of total users from each platform. Pie chart on the right shows percentage of total users from each platform version. You can toggle between iOS and Android to see distribution of platform versions (Toggle button will appear only if there is more than one platform) @@ -84,10 +84,10 @@ help.device_type.chart = Pie chart on the left shows percentage of total users f #session durations view help.durations.chart = Total number of users from each session duration segment (0-10 seconds, 11-30 seconds, 31-60 seconds, 1-3 minutes, 3-10 minutes, 10-30 minutes, 30-60 minutes or > 1 hour) is visualized using a bar chart. -help.durations.table = Session duration\: User is categorized into one of 0-10 seconds, 11-30 seconds, 31-60 seconds, 1-3 minutes, 3-10 minutes, 10-30 minutes, 30-60 minutes or > 1 hour according to his session duration.
      Number of Users\: Number of users (unique devices) in this session duration segment.
      Percent\: Percentage of users in this session duration segment.
      +help.durations.table = Session duration: A user is categorized into one of 0-10 seconds, 11-30 seconds, 31-60 seconds, 1-3 minutes, 3-10 minutes, 10-30 minutes, 30-60 minutes or > 1 hour according to their session duration.
      Number of Users: Number of users (unique devices) in this session duration segment.
      Percent: Percentage of users in this session duration segment.
      #push help.manage-apps.push-apn-certificate = Certificate file for Apple Push Notification (APN) service. In order to send Push Notifications, you need to supply at least one .PK12 file for this app. -help.manage-apps.push-gcm-key = Server API Key for Google Cloud Messaging (GCM) service. It's required if you're going to send messages to your Android app users from Countly. You can get one from Google API Console. +help.manage-apps.push-gcm-key = Server API Key for Google Cloud Messaging (GCM) service. It is required if you're going to send messages to your Android app users from Countly. You can get one from the Google API Console. help.datatables-export = Only visible data will be downloaded diff --git a/frontend/express/public/localization/mail/mail.properties b/frontend/express/public/localization/mail/mail.properties index 4057182d877..edcff97a9d0 100644 --- a/frontend/express/public/localization/mail/mail.properties +++ b/frontend/express/public/localization/mail/mail.properties @@ -1,10 +1,10 @@ #mail templates mail.new-member-subject = Your Countly Account -mail.new-member = Hi {0},

      Your Countly account on
      {1} is created with the following details;

      Username: {2}
      Password: {3}

      Enjoy,
      A fellow Countly Admin -mail.new-member-prid = Hi {0},

      Your Countly account on {1} is created with the following details;

      Username: {2}
      You can set up your password following this link.
      Enjoy,
      A fellow Countly Admin +mail.new-member = Hi {0},

      Your Countly account on {1} has been created with the following details:

      Username: {2}
      Password: {3}

      Enjoy,
      A fellow Countly Admin +mail.new-member-prid = Hi {0},

      Your Countly account on {1} has been created with the following details:

      Username: {2}
      You can set up your password by following this link.
      Enjoy,
      A fellow Countly Admin mail.password-change-subject = Countly Account - Password Change -mail.password-change = Hi {0},

      Your password for your Countly account on {1} has been changed. Below you can find your updated account details;

      Username: {2}
      Password: {3}

      Best,
      A fellow Countly Admin +mail.password-change = Hi {0},

      Your password for your Countly account on {1} has been changed. Below you can find your updated account details:

      Username: {2}
      Password: {3}

      Best,
      A fellow Countly Admin mail.password-reset-subject = Countly Account - Password Reset -mail.password-reset = Hi {0},

      You can reset your Countly account password by following this link.

      If you did not request to reset your password ignore this email.

      Best,
      A fellow Countly Admin +mail.password-reset = Hi {0},

      You can reset your Countly account password by following this link.

      If you did not request to reset your password, please ignore this email.

      Best,
      A fellow Countly Admin mail.time-ban-subject = {0}: Your account is locked -mail.time-ban = Hi {0},

      Due to excess number of failed login attempts, your account has been blocked. You can use this link to unlock your user and login to your dashboard for once.

      Best
      A fellow admin \ No newline at end of file +mail.time-ban = Hi {0},

      Due to an excessive number of failed login attempts, your account has been blocked. You can use this link to unlock your user and log in to your dashboard once.

      Best,
      A fellow admin \ No newline at end of file diff --git a/frontend/express/public/localization/pre-login/pre-login.properties b/frontend/express/public/localization/pre-login/pre-login.properties index f5b1430dcde..8605a441361 100644 --- a/frontend/express/public/localization/pre-login/pre-login.properties +++ b/frontend/express/public/localization/pre-login/pre-login.properties @@ -13,10 +13,10 @@ placeholder.enter-password = Enter your password login.title = Login login.forgot = Forgot password? login.result = Login Failed -login.blocked = Your account was locked due to too many incorrect login attempts. Please wait for a while or contact with your system admin. -login.locked = Your account was locked by admin +login.blocked = Your account has been locked due to too many incorrect login attempts. Please wait for a while or contact your system admin. +login.locked = Your account has been locked by an admin. login.button = Sign In -login.token-expired = Your session was expired. Please login again +login.token-expired = Your session has expired. Please log in again. login.email-adress = Email Address login.email-adress-or-username = Username or E-mail address login.sign-in = or Sign In With Your Email @@ -35,15 +35,15 @@ forgot.explanation = Please enter your account email below in order to receive i forgot.result = You will receive an email shortly if the email you entered exists in the system forgot.button = Send Email forgot.invalid-email = Invalid email address format. -forgot.error = Somethings went wrong. Please try again later. +forgot.error = Something went wrong. Please try again later. forgot.sent-email-title = Password Reset Email Sent forgot.sent-email = An email has been sent to your email address, {0}. Follow the directions in the email to reset your password. #reset reset.explanation = Create your new account password below. -reset.result = You can login with your new password\! +reset.result = You can log in with your new password! reset.invalid = Invalid password reset request -reset.dont-match = Passwords don't match\! +reset.dont-match = Passwords do not match! reset.confirm-password = Confirm Password reset.new-password = New Password reset.button = Reset my password @@ -61,17 +61,17 @@ management-users.full_name.invalid = Must provide full name setup.title = Registration setup.full-name = Full Name setup.username = Username -setup.explanation = You have succesfully setup Countly on your server. You just need to create your administrator account in order to complete the installation. +setup.explanation = You have successfully set up Countly on your server. You just need to create your administrator account to complete the installation. setup.button = Create Account -setup.hint-password-good=Your password is good to go\! +setup.hint-password-good=Your password is good to go! setup.error-username = Please enter a valid username. setup.error-full-name = Please enter a valid full name. -setup.error-email = Please enter a valid email adress. -setup.error-confirm-password = Confirmation password has to be the same as password. +setup.error-email = Please enter a valid email address. +setup.error-confirm-password = The confirmation password has to be the same as the password. setup.ready = Your Countly server is ready! setup.byline = Let's first create your dashboard user account setup.continue-demo-app = Continue with a demo app setup.continue-own-app = I want to create my own app #logout -logout.inactivity = You have been logged out due to inactivity +logout.inactivity = You have been logged out due to inactivity. diff --git a/frontend/express/public/stylesheets/amaranjs/amaran.min.css b/frontend/express/public/stylesheets/amaranjs/amaran.min.css deleted file mode 100644 index 4f43b034960..00000000000 --- a/frontend/express/public/stylesheets/amaranjs/amaran.min.css +++ /dev/null @@ -1,31 +0,0 @@ -.amaran-wrapper * { box-sizing: border-box; } -.amaran-wrapper { position: fixed; z-index: 10000000; } -.amaran-wrapper.top { top: 0; bottom: auto; } -.amaran-wrapper.bottom { bottom: 0; top: auto; } -.amaran-wrapper.left { left: 0; } -.amaran-wrapper.right { right: 0; left: auto; } -.amaran-wrapper.center { width: 50%; height: 50%; margin: auto; position: fixed; top: 0; left: 0; bottom: 0; right: 0; } - -.amaran { width: 200px; background: rgba(0, 0, 0, 0.7); padding: 3px; color: #fff; border-radius: 4px; display: none; font-size: 13px; cursor: pointer; position: relative; text-align: left; min-height: 50px; margin: 10px; } -.amaran-close { position: absolute; top: 5px; right: 0; display: block; width: 20px; height: 20px; cursor: pointer; } -.amaran-close:before { content: "✕"; color: #999; font-weight: bold; font-family: Arial, sans-serif; font-size: 14px; } - -.amaran-sticky { position: absolute; top: 2px; right: 20px; display: block; width: 20px; height: 20px; cursor: pointer; } -.amaran-sticky:before { content: "●"; color: #fff; font-weight: bold; font-family: Arial, sans-serif; font-size: 18px; } -.amaran-sticky.sticky:before { color: #27ae60; } - -.amaran.awesome { width: 320px; min-height: 65px; background: #FFF; border:none; color: #222; margin: 15px; padding: 20px 20px 20px 70px; font-family: "Open Sans", Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 600; box-shadow: 0 1px 7px 0 rgba(93, 93, 93, 0.5); } -.amaran.awesome .icon { width: 50px; height: 50px; position: absolute; top: 10px; left: 10px; background: transparent; border-radius: 50%; text-align: center; line-height: 50px; font-size: 31px; } -.amaran.awesome p { padding: 0; margin: 0; } -.amaran.awesome p span { font-weight: 300; font-size:14px; line-height: 19px; display: block; margin-top:8px; } -.amaran.awesome p span.light { font-size: 13px; line-height: 13px; display: block; color: #777; margin-top:12px; } -.amaran.awesome p span.light:empty { margin:0; } -.amaran.awesome.ok p.bold { color:#252525; } - -.amaran.awesome.ok .icon, -.amaran.awesome.green .icon { color: #2FA732; } -.amaran.awesome.error .icon { color: #D82222; } -.amaran.awesome.warning .icon { color: #f59226; } -.amaran.awesome.yellow .icon { color: #CFA846; } -.amaran.awesome.blue .icon { color: #2980b9; } -.amaran.awesome.purple .icon { color: #5B54AA; } \ No newline at end of file diff --git a/frontend/express/public/stylesheets/amaranjs/animate.min.css b/frontend/express/public/stylesheets/amaranjs/animate.min.css deleted file mode 100644 index 444ecefbd91..00000000000 --- a/frontend/express/public/stylesheets/amaranjs/animate.min.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! -Animate.css - http://daneden.me/animate -Licensed under the MIT license - http://opensource.org/licenses/MIT - -Copyright (c) 2014 Daniel Eden -*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}@-webkit-keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);-ms-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);-ms-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);-ms-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;-ms-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);-ms-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);-ms-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);-ms-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);-ms-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);-ms-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);-ms-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);-ms-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);-ms-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);-ms-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);-ms-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);-ms-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);-ms-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);-ms-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;-ms-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{0%{-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);-ms-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);-ms-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);-ms-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;-ms-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);-ms-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);-ms-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);-ms-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);-ms-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);-ms-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;-ms-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);-ms-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);-ms-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);-ms-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);-ms-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn;-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);-ms-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);-ms-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);-ms-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);-ms-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;-ms-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);-ms-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);-ms-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);-ms-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);-ms-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;-ms-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);-ms-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);-ms-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);-ms-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);-ms-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;-ms-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);-ms-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);-ms-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);-ms-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);-ms-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);-ms-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);-ms-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);-ms-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);-ms-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);-ms-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);-ms-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);-ms-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);-ms-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);-ms-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);-ms-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);-ms-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);-ms-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);-ms-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);-ms-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);-ms-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);-ms-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);-ms-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);-ms-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);-ms-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);-ms-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);-ms-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-ms-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-ms-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);-ms-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);-ms-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;-ms-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);-ms-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);-ms-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);-ms-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);-ms-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);-ms-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);-ms-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);-ms-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);-ms-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);-ms-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);-ms-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);-ms-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);-ms-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);-ms-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);-ms-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);-ms-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);-ms-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY;-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);-ms-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);-ms-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);-ms-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;-ms-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);-ms-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;-ms-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);-ms-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;-ms-transform-origin:center;transform-origin:center;-webkit-transform:none;-ms-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);-ms-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;-ms-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);-ms-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;-ms-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);-ms-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;-ms-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);-ms-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;-ms-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;-ms-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;-ms-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);-ms-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);-ms-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);-ms-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);-ms-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);-ms-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);-ms-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);-ms-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);-ms-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);-ms-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;-ms-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);-ms-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-ms-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-ms-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-ms-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-ms-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-ms-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-ms-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-ms-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-ms-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-ms-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-ms-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;-ms-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);-ms-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);-ms-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;-ms-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);-ms-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);-ms-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;-ms-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-ms-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-ms-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;-ms-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp} \ No newline at end of file diff --git a/frontend/express/public/stylesheets/countly-checkbox/countly.checkbox.css b/frontend/express/public/stylesheets/countly-checkbox/countly.checkbox.css deleted file mode 100644 index c4f08b000e8..00000000000 --- a/frontend/express/public/stylesheets/countly-checkbox/countly.checkbox.css +++ /dev/null @@ -1,36 +0,0 @@ -.countly-checkbox-native { - position: relative; - top: -15px; - left: -5px; - opacity: 0; - cursor: pointer; -} -.countly-checkbox-wrapper { - height: 11px; - width: 11px; - border:1px solid #d0d0d0; - border-radius: 2px; - background-color: white; - text-align: center; - cursor: pointer; -} -.countly-checkbox-checked { - background-color: #2FA732; - border:1px solid #2FA732; -} -.countly-checkbox-icon { - position: relative; - color: white; - font-size:10px; - top: -1px; - opacity: 0; -} -.countly-checkbox-label { - position: relative; - top: -13px; - left: -5px; -} -.countly-checkbox-disabled { - background-color: #2fa73273; - border: 1px solid transparent; -} \ No newline at end of file diff --git a/frontend/express/public/stylesheets/main.css b/frontend/express/public/stylesheets/main.css index 1fd73c0a134..b94c7f89df5 100644 --- a/frontend/express/public/stylesheets/main.css +++ b/frontend/express/public/stylesheets/main.css @@ -162,21 +162,12 @@ src: url('../fonts/Oswald-700/Oswald-700.eot?#iefix') format('embedded-opentype' html { height: 100%; } body { margin:0; padding:0; overflow:auto; background-color:#F9F9F9; user-select:text; font-family: Ubuntu,Helvetica,sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* #content-container { margin-left:224px; min-width:768px; min-height: 400px; padding:78px 16px 35px 16px !important; transition: margin-left 0.55s; will-change: margin-left; } */ -#content-container #event-nav, -#content-container #app-management-bar, -#content-container #configs-title-bar { transition: left 0.55s, width 200ms; will-change: left; border-radius:2px; } -#content-container.cover-left { margin-left: 0!important; transition: margin-left 0.55s; will-change: margin-left; } -#content-container.cover-left #event-nav, -#content-container.cover-left #app-management-bar, -#content-container.cover-left #configs-title-bar { left:18px; transition: left 0.55s, width 200ms; will-change: left; } /* #content {padding-bottom:15px; } */ a { color:inherit; text-decoration:none; } a:visited { color:inherit; } a:hover { color:inherit; } a:active { color:inherit; } -#app-tooltip{display: none; position: absolute; z-index: 1000; background-color: #CCC; height: 45px; margin-left:5px;} -#app-tooltip .app-container{padding-left:11px;} .break {word-wrap: break-word; word-break: break-all;} .trim {text-overflow: ellipsis; overflow:hidden; white-space: nowrap;} .over {z-index:100;} @@ -192,36 +183,12 @@ table { border-collapse: collapse; } @keyframes flash { 0% { background-color:none;} 30% { background-color:#ddf3dd;} 100% {background-color:none;} } /* FOOTER */ -#content-footer{position: fixed; bottom:0; left:0px; width: 100%; background-color: #292929; font: 11px Ubuntu,Helvetica,sans-serif; color: #585858; height: 35px; z-index:999;} -#content-footer span{float: left; line-height: 35px; margin-left:10px; text-align:left; } -#content-footer ul {list-style: none; float: right; margin: 0; padding: 0; margin-right: 10px;} -#content-footer ul li{float: left; margin-right: 7px; margin-left: 7px; line-height: 35px;} -#content-footer ul li a { transition:color 1s; cursor: pointer; } -#content-footer ul li a:hover { color:#2FA732; transition:color 1s; } /* SIDEBAR */ #sidebar { position:fixed; left:0; width:224px; background-color:#0B131A; height:100%; z-index:998; user-select:none; } -#sidebar-top { display: none; height:112px; padding-top:11px; border-right:1px solid #ABABAB; -/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#e6e6e6+0,adacac+100 */ -background: #e6e6e6; /* Old browsers */ -background: -moz-linear-gradient(top, #e6e6e6 0%, #adacac 100%); /* FF3.6-15 */ -background: -webkit-linear-gradient(top, #e6e6e6 0%,#adacac 100%); /* Chrome10-25,Safari5.1-6 */ -background: linear-gradient(to bottom, #e6e6e6 0%,#adacac 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ -filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e6e6e6', endColorstr='#adacac',GradientType=0 ); /* IE6-9 */ -border-bottom: 1px solid #888; -} #sidebar-menu { position: relative; margin-top:59px; } -.scroll-active .sidebar-menu { height:auto; position:relative; } .sidebar-menu{padding-bottom:120px;} -#sidebar-menu .sidebar-menu .menu-category-title{padding-left:16px; padding-right:15px; padding-top:16px; font:12px Ubuntu,Helvetica,sans-serif; color:#9F9F9F; width: 195px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; display:block; text-transform: uppercase; padding-bottom: 5px;} -#sidebar-menu .sidebar-menu .menu-category-title.active, #sidebar-menu .sidebar-menu .menu-category:hover .menu-category-title{color: #FFF;} -#sidebar-menu .sidebar-menu .menu-category .menu-category-title:hover {color:#9F9F9F; } -#sidebar-menu .sidebar-menu .menu-category .menu-category-title.active:hover {color: #FFF; } -#sidebar-menu .sidebar-menu .menu-category>.item { width:225px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; height:26px; padding-top:3px; display:block; cursor:pointer; } - #sidebar-menu .sidebar-menu .menu-category>.item.hide { display: none; } #sidebar-menu .sidebar-menu .item:hover { background-position:446px; } - #sidebar-menu .sidebar-menu .menu-category>.item.active { background-color: #2FA732; border-color: #2FA732; } - #sidebar-menu .sidebar-menu .item.menu-active { background-color: #02060B; border-color: #02060B } #sidebar-menu .sidebar-menu .item .logo { color:#9F9F9F; width:25px; height:22px; float:left; margin-left:16px; margin-top:2px; font-size: 18px; text-align: center; } #sidebar-menu .sidebar-menu .item .logo .material-icons { font-size:19px; margin-top:1px; } /* Fix for old .fa icons, this can be removed once all enterprise plugins have updated icons */ @@ -232,40 +199,12 @@ border-bottom: 1px solid #888; font-size: 18px !important; margin-left: 17px !important; } - #sidebar-menu .sidebar-menu .menu-category>.item>.logo-icon { background-image:none; font-size:24px; text-align:center; padding-top:4px; width: 35px; margin-left: 14px; line-height: 34px; } #sidebar-menu .sidebar-menu .item.active .logo { color:#FFF; } #sidebar-menu .sidebar-menu .item .text { margin-left:15px; float:left; padding-top:3px; font:14px Ubuntu,Helvetica,sans-serif; line-height:130%; color:#9F9F9F; max-width: 140px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } #sidebar-menu .sidebar-menu .item.active:hover .logo { color: #f6f6f6; } - #sidebar-menu .sidebar-menu .item.menu-active:hover .logo, - #sidebar-menu .sidebar-menu .item.menu-active .logo { color: #f6f6f6; } #sidebar-menu .sidebar-menu .item:hover .logo { color: #FFF; } #sidebar-menu .sidebar-menu .item:hover .text { color: #FFF; } - #sidebar-menu .sidebar-menu .item:hover .ion-chevron-right { color: #FFF; } #sidebar-menu .sidebar-menu .item.active .text { color:#FFF; } - #sidebar-menu .sidebar-menu .item .ion-chevron-right { position: absolute; right: 15px; font-size: 10px; color: #505050; padding-top: 7px; } - #sidebar-menu .sidebar-menu .item.active .ion-chevron-right { color:#f6f6f6; } - -#sidebar-menu .sidebar-menu .sidebar-submenu { display:none; position:absolute; top:0; background-color: #02060B; right:0; width:175px; height:100%; z-index:1; } - #sidebar-menu .sidebar-menu .sidebar-submenu .menu-title { min-height:16px; padding: 14px 0 15px 25px; color: #ececec; font-family: Ubuntu; font-size: 14px; } - #sidebar-menu .sidebar-menu .sidebar-submenu .submenu-close { right: 18px; position: absolute; top: 14px; font-size: 14px; cursor: pointer; opacity: 0.7; } - #sidebar-menu .sidebar-menu .sidebar-submenu .submenu-close:hover { opacity: 1; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item, - #sidebar-menu .sidebar-menu .sidebar-submenu .disabled-item { text-transform:capitalize; background-color: #02060B; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; height:30px; display:block; padding-left:8px; cursor:pointer; } - #sidebar-menu .sidebar-menu .sidebar-submenu .disabled-item { cursor:default; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item .logo-icon { display:none; color:#888; width:30px; height:30px; float:left; margin-left:8px; margin-top:8px; text-align:center;} - #sidebar-menu .sidebar-menu .sidebar-submenu .item .logo { display:none; color:#888; width:30px; height:30px; float:left; margin-left:8px; margin-top:1px; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item.active .logo, - #sidebar-menu .sidebar-menu .sidebar-submenu .item.active .logo-icon { color:#2FA732; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item .text { margin-left:17px; float:left; padding-top:8px; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#888; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item:hover .text { color: #FFF; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item.active .text { color:#2FA732; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item.active:hover .text { opacity:1; } - #sidebar-menu .sidebar-menu .sidebar-submenu .item:last-child { background-image:none; margin-bottom: 120px;} - #sidebar-menu .sidebar-menu .sidebar-submenu .item.help-toggle.active { color:#666; } - - #management-submenu.sidebar-submenu .disabled-item { opacity:0.3; } - #management-submenu.sidebar-submenu .disabled-item .logo { width:30px; height:30px; float:left; margin-left:8px; margin-top:1px; } - #management-submenu.sidebar-submenu .disabled-item .text { margin-left:17px; float:left; padding-top:8px; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#666; } @media only screen and (max-height: 800px) { #sidebar-menu .sidebar-menu .item .logo { width:25px; height:22px; float:left; margin-left:16px; margin-top:3px; font-size: 16px; } @@ -277,34 +216,12 @@ border-bottom: 1px solid #888; font-size: 16px !important; margin-left: 17px !important; } -#sidebar-menu .sidebar-menu .menu-category>.item>.logo-icon { background-image:none; font-size:22px; text-align:center; padding-top:5px; width: 35px; margin-left: 14px; line-height: 34px; } -} -@media only screen and (min-height: 801px) { -#sidebar-menu .sidebar-menu .menu-category>.item { - padding-top: 5px; - padding-bottom: 2px; } -#sidebar-menu .sidebar-menu .menu-category-title{padding-bottom: 10px;} -} - -#sidebar-event-count { float:right; border-radius:15px; font-family:Oswald; font-size:13px; color:#DDD; background-color:#333; border:1px solid #0C0C0C; box-shadow:0 1px 1px 0 #4A4A4A, inset 0 1px 1px 0 #1f1f1f; padding:2px 6px; margin:7px 10px 0 0; } -.item.active #sidebar-event-count { border-color:#6BB96E; box-shadow:0 0 1px 0 #ACE7B1, inset 0 1px 1px 0 #1f1f1f; } /* SIDEBAR END */ /* DASHBOARD */ -#dashboard-graph, -#dashboard-graph-secondary { font-family:Oswald; font-size:14px; margin:0 30px !important; } -#dashboard-graph .legendLabel,.graph .legendLabel { font-family:Ubuntu !important; font-size:14px !important; } - -.usparkline, .dsparkline {display: none;} - -.graph-no-data { display:none; height:100%; position:relative; } - .graph-no-data .inner { user-select:none; text-align: center; position: absolute; width: 400px; left: 50%; margin-left: -200px; height: 64px; margin-top: -40px; top: 50%;} - .graph-no-data .inner .icon { display: inline-block; width: 60px; height: 60px; background-image: url("../images/dashboard/graph-no-data.svg"); background-size: contain; margin-right: 20px; background-repeat: no-repeat; } - .graph-no-data .inner .text { cursor:default; display: inline-block; color: #a2a2a2; vertical-align: text-bottom; margin-bottom: 23px; font-size: 16px; } .widget { margin-bottom:16px; border-radius:2px; } -.widget-no-shadow { box-shadow: none; } .widget-header { height:41px; position:relative; padding:8px 8px; color:#666; font-size:13px; border-top-left-radius:2px; border-top-right-radius:2px; border:1px solid #D0D0D0; border-bottom:none; background-color:#ECECEC; } .widget-header .left { float:left; margin-top:2px; margin-left:2px; } .widget-header .right { float:right; margin-right:2px; } @@ -313,16 +230,7 @@ border-bottom: 1px solid #888; .widget-header .back { font:16px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#636363; margin-right: 10px;} .widget-header .left .title { font:19px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#636363; float:left; padding-top:8px; float:left; margin-left:3px; text-transform: uppercase; } .widget-header .left .title.small { font-size:16px; padding-top: 0; } - .widget-header .left .title.dynamic-title { max-width: 700px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} - @media (min-width: 1601px) and (max-width: 1700px) { .widget-header .left .title.dynamic-title {max-width: 500px;} } - @media (min-width: 1401px) and (max-width: 1600px) { .widget-header .left .title.dynamic-title {max-width: 400px;} } - @media (min-width: 1301px) and (max-width: 1400px) { .widget-header .left .title.dynamic-title {max-width: 300px;} } - @media (min-width: 1101px) and (max-width: 1300px) { .widget-header .left .title.dynamic-title {max-width: 250px;} } - @media (max-width: 1100px) { .widget-header .left .title.dynamic-title {max-width: 100px;} } .widget-header .logo { float:left; width:38px; height:38px; } - .widget-header .logo.font-logo { color:#6E6E6E; background-image: none; height:31px; font-size: 25px; padding-top: 5px; text-align: center; } - .widget-header .logo.font-logo2 { color:#6E6E6E; background-image: none; height:31px; font-size: 25px; text-align: center; padding-top: 4px; } - .widget-header .logo.font-logo>a { line-height: 10px; } .widget-header .logo.sessions { background-position:-38px; } .widget-header .logo.frequency { background-position:-76px; } .widget-header .logo.countries { background-position:-114px; } @@ -335,162 +243,26 @@ border-bottom: 1px solid #888; .widget-header .logo.resolutions { background-position:-418px; } .widget-header .logo.densities { background-position:-456px; } .widget-tips { display:none; background-color: #f9f9f9; padding: 10px 14px; color: #868686; font-size: 13px; border: 1px solid #d0d0d0; border-bottom-color: #e9e9e9;overflow: auto;} -.widget-footer { text-align:right; min-height:10px; color:#666; font-size:11px; border-bottom-left-radius:2px; border-bottom-right-radius:2px; border:1px solid #D0D0D0; border-top:none; background-color:#FFF; box-shadow:inset 0 1px 0 #FFF; overflow:hidden; } - .widget.google-disabled .widget-footer { border-top:2px solid #D0D0D0; } .widget-content { background-color:#FFF; border:1px solid #D0D0D0; } - .widget.google-disabled .widget-content { display: none; } -.fix-two-columns { position:relative; } - -.widget-group { border:1px solid #D0D0D0; margin-bottom: 16px; border-radius:2px; } -.widget-group .dashboard-summary { margin:0; border-top:1px solid #d0d0d0; } -.widget-group .big-numbers.top.widgets .inner, -.widget-group .dashboard-summary .item .inner { border-radius:0; margin-left:0; box-shadow: none !important; border-left: 1px solid #D0D0D0; padding:10px 15px; } -.widget-group .big-numbers.top.widgets:first-child .inner, -.widget-group .dashboard-summary .item:first-child .inner { margin-left:0; border:none; } -.widget.segmentation-widget {margin-bottom: 0px;} -.segmentation-table #dataTableTwo_wrapper {margin-top: 0px; overflow: auto; position: relative;} - -#big-numbers-container, .big-numbers-container, -#intermediate-numbers-container { overflow:hidden; position:relative; } -#big-numbers-container.dashboard , .big-numbers-container.dashboard { border:1px solid #D0D0D0; border-bottom:none; padding-bottom:8px; } - .big-numbers { float:left; position:relative; } - .widget-footer .big-numbers:first-child .inner { border-bottom-left-radius:2px; } - .widget-footer .big-numbers:last-child .inner { border-bottom-right-radius:2px; } - .big-numbers .inner { border-left:1px solid #D0D0D0; border-bottom:1px solid #D0D0D0; background-color:#F9F9F9; height:180px; text-align:center; } - .widget-content .big-numbers .inner { height:190px; cursor:pointer; } - .widget-footer .big-numbers .inner { height:100px; border-bottom:none; background-color:#f4f4f4; } - .big-numbers.active .inner { background-color:#FFF; } - .big-numbers:first-child .inner { border-left:none; } - .big-numbers:last-child { position:absolute; right:0; border-left:none; } - .big-numbers .select { padding-top:7px; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#5B5B5B; position:absolute; height:23px; width:100%; background-color:#D6D6D6; box-shadow:inset 0 1px 0 #F6F6F6; } - .big-numbers .select .title { max-width:156px; overflow:hidden; text-overflow:ellipsis; margin:0 auto; white-space:nowrap; } - .widget-content .big-numbers .select { bottom:1px; border-top:1px solid #A1A2A2; cursor:pointer; } - .widget-footer .big-numbers .select { top:0; border-bottom:1px solid #A1A2A2; position:relative; } - .big-numbers.active .select { color:#EEE; background-color:#2B2B2B; box-shadow:inset 0 1px 0 #5E5E5E; border-top-color:#404040; border-bottom:1px solid #616161; bottom:0; } - .big-numbers .inner .logo { width:60px; height:60px; margin:0 auto; } - .big-numbers .number { font:30px Oswald; color:#666; } - .widget-content .big-numbers .number { margin-top:1px; } - .widget-footer .big-numbers .number { margin-top:7px; } - .big-numbers.active .number { color:#333; } - .big-numbers .arrow { display:none; width:18px; height:8px; position:absolute; left:50%; z-index:2; margin-left:-9px; bottom:-6px; } - .big-numbers.active .arrow { display:block; } - .big-numbers .spark { margin-top:11px; } - .big-numbers .color { height:5px; } /*.big-numbers:nth-child(1) .color { background-color:#52A3EF; } .big-numbers:nth-child(2) .color { background-color:#FF8700; } .big-numbers:nth-child(3) .color { background-color:#0EC1B9; } */ - .widget-content .big-numbers .trend { width:12px; height:9px; right:7%; top:11px; position:absolute; } - .widget-footer .big-numbers .trend { width:12px; height:9px; right:20px; top:62px; position:absolute; } - .widget-footer .big-numbers .check {width: 12px; height: 9px; left: 20px; top: 57px; position: absolute; font-size: 19px; color: #bbb;} - .widget-content .big-numbers .change { right:15px; white-space:nowrap; top:-1px; position:absolute; font:10px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#999; } - .big-numbers.active .change { color:#333; } - - .map-list { background-image:url('../images/dashboard/map_dotted_bg.png'); background-color:#FFF; height:400px; border:1px solid #D0D0D0; position: relative;} #geo-chart { display: inline-block; } - #geo-chart-outer { border-radius:7px; text-align: center; margin-top: 25px; float:left; width:70% } - #geo-chart-outer.big { float: none; margin: 0 auto; margin-top: 25px; width: auto; } - #map-list-right { float:left; margin-top: 20px; width:30%; height:330px; overflow:hidden; } - #geo-chart-outer.empty { width: 100%; } - #geo-chart-outer.empty + #map-list-right { display: none; } - - .data-type-selector-group .big-numbers.top .inner { height: 30px; } - - .geo-switch .cly-button-group {position: absolute; top:0px; left:0px;} - .geo-switch .cly-button-group .icon-button:first-child{border-bottom-left-radius:0; border-top-left-radius:0px; border-left:none;} - .geo-switch .cly-button-group .icon-button:last-child { border-top-right-radius:0; border-bottom-right-radius:0; } - .geo-switch .cly-button-group .icon-button{border-top:none;} - - .map-list-item { overflow:hidden; padding: 5px 25px 5px 1px; } .flag { float:left; width:16px; height:11px; border-radius:2px; box-shadow:0 0 1px 0 #333; margin-top:1px; margin-right:10px; background-image:url('../images/flags/tr.png'); background-repeat: no-repeat; } .flag.ch { width:11px !important; margin-right:15px; } .flag.me { width:16px !important; height:12px !important; } .flag.np { width:9px !important; background-position:0 0; margin-right:17px; } - .map-list-item .flag { margin-top:6px; } - .map-list-item:hover .flag {} - .map-list-item .total { float:right; color:#646464; font:17px Oswald; margin-right:10px; line-height:23px; } - .map-list .country-name { width:128px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; float:left; color:#646464; font-size:15px; line-height:23px; } - .map-list .bar { float:left; margin-left:10px; height:15px; margin-top:2px; background-color:#333; } - #country-toggle {font-size:12px; padding: 7px;} .graph { font:14px Oswald; z-index:1; } .graph table tr:nth-child(n+10){ display:none; } - .pie-chart-container { float:left; width:50%; position:relative; height:360px; } - .pie-chart-container .graph-segment-container { position:absolute; left:10px; top:10px; z-index:3; } - .pie-overlay { position: absolute; z-index: 1; width: 225px; height: 225px; left: 50%; margin-left: -115px; top: 66px; border: 2px solid #e6e6e6; border-radius: 200px; } - .pie-overlay .title { font-size:11px; color:#969696; margin:0 auto; text-align:center; margin-top:8px; max-width:100px; line-height:17px; } - .pie-overlay .logo { color:#969696; margin:0 auto; text-align:center; margin-top:79px; font-size: 40px; width: 100%; } - .pieLabel { max-width: 100px; } - .pieLabel div { font-size:10px !important; } - -.big-numbers.top .inner { height:170px; cursor:pointer; } -.big-numbers.top .select { bottom:1px; cursor:pointer; padding-top:7px; font-size:12px; line-height:111%; color:#969696; position:absolute; height:23px; width:100%; background-color: transparent !important; background-image: none !important; box-shadow: none; border:none; } -.big-numbers.top .select.large { height: 29px; } - .big-numbers.top .select.large .title { font-size:12px; } -.big-numbers.top.active .select { border-bottom:1px solid #FFF; bottom:0; } -.big-numbers.top .inner .logo { margin:0 auto; font-size: 30px; line-height: 30px; width: 30px; height: 30px; padding-top: 15px; margin-bottom: 10px; } -.big-numbers.top .inner .logo.ion { background-image:none; font-size: 30px; line-height: 30px; color: #969696; } -.big-numbers.top.active .inner .logo.ion { color: #535353; } -.big-numbers.top .inner .logo.material { background-image:none; } -.big-numbers.top .inner .logo.material .material-icons { font-size: 30px; line-height: 30px; color: #969696; } -.big-numbers.top.active .inner .logo.material .material-icons { color: #535353; } -.big-numbers.top .number { font:30px Oswald; color:#666; margin: 0; } -.big-numbers.top.active .number { color:#333; } -.big-numbers.top .title { padding-top:2px; padding-bottom:3px; font-size:10px; color:#666666; text-transform: uppercase; } -.big-numbers.top .spark { margin-top:14px; } -.big-numbers.top.active .spark { display: none; } -.big-numbers.top .trend { display: none; font-size:11px; margin-top:20px; position: relative; top:inherit; right: inherit; width: auto; height: auto; } -.big-numbers.top .trend .material-icons { font-size: 16px; vertical-align: middle; margin-right:5px; } -.big-numbers.top .trend.u, -.big-numbers.top .trend.u .change { color:#83C986 !important; } -.big-numbers.top .trend.d, -.big-numbers.top .trend.d .change { color:#DB6E6E !important; } -.big-numbers.top.active .trend { display: block; } -.big-numbers.top .change { display:inline-block; vertical-align: middle; position: relative; top:inherit; right: inherit; } - -.big-numbers.top.widgets { border:none; } -.big-numbers.top.widgets .inner { cursor:default; border:none; margin-left:5px; background-color: #FFF; box-shadow: inset 0 0 0 1px #D0D0D0; border-radius: 2px; padding:10px; height:66px; } -.big-numbers.top.widgets:first-child .inner { margin-left:0; } -.big-numbers.top.widgets.dark .inner { border:none; background-color: #3c3c3c; box-shadow: none; } -.big-numbers.top.widgets.dark .inner .number, -.big-numbers.top.widgets .inner .title { color:#484848; font-size:12px; padding-top: 8px; } -.big-numbers.top.widgets.dark .inner .title { color:#FFF; } /* DASHBOARD END */ /* NEW BIG NUMBERS */ -.big-numbers-v2 { margin-top: -1px; padding-top: 10px; border-color: #D0D0D0; } -.big-numbers-v2 #big-numbers-container, .big-numbers-v2 .big-numbers-container { margin: 0 auto; } -.big-numbers-v2 .big-numbers .inner { border-left: none; border-top: none; text-align: center; padding-top: 30px; background-color: #FFF; height: 100px; } -.big-numbers-v2.condensed .big-numbers .inner { padding-top: 10px; background-color: #FFF; height: 80px; } -.big-numbers-v2 .big-numbers:nth-child(1) .inner { border-left:none; } -.big-numbers-v2 .big-numbers .select { text-transform: uppercase; color: #484848; font-size:13px; border:none; box-shadow:none; background: transparent; display: inline-block; width: auto; padding-top: 0px; margin-left: 8px; vertical-align: top; height: auto; } -.big-numbers-v2 .big-numbers .color { display: inline-block; width:15px; height:15px; margin-top: 0; border-radius: 1px; } -.big-numbers-v2 .big-numbers.radio, -.big-numbers-v2 .big-numbers.check { cursor: pointer; } -.big-numbers-v2 .big-numbers.radio:hover, -.big-numbers-v2 .big-numbers.check:hover { opacity: 0.7; } -.big-numbers-v2 .big-numbers.radio .color, -.big-numbers-v2 .big-numbers.check .color { width:13px; height:13px; border-radius:20px; background-color: transparent; cursor:pointer; } -.big-numbers-v2 .big-numbers.check .color { border-radius:1px; } -.big-numbers-v2 .big-numbers.radio.selected .color, -.big-numbers-v2 .big-numbers.check.selected .color { box-shadow:inset 0 0 0 1px #FFF; cursor: default; } - - -.big-numbers-v2 .big-numbers .number { margin-top: 2px; color:#484848; font-size: 34px; } -.big-numbers-v2 .big-numbers .trend { margin-top:5px; height: auto; width: auto; top:0; right:0; position: relative; } -.big-numbers-v2 .big-numbers .trend i { font-size: 13px; } -.big-numbers-v2 .big-numbers .trend.u { color:#83C986; } -.big-numbers-v2 .big-numbers .trend.d { color:#DB6E6E; } - -.google-disabled .big-numbers.radio .color { display: none; } -.google-disabled .big-numbers.radio { cursor: default; } -.google-disabled .big-numbers.radio:hover { opacity: 1; } - /* APP NAVIGATION */ #app-management-bar { z-index:3; border-radius: 2px; } #app-management-bar #app-nav-head { padding-left:15px; } #app-nav-title { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:85px; float:left; padding-top:4px; } -#app-nav { width:190px; display:none; text-align:right; height:100%; position:fixed; left:31px; z-index:997; padding-bottom: 120px; box-sizing: border-box; box-shadow: inset -1px 0 0 0 #d4d4d4; background-color: rgba(239, 239, 239, 0.7); } #app-nav-head { height:27px; padding:15px 20px 15px 15px; color:#636363; font:18px Ubuntu,Helvetica,sans-serif; line-height:111%; text-align:left; background-color: #ECECEC; border-bottom:1px solid #d0d0d0; } #app-nav-head .button-container { overflow:hidden; position:absolute; top:22px; right:10px; } .app-container { cursor:pointer; height:26px; padding:8px 12px; padding-left:32px; overflow:hidden; border-top: 1px solid #d0d0d0; background-color: #efefef; } @@ -499,9 +271,6 @@ border-bottom: 1px solid #888; .app-container.active { background-color: #dedede; } .app-container .logo { float:left; width:20px; height:20px; background-size:22px 22px; margin-top:2px; border-radius:4px; border:1px solid #a2a2a2; background-position:center; } .app-container .name { width:125px; text-align:left; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; float:left; margin-left:10px; padding-top:6px; color:#6b6b6b; font:13px Ubuntu,Helvetica,sans-serif; } -.new-app-name { width:300px; text-align:left; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; } -#sort-app-button { padding: 7px 1px; } -#sort-app-button i { font-size: 20px; margin: 0; line-height: 16px; } /* APP NAVIGATION END */ #app-management-bar { overflow:hidden; width:180px; position:fixed; left:242px; top:79px; text-align:right; background-color:#efefef; max-height:580px; box-sizing: border-box; box-shadow: 0 0 0 1px #d0d0d0; } @@ -511,66 +280,13 @@ border-bottom: 1px solid #888; #app-management-bar.expand { width:300px; box-shadow: 0 5px 18px 0 #a5a5a5, 0 0 0 1px #d0d0d0; } #app-management-bar.expand .app-container .name { width:245px; transition:width 200ms; } -#app-management-bar .nav-search input { -transition:width 200ms; --webkit-appearance: textfield; -width: 100%; -height: 30px; -padding-right: 20px; -} -#app-management-bar.expand .nav-search input { -/*width:278px;*/ -transition:width 200ms; -} - -#management-app-container { max-height: 450px; } -#manage-new-app { display: none; } .app-details input { width:310px; } #add-new-app .hint, .app-details .hint { padding-top: 8px; font-size:11px; color:#B7B6B6; clear: both; } -#add-app-button {display: block; text-align: center; padding: 10px 0 12px 0; border-bottom: 1px solid #d0d0d0; font: 13px Ubuntu,Helvetica,sans-serif; color: #6b6b6b; cursor: pointer;} -#add-app-button:hover{background-color: #dedede;} -#add-app-button i {color: #2fa732; margin-right: 5px; font-size: 18px; display: inline-block; vertical-align: bottom; margin-bottom: -4px;} -#app_details {margin-left: 10px; text-decoration:underline; font-size: 11px; color: #2FA732; cursor: pointer;} .app-details table.d-table {border-collapse:separate; border-bottom-left-radius:2px; border-bottom-right-radius:2px;} .app-details table.d-table td {border-top:1px solid #ececec; border-bottom:none;} .app-details table.d-table tr:first-child td {border-top:none; border-bottom:none;} -.app-details #app-edit-timezone .read .flag { box-shadow: none; } -.app_details_table{min-width: 800px; position: relative;} -.dialog.app_details_table .indicator{margin-bottom: 0;} -.dialog.app_details_table .buttons { box-shadow: inset 0 1px 0 #ccc; padding: 13px; margin-top: -1px; } -.app_details_table table.d-table{margin-bottom:0;} -.app_details_table td{border-left: 1px solid #ececec; line-height:25px;} -.app_details_table table.d-table tr td.second-header{width: 150px;} -.app_details_table .indicator {display:none;} -.dialog.app_details_table {border:none !important; box-shadow: 0 2px 14px 0 rgba(0,0,0,0.25);} -.dialog.app_details_table table {border-left:none; border-right:none;} -.dialog.app_details_table .d-table th:first-child{border-top-left-radius: 0px;} -.dialog.app_details_table .d-table th:last-child{border-top-right-radius: 0px;} -.dialog.app_details_table .title { font: 19px Ubuntu,Helvetica,sans-serif; -line-height: 100%; -color: #636363; -margin-left: 0px; -text-transform: uppercase; height:auto; padding:20px 15px 15px 20px; border-bottom: 1px solid #cccccc;} -.app_details_table table.d-table tr:nth-child(odd):hover { -background-color: #FFFFFF; -} - -.app_details_table table.d-table tr:nth-child(even):hover { -background-color: #F9F9F9; -} - -#code-countly {background-color: #fff; border-radius: 2px; padding: 20px; border: 1px solid #D0D0D0; margin-left: 199px;} -#code-countly h3 {font-size: 16px; color: #636363; margin-top: 0px;} -#code-countly p {font-size: 14px; line-height: 20px; color: #AFAFAF;} -#code-countly p.select-platforms {font-size: 12px; text-transform:uppercase; color: #D4D4D4;} -#code-countly .sdks {overflow: auto;} -#code-countly .sdks a{color: #2FA732; float: left; text-decoration: none; font-size: 14px; margin-right: 20px;} -#code-countly .sdks a:hover { text-decoration: underline; } -#code-countly-content {margin-left: 135px;} -#code-countly-logo {background-image: url('../images/dashboard/apps-sdk-icon.svg'); float: left; width: 100px; height:100px; background-repeat: no-repeat; background-position: 50% 0%;} /* TABLES */ -.dataTables_wrapper { margin:15px 0; position: relative; } table.d-table { width:100%; padding:0; margin:0; border-radius:2px; margin-bottom:20px; border-left: 1px solid #D0D0D0; border-right: 1px solid #D0D0D0; } table.d-table:not(.no-fix) { table-layout:fixed; } .d-table th { padding:11px 10px 10px 10px; color:#484848; font-weight:normal; font-size:11px; text-transform: uppercase; line-height:12px; text-align:left; border-bottom:1px solid #E2E2E2; background-color:#F3F3F3; border-top: 1px solid #D0D0D0; } @@ -584,12 +300,9 @@ table.d-table:not(.no-fix) { table-layout:fixed; } .d-table tr:last-child { border-bottom:none; } .d-table tr:nth-child(even){ background-color:#F9F9F9} .d-table tr:hover { background-color:#F1F1F1; } -.d-table tr td.dataTables_empty:hover { background-color:#FFFFFF; } .d-table tr:last-child td { border-bottom:none; } .d-table tr:last-child td:first-child { border-bottom-left-radius:7px; } .d-table tr:last-child td:last-child { border-bottom-right-radius:7px; } -.d-table .table-no-data { text-align:center; font:15px Ubuntu,Helvetica,sans-serif; line-height:111%; padding:20px; color:#CCC; } -.d-table .table-no-data:hover { background-color:#FFF; } .d-table.horizontal { border-radius:0; } .d-table.horizontal tr:hover { background-color:#FFF; } .d-table.horizontal tr:nth-child(even):hover { background-color:#FBFBFB; } @@ -604,8 +317,6 @@ table.d-table:not(.no-fix) { table-layout:fixed; } .d-table .center{text-align: center;} .d-table .right{text-align: right;} -div.datatablesubrow {display: none;} - .d-table tr[id] { cursor: pointer; } .d-table tr.selected {background-color: #FFE4C9;} @@ -615,38 +326,9 @@ div.datatablesubrow {display: none;} .d-table textarea { max-width: 274px; } .d-table input[type=password] { border-radius:2px; margin:0; font:14px Ubuntu,Helvetica,sans-serif; line-height:111%; padding:5px; border:1px solid #D0D0D0; width:274px; } -.table-template {margin-top: -16px;} - .dataTable { border-radius:0 !important; margin-bottom:0 !important; } .dataTable th { border-radius:0 !important; outline:none; cursor:pointer; } -.dataTable th.sorting_disabled { cursor:auto; } .dataTable td { border-radius:0 !important; } -.dataTable-bottom, .dataTable-top { border: 1px solid #D0D0D0; padding:0; overflow:auto; color:#969696; font-weight:normal; font-size:10px; line-height:111%; text-align:left; background-color:#ECECEC; } -.dataTable-top { border-bottom:none; color:#BBB; transition:color 0.5s; border-top-left-radius:2px; border-top-right-radius:2px; } -.dataTable-bottom { display:none; border-top:1px solid #E2E2E2; border-bottom-left-radius:2px; border-bottom-right-radius:2px; background-color: #ECECEC; } -.dataTable-top:hover { color:#888; transition:color 0.5s; } -.dataTable-top .dataTables_filter { float:left; padding-top:5px; display:none; } -.dataTable-top .dataTables_filter input { font-size:13px; margin:0; border-radius:2px; background-color:#FFF; border:1px solid #CCC; width:200px; transition:width 0.5s; outline:none; padding:2px 6px; } -.dataTable-top .dataTables_length { float:right ; padding:5px 11px; border-left: 1px solid #cccccc;} -.dataTable-top .dataTables_length label { text-transform: uppercase; } -#dataTables_length_input {font-size:13px; margin:0; border-radius:2px; background-color:#FFF; border:1px solid #CCC; width:200px; transition:width 0.5s; outline:none; padding:2px 6px; width: 50px; margin-left: 9px;} -.dataTable-top .DTTT_container { float:right; padding: 11px 0; padding-top: 12px; } -.dataTable-top .DTTT_container a { margin-right:10px; } -.dataTable-top .DTTT_container a:hover { text-decoration:underline; } -.DTTT_container { visibility:hidden; } -.DTTT_container .DTTT_button { position:relative; display:inline-block; } -.DTTT_container .DTTT_button div>* { vertical-align:inherit; } -.save-table-data { float:right; font-size:17px; padding:8px 12px 7px 7px; cursor:pointer; } -.search-table-data { float:left; font-size:17px; padding:8px 7px 7px 7px; cursor:pointer; } -.FixedHeader_Cloned .dataTable { border-bottom:none; } -.dataTable-bottom .dataTables_info { float:left; padding:5px 10px; } -.dataTables_paginate { float:right; } -.dataTables_paginate span { display:inline-block; padding:7px 6px 5px 6px; font-size:20px; cursor:pointer; border-left:1px solid #CCC; } -.dataTable-bottom .dataTables_paginate span { font-size:18px; padding-right:5px; } -.dataTables_paginate .paginate_disabled_previous { opacity:0.2; } -.dataTables_paginate .paginate_disabled_next { opacity:0.2; } -.dataTable thead th.sorting_asc:after { color:#2FA732; display: inline-block; font-family: 'Font Awesome 5 Free'; font-weight: 900; content: "\f0de"; margin-left: 7px; vertical-align: text-top; margin-top: 7px; line-height: 5px; } -.dataTable thead th.sorting_desc:after { color:#2FA732; display: inline-block; font-family: 'Font Awesome 5 Free'; font-weight: 900; content: "\f0dd"; margin-left: 7px; vertical-align: text-top; margin-top: 2px; line-height: 6px; } .dataTable thead th.sorting:after { color:#BBBBBB; display: inline-block; font-family: 'Font Awesome 5 Free'; font-weight: 900; content: "\f0dc"; margin-left: 7px; vertical-align: text-top; margin-top: 4px; line-height: 6px; } .d-table.horizontal { border:1px solid #D0D0D0; } @@ -655,15 +337,8 @@ div.datatablesubrow {display: none;} .d-table.horizontal tr:hover, .d-table.horizontal tr:nth-child(even), .d-table.horizontal tr:nth-child(even):hover { background-color: #FFF; } -.d-table.horizontal .populate-demo-data td, -.d-table.horizontal td td { border-bottom:none; } -.table-placeholder { z-index:-1; display:block; height: 100%; min-height:120px; background-color: #FFF; border:1px solid #D0D0D0; border-radius:2px; border-top-left-radius: 0; border-top-right-radius: 0; opacity: 1; position: absolute; top:0; width: 100%; box-sizing: border-box; } -.table-placeholder .top { height: 34px; border-bottom: 1px solid #d0d0d0; background-color: #ECECEC; } -.table-placeholder .header { height: 33px; border-bottom: 1px solid #d0d0d0; background-color: #F3F3F3; } - -.table-loader { height: 1px; width: 100%; position: absolute; overflow: hidden; background-color: transparent; top:33px; left:0; box-sizing: border-box; margin:0; z-index: 1; } -.table-loader:before{ display: block; position: absolute; content: ""; left:-200px; width: 200px; height: 1px; background-color: #2fa732; animation: table-loading 2s linear infinite; animation-delay:1s; } +.d-table.horizontal td td { border-bottom:none; } @keyframes table-loading { from {left: -30%; width: 30%;} 50% {width: 30%;} @@ -681,11 +356,10 @@ to {left: 100%;} .icon-button.dark { background-color:#02060b; color:#BFBFBF; box-shadow:inset 0 0 0 1px #02060b; } .icon-button .icon { float:left; margin-right:7px; background-repeat:no-repeat; } .icon-button .text { float:right; padding-top:2px; } -.icon-button.create-report, + .icon-button.green { background-color:#2EB52B; color:#FFF; box-shadow:inset 0 0 0 1px #2EB52B; } -.icon-button.delete-app, -.icon-button.red, -.dialog.red #dialog-continue { background-color:#D63E40; color:#FFF; box-shadow:inset 0 0 0 1px #D63E40; } + +.icon-button.red { background-color:#D63E40; color:#FFF; box-shadow:inset 0 0 0 1px #D63E40; } .icon-button i { margin-right:6px; line-height: 9px; } .button .back{ color: #666; cursor:pointer; user-select:none; background-color:#E0E0E0; float:left; padding:8px 20px; padding-top:7px; border:1px solid #A5A5A5; border-radius: 2px; font: 13px Ubuntu,Helvetica,sans-serif; margin-top: 5px; margin-right: -5px;} @@ -700,12 +374,7 @@ to {left: 100%;} #date-selector { float:right; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#6B6B6B; padding:6px; padding-right:0; user-select:none; position: relative; } #date-selector .button { visibility: visible; cursor:pointer; user-select:none; padding:7px 5px 7px 5px; margin-right:-1px; color: #ffffff; font-size:13px; line-height:13px; } -.date-selector-buttons {background-color: #03060c; width: 160px; position:absolute; right:0; top:0; padding: 0px 20px;margin: 0px -3px 0 0; border-top-right-radius:2px; border-bottom-right-radius:2px; height:100%} -.date-selector-buttons .button:nth-child(1) { margin-top:20px;} .widget-header:hover #date-selector .button { visibility: visible; } -#date-selector .date-buttons-container { float: left;} -#date-selector .date-buttons-container .button:first-child { border-top-left-radius:2px; border-bottom-left-radius:2px; } -#date-selector .date-buttons-container .button:last-child { border-top-right-radius:2px; border-bottom-right-radius:2px; border-right:1px solid #D0D0D0; } #date-selector .button:hover { background-color:#1b2732; } #date-selector .button:active { background-color:#1b2732; } #date-selector .button.active { background-color:#1b2732; } @@ -727,9 +396,9 @@ to {left: 100%;} border: 1px solid #243544; } #date-selector .calendar-block span.date-input-label {float: right; display: inline-block; text-transform: uppercase; color: #d2d2d1; margin-top:11px; font: 12px Ubuntu,Helvetica,sans-serif;} -#date-picker, .date-picker, .date-picker-ext-wrapper{ white-space:nowrap; display:none; position:absolute; z-index:1000; padding:2px 3px 6px 3px; background-color:#0b131a; border-radius:2px; right: 2px; top: 41px; } -#date-picker .calendar-container, .date-picker .calendar-container, .date-picker-ext-wrapper .calendar-container { overflow:auto; padding:10px 5px; margin-right:200px; } -#date-picker .calendar-container .calendar, .date-picker .calendar-container .calendar, .date-picker-ext-wrapper .calendar-container .calendar { vertical-align: top; margin-bottom:10px; } +#date-picker, .date-picker{ white-space:nowrap; display:none; position:absolute; z-index:1000; padding:2px 3px 6px 3px; background-color:#0b131a; border-radius:2px; right: 2px; top: 41px; } +#date-picker .calendar-container, .date-picker .calendar-container { overflow:auto; padding:10px 5px; margin-right:200px; } +#date-picker .calendar-container .calendar, .date-picker .calendar-container .calendar { vertical-align: top; margin-bottom:10px; } #date-picker .calendar-container .calendar:nth-child(2) { margin-right:0; } #date-picker .button-container { overflow:auto; position:absolute; right: 20px; bottom: 15px;} #date-picker .button-container .icon-button { display: inline-block; padding: 7px 10px; float: right } @@ -739,157 +408,14 @@ to {left: 100%;} margin: 1px; padding: 4px; } -#date-picker .in-range a.ui-state-hover { - background:#1b2732; -} - -#date-picker .ui-datepicker-title { - font-size:13px; -} #date-picker:before { border: 6px solid rgba(194, 225, 245, 0); border-bottom-color: #03060c; right: 9px; top: -11px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } #selected-date {font-size:13px; color:#767676; line-height:28px; } -.threes-column .big-numbers { width:33%; } -.threes-column .big-numbers:last-child { width:34%; } -.two-column .big-numbers { width:50%; } -.one-column .big-numbers { width:100%; position:relative; } - -.two-columns { width:50%; } - -.three-column { width:33%; } -.three-column:nth-child(2) { width:34%; } -.three-column:last-child { width:33%; } - -.six-column { width:17%; } -.six-column:first-child { width:16%; } -.six-column:last-child { width:17%; } - -.four-column, .dashboard-summary .item.four-column { width:25%; } -.five-column, .dashboard-summary .item.five-column { width:20%; } - -.sticky-header.hide { display:none; } -.sticky-header { top:0; position:fixed; } -.sticky-header table { border:none; border-radius:0; } -.sticky-header table th { box-shadow: inset 0 -1px 0 0 #d0d0d0; border-bottom: none; outline: none; cursor: default; position:relative; cursor:pointer;} -.sticky-header table th.sorting_disabled { cursor:auto; } -.sticky-header table th:first-child { box-shadow: inset 0 -1px 0 0 #d0d0d0, inset 1px 0 0 0 #d0d0d0; } -.sticky-header table th:last-child { box-shadow: inset 0 -1px 0 0 #d0d0d0, inset -1px 0 0 0 #d0d0d0; } - /* DATEPICKER */ -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { text-decoration: none; border:none; color: #FFF; font-size:12px; padding:5px; background-color:transparent; text-align:center; background-image:none; box-shadow: none; } -.ui-datepicker a, -.ui-datepicker-inline a { text-decoration: none !important; } -.ui-widget-content .ui-state-hover { background-color:#1b2732; color:#ffffff; text-shadow:none; background-image:none; margin: 1px; padding: 4px; border-radius: 2px; } -.ui-widget-content .ui-state-active { background-color:#2FA732; color:#FFF; text-shadow:none; background-image:none; margin: 1px; padding: 4px; border-radius: 2px; } -.ui-datepicker.ui-widget { padding:10px; background-color: #0b131a; } -.ui-datepicker td { padding:0; border:1px solid #192733; border-left:none; background-color: transparent; } -.ui-datepicker th { font-weight:normal; font-size:8px; } -.ui-datepicker-inline { border-radius:0; } -.ui-datepicker-inline table { margin:0 auto; font-weight:normal; width:99%; } -.ui-datepicker-calendar tbody, -.ui-datepicker-inline table tbody { border:1px solid #192733; } -.ui-datepicker-group-last .ui-datepicker-calendar {} -.ui-datepicker { width:190px ! important; border:none; } -.ui-widget-header { border-radius:0; border:none; background-color:transparent; background-image:none; color:#FFF; font-weight:normal; font-size:12px; height:23px; } -.ui-datepicker { font-weight:normal; line-height:111%; overflow:auto; } -.ui-widget-content { background-color:transparent; background-image:none; padding:0; } -.ui-datepicker-calendar thead { font-weight:normal; border-bottom:1px solid #BBBBBB; } -.ui-datepicker-calendar thead th { text-transform:uppercase; height:15px; text-align: center; color:#d6d6d6; border:none; background-image:none; padding: 9px 3px 0 3px; } -.ui-datepicker-calendar tr { line-height: 111%; } -.ui-datepicker-calendar tr:last-child td { border-bottom:none; } -.ui-datepicker-calendar td:last-child { border-right:none; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:154px; margin:5px; box-shadow:0 1px 1px 1px #000; } -.ui-datepicker th { padding:4px 3px; } -.ui-corner-all.ui-state-hover { background-color:transparent; border:none; cursor:pointer; } -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { width:15px; height:20px; } -#date-picker .ui-datepicker .ui-datepicker-prev, -#date-picker .ui-datepicker .ui-datepicker-next { height:23px; } -.ui-datepicker-inline .ui-datepicker-prev, -.ui-datepicker-inline .ui-datepicker-next { height:21px; } -.ui-datepicker .ui-widget-header .ui-icon { background-image: none; text-indent: 3px; } -.ui-icon-circle-triangle-w, -.ui-icon-circle-triangle-e { font-family: 'Font Awesome 5 Free';font-weight: 900; text-align:right; width:11px; overflow: hidden; color:#bfbfbf; font-size:10px; } -.ui-icon-circle-triangle-w:before { content: "\f053 "; } -.ui-icon-circle-triangle-e:before { content: "\f054 "; } -.ui-datepicker-prev.ui-state-hover, -.ui-datepicker-next.ui-state-hover { padding:0; } -.ui-datepicker .ui-datepicker-title { line-height:21px; } -.ui-datepicker-other-month span { opacity: 0; } - - -.calendar-light .ui-datepicker.ui-widget { padding:1px; background-color: #FFF; } -.calendar-light .ui-state-default, -.calendar-light .ui-widget-content .ui-state-default, -.calendar-light .ui-widget-header .ui-state-default { color:#000; } -.calendar-light .ui-widget-content .ui-state-hover { color:#424242; } -.calendar-light .ui-widget-content .ui-state-active { color:#FFF; } -.calendar-light .ui-datepicker td, -.calendar-light .ui-datepicker-calendar tbody, -.calendar-light .ui-datepicker-inline table tbody { border-color:#CCC; } -.calendar-light .ui-widget-header { color:#000; } - - -.datepicker-extended{ -display: inline-block; -} - -.datepicker-extended.datepicker-range .in-range a { -background: rgba(46, 167, 50, 0.6); -border-radius: 2px; -margin: 1px; -padding: 4px; -} - -.datepicker-extended.datepicker-range .point a{ - background-color: #2FA732; - color: #FFF; - text-shadow: none; - background-image: none; - margin: 1px; - padding: 4px; - border-radius: 2px; -} -.datepicker-extended .text-fields input { - height: 19px; - background-color: #0b131a; - color: white; - border: 1px solid #979797; - margin-bottom: 4px; - font-family: 'Ubuntu'; - border-radius: 2px; - font-size: 12px; - padding: 4px 7px; - } - .datepicker-extended .text-fields input.focused { - background-color: #22232b; - border-color: #2EB52B; - } - .datepicker-extended .text-fields{ - background-color: #0b131a; - } - .datepicker-extended .text-fields .input-0 { - width: 194px; - } - .datepicker-extended.datepicker-range .text-fields .input-0, - .datepicker-extended.datepicker-range .text-fields .input-1 { - width: 82px; - } - .datepicker-extended.datepicker-range .text-fields .input-0 { - margin-right: 7px; - } - .datepicker-extended.datepicker-range .text-fields .input-1 { - margin-left: 7px; - } /* DATEPICKER END */ /* FORMS */ -.cly-button-dark { color:#DDD; background-color:#292929; border:1px solid #1B1B1B; box-shadow:inset 0 1px 0 #777777; cursor:pointer; float:left; padding:5px 10px; border-radius:4px; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; } -.cly-button-dark:hover { opacity:0.9; } -.cly-button-dark:active,.cly-button-dark.active { background-color:#3E3E3E; box-shadow:inset 0 1px 0 #444; } .dashboard-summary { margin-bottom:16px; overflow:auto; } .dashboard-summary .item { float:left; font-family:Oswald; width:25%; } @@ -903,14 +429,6 @@ padding: 4px; .dashboard-summary .item:last-child .inner { border-right:none; } .dashboard-summary .item .title { font:12px Ubuntu,Helvetica,sans-serif; line-height:111%; text-align:center; color:#FFF; text-transform:uppercase;} .dashboard-summary .item .bar { width:80%; height:6px; padding-top:2px; padding-bottom:2px; overflow:auto; background-color:transparent; margin:0 auto; margin-top:5px; margin-bottom:5px; } - .dashboard-summary .item .bar .bar-inner { width:40%; float:left; height:6px; box-shadow:inset 2px 0 0 0 #333 } - .dashboard-summary .item .bar .bar-inner:hover { margin-bottom:-1px; margin-top:-1px; height:8px; } - - .dashboard-summary .item .bar .bar-inner:first-child { box-shadow:none; } - .dashboard-summary .item .bar .bar-inner-new:nth-child(2) { width:42%; } - .dashboard-summary .item .bar .bar-inner-new:nth-child(3) { width:16%; } - - .dashboard-summary.two-bars .item .bar .bar-inner:nth-child(2) { box-shadow: 2px 0 0 0 #ECECEC; background-color: #ECECEC; pointer-events:none; } .dashboard-summary .item .number { font-size:26px; text-align:center; color:#52A3EF; line-height:33px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .dashboard-summary .item .no-data { font:18px Ubuntu,Helvetica,sans-serif; line-height:111%; text-align:center; color:#222; padding-bottom:14px; padding-top:20px; } @@ -918,7 +436,6 @@ padding: 4px; .dashboard-summary .item.light .inner { background-color: #FFF; box-shadow: inset 0 0 0 1px #D0D0D0; } .dashboard-summary .item.light .inner .title { color:#484848; } -.dashboard-summary .item.light .bar .bar-inner { box-shadow:inset 2px 0 0 0 #FFF; background-color: #52a3ef; } .cly-select { position:relative; background-color:#FDFDFD; user-select:none; display:inline-block; width:135px; height:27px; border:1px solid #D0D0D0; border-radius:2px; cursor:pointer; } .widget-header .cly-select { background-color: #ECECEC; position:relative; } @@ -938,9 +455,7 @@ padding: 4px; .cly-select .search input::-webkit-search-decoration { -webkit-appearance: none; } .cly-select .search + .select-items { margin-top: 33px; border-top-left-radius: 0; border-top-right-radius: 0; } .cly-select .select-items { top:100%; z-index:2; display:none; position:absolute; margin-left:-1px; border-radius:2px; background-color:#FFF; border:1px solid #D0D0D0; width:135px; } - .cly-select.upside-down .select-items { bottom:100%; top: auto;} .cly-select.dark .select-items { border-color:#d0d0d0; } - .cly-select .select-items .scroll-list { max-height:188px; } .cly-select .select-items .warning { color:#FF8700; font-weight:normal; border-bottom:1px solid #e6e6e6; font:11px Ubuntu,Helvetica,sans-serif; line-height:14px; padding:7px 9px; cursor: default; text-align: center; } .cly-select .select-items .item { text-overflow:ellipsis; overflow:hidden; white-space:nowrap; color:#666; font-weight:normal; border-bottom:1px solid #e6e6e6; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; padding:5px 9px; padding-bottom:7px; } .cly-select .select-items .item:last-child, @@ -962,7 +477,6 @@ padding: 4px; .cly-select .right.combo:before { color:#717171; font-family: 'Ionicons'; content: "\f123"; font-size: 9px; position: absolute; right: 8px; } .cly-select:hover .right.combo:before { color:#2fa732; } .cly-select.active .right.combo:before { content: "\f126"; color:#2fa732; } - .cly-select .slimScrollBar.ui-draggable { cursor:default; } .cly-select.loading:after { content:"Loading..."; position: absolute; top:1px; left: 0; color:#d0d0d0; background-color: #fdfdfd; padding: 5px 40px 5px 11px; font-size: 13px; } @@ -976,16 +490,6 @@ padding: 4px; .cly-select.float .select-items, .cly-select.float .search { width:220px; } -.cly-select.float-right { float:right; width: 150px; background-color: #fff; margin-right: 5px; margin-top:6px;} -.cly-select.float-right.green { float:right; width: 150px; background-color: #2FA732; border-color:#2FA732; margin-right: 5px; margin-top:6px;} -.cly-select.float-right.green .text{ color:#fff;} -.cly-select.float-right.green .right.combo:before{ color:#fff;} -.cly-select.float-right.green.disabled { background-color:#FDFDFD; border-color:#D0D0D0; } -.cly-select.float-right.green.disabled .text{ color:#444;} -.cly-select.float-right.green.disabled .right.combo:before{ color:#717171;} -.cly-select.disabling-on .select-items .item.disabled { opacity: 0.5; cursor: default; } -.cly-select.disabling-on .select-items .item.disabled:hover { background-color: #FFF; } - .cly-multi-select { position:relative; background-color:#FDFDFD; user-select:none; display:inline-block; width:135px; height:auto; min-height: 32px; border:1px solid #D0D0D0; border-radius:2px; cursor:pointer; } .cly-multi-select .select-inner { position:relative; width:100%; height:100%; } .cly-multi-select.active { border-bottom-left-radius:0; border-bottom-right-radius:0; } @@ -996,7 +500,6 @@ padding: 4px; .cly-multi-select .search input { height:14px; padding:0; margin:0; border:none; outline:none; width:100%; font:13px Ubuntu; line-height:111%; } .cly-multi-select .search + .select-items { margin-top: 33px; border-top-left-radius: 0; border-top-right-radius: 0; } .cly-multi-select .select-items { top:100%; z-index:2; display:none; position:absolute; margin-left:-1px; border-radius:2px; background-color:#FFF; border:1px solid #D0D0D0; width:135px; max-height: 188px; overflow-y: auto; } -.cly-multi-select .select-items .scroll-list { max-height:188px; } .cly-multi-select .select-items .item { position:relative; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; color:#666; font-weight:normal; border-bottom:1px solid #e6e6e6; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; padding:5px 9px; padding-bottom:7px; } .cly-multi-select .select-items .item:last-child, .cly-multi-select .select-items .item.last { border-bottom: none; } @@ -1015,62 +518,20 @@ padding: 4px; .cly-multi-select .right.combo:before { color:#717171; font-family: 'Ionicons'; content: "\f123"; font-size: 9px; position: absolute; right: 8px; } .cly-multi-select:hover .right.combo:before { color:#2fa732; } .cly-multi-select.active .right.combo:before { content: "\f126"; color:#2fa732; } -.cly-multi-select .slimScrollBar.ui-draggable { cursor:default; } .cly-multi-select .selection { cursor:default; position:relative; float: left; border-radius: 2px; background-color: #777; color:#f1f1f1; padding:3px 19px 3px 10px; margin: 2px 5px 2px 0; font-size: 12px; } .cly-multi-select .selection:hover { background-color: #5a5a5a; } .cly-multi-select .selection .remove { position: absolute; right:5px; top:3px; font-size: 11px; cursor: pointer; } -.cly-multi-select.selection-exists .default-text { display: none; } -.cly-multi-select .default-text { display: block; padding: 5px 0; } .cly-multi-select .select-items .item.selected { color: #2fa732; display: none; } .cly-multi-select.disabled { opacity: 0.4 !important; cursor: default; } -body .selectize-control.multi .selectize-input input { height: 18px; } -body .selectize-control.multi .selectize-input, body .selectize-control.multi .selectize-input.has-items { position:relative; background-color:#FDFDFD; user-select:none; height:auto; min-height: 32px; border:1px solid #D0D0D0; border-radius:2px; cursor:text; } -body .selectize-control.multi .selectize-input > div { font-family: Ubuntu,sans-serif; line-height: 14px; border-radius: 2px; background-color: #777; color:#f1f1f1; padding:3px 19px 3px 10px; margin: 0 5px 2px 0; font-size: 12px; } -body .selectize-control.multi .selectize-input > div:hover { background-color: #5a5a5a; color: #f1f1f1; cursor: default; } -body .selectize-control.multi .selectize-input > div.active { background-color: #777; color: #f1f1f1; cursor: default; } -body .selectize-control.multi .selectize-input > div .remove { position: absolute; right:3px; top:3px; font-size: 16px; line-height: 9px; font-weight: 100; cursor: pointer; } -body .selectize-control.plugin-remove_button [data-value] .remove { border: none; } - -.cly-text-select { display:inline-block; height:27px; } -.cly-text-select input { margin-left:-1px; width:195px; height:27px; color:#444; font-weight:normal; font:13px Ubuntu,Helvetica,sans-serif; border:1px solid #D0D0D0; border-radius:2px; padding:0 8px; display:inherit; outline:none; } -.cly-text-select.req { border-color:#E95C6C; } -.cly-text-select.dark { border-color:#666; } -.cly-text-select.disabled { opacity: 0.4 !important; cursor: default; } -.cly-text-select .select-inner { position:relative; width:100%; height:100%; } -.cly-text-select.active { border-bottom-left-radius:0; border-bottom-right-radius:0; } -.cly-text-select.active .right { border-bottom-right-radius:0; } -.cly-text-select .select-items { z-index:1000; display:none; position:absolute; margin-left:-1px; border-radius:2px; background-color:#FFF; border:1px solid #D0D0D0; border-top-left-radius:0; border-top-right-radius:0; width:135px; } -.cly-text-select.dark .select-items { border-color:#666; } -.cly-text-select .select-items.square { border-radius:0; } -.cly-text-select .select-items.square .item:last-child { border-radius:0; } -.cly-text-select .select-items .scroll-list { max-height:189px; } -.cly-text-select .select-items .item { cursor: pointer; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; color:#666; font-weight:normal; border-bottom:1px solid #e6e6e6; font:13px Ubuntu,Helvetica,sans-serif; padding:5px 9px; padding-bottom:7px; } -.cly-text-select.dark .select-items .item { border-color:#888; } -.cly-text-select .select-items .item.hidden { display:none; } -.cly-text-select .flag { opacity:0.8; width:16px; height:11px; border-radius:2px; box-shadow:0 0 1px 0 #333; margin-right:8px; margin-top:2px; float:left; } - .cly-text-select .flag.ch { margin-right:13px; } - .cly-text-select .flag.np { margin-right:15px; } -.cly-text-select .select-items .item:hover { background-color:#f3f3f3; } -.cly-text-select .select-items .item:hover .flag { box-shadow:0 0 0 1px #000; } -.cly-text-select .select-items .item:last-child, -.cly-text-select .select-items .item.last { border-bottom: none; } - -.cly-text-select .text-container { float:left; width:100%; } -.cly-text-select .slimScrollBar.ui-draggable { cursor:default; } - .read {} .read .country { float:left; margin-right:8px; } .read .timezone { float:left; } .read .logo { float:left; height:25px; width:25px; background-size:27px 27px; margin-top:1px; border-radius:4px; border:1px solid #555; background-position:center; } .edit { display:none; } -#sidebar-new-app { display:none; } - .required { font-size:23px; color:#B94A48; vertical-align:top; display:none; padding-left:7px; margin-top: -2px; position: absolute; } .red-text { font-size:12px; color:#B94A48; vertical-align:text-top; padding-left:5px; } -.green-text { font-size:12px; color:#50C354; vertical-align:text-top; padding-left:5px; } -.required-color { color:#B94A48 !important; } #overlay { display:none; background-color:#000; opacity:0.2; width:100%; height:100%; position:fixed; z-index:10000; top:0; } .dialog { display:none; position:fixed; max-width:400px; left:50%; top:50%; background-color:#FFF; border:1px solid #999; border-radius:2px; z-index:10001; } @@ -1087,65 +548,20 @@ body .selectize-control.plugin-remove_button [data-value] .remove { border: none .dialog .buttons { margin-top:15px; overflow:auto; padding:10px; padding-top:0; } .dialog .buttons .icon-button { float:right; } .dialog input[type=text], .dialog input[type=password] { margin:0; font:15px Ubuntu,Helvetica,sans-serif; line-height:111%; padding:3px; border:1px solid #DDD; } - .dialog .result-message { float:left; margin-top:6px; font:italic 13px Ubuntu,Helvetica,sans-serif; line-height:111%; } - .dialog .result-message.red { color:#D63E40; } - .dialog .result-message.green { color:#6BB96E; } .dialog .message .title { margin-bottom:8px; } .dialog .message .input input { width:280px; } .dialog .message a { text-decoration: underline; } -.dialog.cly-loading .content { height: 5em; } .dialog.popStyleGreen .indicator {display:none;} .dialog.popStyleGreen{ text-align:center; color:#717171; width:300px; border:none; border-radius: 2px; padding:30px 30px 18px 30px; max-width:450px; box-sizing: border-box; box-shadow: 0 2px 14px 0 rgba(0,0,0,0.25);} .dialog.popStyleGreen .title{color:#636363; font-size:16px; text-align:center; margin: 25px 0px 15px 0px; font-weight:500; } .dialog.popStyleGreen .message{color:#717171; font-size:13px; line-height:19px; text-align:center;font-family:Ubuntu,Helvetica,sans-serif; margin: 0px; word-wrap:break-word; } -.dialog.popStyleGreen #dialog-continue, .dialog.popStyleGreen #dialog-ok{background-color:#2EB52B;color:#ffffff; border-radius:2px; } -.dialog.popStyleGreen #dialog-ok{margin-bottom:12px;} .dialog.popStyleGreen .icon-button {float:none; border:none; padding:12px; box-shadow:none; display: inline-block; margin:0; } .dialog.popStyleGreen #dialog-cancel{background-color:none; color:#929292; text-decoration: underline; background-color:#ffffff;} .dialog.popStyleGreen .image {width:85px; height:85px; margin: 0px auto 0px auto;} .dialog.popStyleGreen .image div{width:85px; height:85px; margin:0; padding:0;} .dialog.popStyleGreen p {line-height:40px; padding:0; margin:0;} .dialog.popStyleGreen .buttons { padding:0; margin: 30px 0px 0px 0px;} -.dialog.popStyleGreenWide{width:450px;} -.dialog.popStyleGreenWide .message{ text-align:left;} - -.loading-bars, -.loading-bars:before, -.loading-bars:after { -background: #3FAA43; --webkit-animation: load1 1s infinite ease-in-out; -animation: load1 1s infinite ease-in-out; -width: 1em; -height: 4em; -} -.loading-bars { - position: relative; - margin: 3em auto 0; -position: relative; -color: #3FAA43; -text-indent: -9999em; -font-size: 11px; --webkit-transform: translateZ(0); --ms-transform: translateZ(0); -transform: translateZ(0); --webkit-animation-delay: -0.16s; -animation-delay: -0.16s; -} -.loading-bars:before, -.loading-bars:after { -position: absolute; -top: 0; -content: ''; -} -.loading-bars:before { -left: -1.5em; --webkit-animation-delay: -0.32s; -animation-delay: -0.32s; -} -.loading-bars:after { -left: 1.5em; -} @-webkit-keyframes load1 { 0%, 80%, @@ -1170,51 +586,20 @@ left: 1.5em; height: 5em; } } - -#new-install-overlay { display:none; z-index:2; position:absolute; width:100%; height:100%; background-color:#000; opacity:0.6; } .alert { font-family:Ubuntu,Helvetica,sans-serif; line-height:111%; border-radius:4px; padding:8px 14px; } .alert.danger { color:#B94A48; background-color:#F2DEDE; border:1px solid #EED3D7; } .alert.success { color:#468847; background-color:#DFF0D8; border:1px solid #D6E9C6; } /* USER MANAGEMENT */ -.manage-user { padding:10px; } -.manage-users-table {margin-top: -16px;} -.manage-users-table .dataTable-top {border-radius: 0;} #user-table { border-bottom-left-radius:0; border-bottom-right-radius:0; } -#user-table td, -.user-details.create-user-row td { font-family: Ubuntu; } - -#user-table .help-edit { font-size:11px; display:none; position:absolute; right:3px; top:2px; background-color: #F1F1F1; padding: 1px 1px 1px 15px; line-height: 130%; } -#user-table .help-close { font-size:11px; display:none; position:absolute; right:3px; top:2px; background-color: #FFF; padding: 1px 1px 1px 15px; line-height: 130%; } +#user-table td { font-family: Ubuntu; } #user-table tr td.details { padding:0; } -#user-table tr:hover .help-edit { display:block; } #user-table tr.active:hover { background-color:#FFF; } -#user-table tr.active:hover .help-edit { display:none; } -#user-table tr.active:hover .help-close { display:block; } .user-details { display:none; overflow:auto; padding-bottom: 45px;} #user-table tr td>div { position:relative; } -.user-details.create-user-row { padding-bottom: 45px; box-shadow: inset 2px 0 0 -1px #DDD, inset -2px 0 0 -1px #DDD, inset 0 2px 0 -1px #DDD; position: relative; font-size: 12px; font-weight: normal; color: #6B6B6B; margin-bottom: -15px; } .user-details { background-color:#f9f9f9; } .user-details:hover { background-color:#f9f9f9; } -#listof-apps { width:200px; display:none; position:absolute; margin-top:12px; z-index:1000; padding:7px; background-color:#292929; border-radius:2px; } - #listof-apps:before { border: 6px solid rgba(194, 225, 245, 0); border-bottom-color: #292929; left: 20px; top: -12px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } - #listof-apps .button-container { overflow:auto; margin-top:10px; margin-bottom: 5px; } - #listof-apps .button-container .icon-button { float:right; font-size:11px; } - #listof-apps .scrollable { min-height:36px; max-height:221px; overflow:auto; background-color:transparent; } - #listof-apps .app { width:184px; border-bottom:1px solid #d4d4d4; padding:8px; overflow:auto; background-color:#efefef; cursor:pointer; color:#6b6b6b; margin:0 auto; } - #listof-apps .app:last-child { border-bottom:none; } - #listof-apps .app.disabled { display: none !important; } - #listof-apps .app.selected { background-color:#dedede; } - #listof-apps .app:hover { background-color: #e6e6e6; } - #listof-apps .app .image { background-size:22px 22px; float:left; margin-right:10px; border-radius:4px; width:20px; height:20px; background-position:center; border:1px solid #a2a2a2; } - #listof-apps .app.selected .image { box-shadow:0 0 0 1px #2EB52B; } - #listof-apps .app .name { float:left; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; padding-top:4px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; width:90px; } - #listof-apps #deselect-all.icon-button, #listof-apps .btn-deselect-all.icon-button { display:none; max-width: none; } - #listof-apps #done { margin-left:5px; } -#listof-apps .search { background-color: #fbfbfb; position:relative; border-bottom: 1px solid #d4d4d4; } -#listof-apps .search i { position: absolute; top: 11px; right: 11px; color: #6b6b6b; font-size: 10px; } -#listof-apps .search input { outline: none; font-size: 13px; border: none; padding: 8px 10px; margin-right: 1px; width: 146px; background-color: #fbfbfb; color: #6b6b6b; } .user-details .button-container { overflow:auto; bottom:8px; right:16px; position:absolute; } .user-details .row { overflow:auto; border-top:1px solid #EEE; padding:10px; margin:0 1px; } @@ -1223,247 +608,21 @@ left: 1.5em; .user-details .row .detail { margin-left:165px; } .user-details .button-container { padding-bottom:5px; } .user-details .button-container .icon-button { float:right; } - .user-details .app-selection { margin-left:10px; border-radius:10px; background-color:#CCC; cursor:pointer; float:left; width:15px; height:15px; } .user-details .select-apps { margin-left:10px; cursor:pointer; float:left; font-size:17px; margin-top: -1px; color:#2EB52B; line-height: 15px; } - .user-details .user-admin-list span, .user-details .no-apps { color:#CCC; font-size:12px; font-style:italic; } -.user-details .no-apps { margin-left:165px; display:none; } -.small-link { margin-top:10px; font-size:11px; cursor:pointer; color:#999; vertical-align:text-top; display:inline-block; } -.small-link:hover { text-decoration:underline; } -.password-row { display:none; } -.user-noapps { position:absolute; left:50%; top:50%; width:460px; margin-left:-118px; font:16px Ubuntu,Helvetica,sans-serif; line-height:23px; color:#555; height:50px; margin-top:-25px; } .checkbox { cursor:pointer; width:16px; height:16px; float:left; margin-right:5px; background-image:url('../images/management/checkbox.png'); background-position:-16px; } .checkbox.checked { background-position:0; } /* USER MANAGEMENT END */ -.icon-button.light.graph-segment.active { border-color:#333; box-shadow:inset 0 0 3px #222; background-color:#3E3E3E; background-image:linear-gradient(top, #292929 40%, #3E3E3E 100%); background-image:linear-gradient(to bottom, #292929 40%, #3E3E3E 100%); } -.icon-button.light.graph-segment.active:hover { opacity:1; } -.os-rows.active, -.os-rows.active:hover { background-color:#777 !important; } -.os-rows.active td { color: #fff; } - /* EVENTS */ -#event-nav { transition:width 200ms; overflow:hidden; z-index:3; width:180px; position:fixed; left:242px; top:79px; text-align:right; background-color:#efefef; max-height:580px; box-sizing:border-box; box-shadow: 0 0 0 1px #d0d0d0; border-radius:2px;} -#event-nav .nav-search { border-top:1px solid #d0d0d0; border-bottom:1px solid #d0d0d0;} -#event-nav .scrollable .searchable:first-of-type { border-top:none !important;} #event-nav-head { background-color:#ececec; position:relative; height:27px; padding:15px 20px 15px 15px; color:#636363; font:18px Ubuntu,Helvetica,sans-serif; line-height:111%; text-align:left; } -#event-nav-title { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:85px; float:left; padding-top:4px; } - -#event-nav.expand { width:300px; box-shadow: 0 5px 18px 0 #a5a5a5, 0 0 0 1px #d0d0d0; transition:width 200ms; } -#event-nav .nav-search input { - transition:width 200ms; - -webkit-appearance: textfield; - height: 30px; - width: 100%; - padding-right: 20px; -} -#event-nav.expand .nav-search input { - /*width:278px;*/ - transition:width 200ms; -} -#event-nav.expand .name { width:271px; } .event-container { position:relative; cursor:pointer; padding:4px 12px; overflow:hidden; border-top: 1px solid #D0D0D0; } .event-container:hover { background-color: #dedede; } .event-container.active { background-color: #dedede; } .event-container .name { width:151px; text-align:left; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; float:left; padding:5px; color:#6b6b6b; font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; } - -#event-update-area { float:left; } -#edit-event-table-container { width:950px; max-height:400px; overflow:auto; } .events .buttons { margin-top:0; padding:13px; box-shadow:inset 0 1px 0 #ccc; border-bottom-left-radius:2px; border-bottom-right-radius:2px; } -#evens-blueprint-config .ui-tabs .ui-tabs-nav{height: 40px; border: none; background-color:transparent; padding-left: 12px;} -#evens-blueprint-config .ui-tabs .ui-tabs-panel{padding:0;} -#evens-blueprint-config .ui-tabs .ui-tabs-nav li a{background-color: transparent; color: #666; padding: 0px 0px 6px 0px; font-size:15px} -#evens-blueprint-config .ui-tabs.ui-widget-content .ui-tabs-nav > .ui-state-default {border-top: none;} -#evens-blueprint-config .ui-tabs .ui-tabs-nav li.ui-tabs-active {border-top: none; border-bottom: none !important; background-color:transparent;} -#evens-blueprint-config .ui-tabs .ui-tabs-nav li.ui-tabs-active a{color:#333; border-bottom: 2px solid #19cc63 !important;} -#evens-blueprint-config .ui-tabs .ui-tabs-nav li {border-bottom:none !important; width: auto; margin-right: 30px;} -#evens-blueprint-config .ui-tabs .ui-tabs-nav {margin-top:0px; margin-top:10px; margin-bottom: 10px} -#events-general-filter.cly-select .right.combo:before{background-color: #444;color: #fff;border-radius: 4px;padding: 1px;position: relative;font-size: 10px;} -#event-group-general-filter.cly-select .right.combo:before{background-color: #444;color: #fff;border-radius: 4px;padding: 1px;position: relative;font-size: 10px;} - -#events-blueprint-drawer { z-index: 10000;} -#events-blueprint-drawer #add-parameter-title { display: block; } -#events-blueprint-drawer #create-parameter { display: block; } -#events-blueprint-drawer.editing #edit-event-blueprint-title { display: block; } -#events-blueprint-drawer.editing #save-parameter { display: block; } -#events-blueprint-drawer.editing #add-parameter-title { display: none; } -#events-blueprint-drawer.editing #create-parameter { display: none; } -#events-blueprint-drawer #rc-parameter-description-section .label span, #events-blueprint-drawer #rc-parameter-description-section .label a {cursor: pointer;} -#events-blueprint-drawer input::placeholder, #rc-condition-drawer input::placeholder {font: 13px Ubuntu,Helvetica,sans-serif;} -#events-blueprint-drawer input::-webkit-input-placeholder, #rc-condition-drawer input::-webkit-input-placeholder {font: 13px Ubuntu,Helvetica,sans-serif;} -#events-blueprint-drawer input::-moz-placeholder, #rc-condition-drawer input::-moz-placeholder {font: 13px Ubuntu,Helvetica,sans-serif;} -#events-blueprint-drawer input:-ms-input-placeholder, #rc-condition-drawer input:-ms-input-placeholder {font: 13px Ubuntu,Helvetica,sans-serif;} -#events-blueprint-drawer input, #rc-condition-drawer input{font: 13px Ubuntu,Helvetica,sans-serif;color: #444} -#events-blueprint-drawer textarea {font: 13px Ubuntu,Helvetica,sans-serif;color: #444;width: 100%; border-radius: 2px; resize: none; color: #444; border: none; box-shadow: inset 0 0 0 1px #d0d0d0; padding: 7px;padding-right: 25px;box-sizing: border-box;height: 30px;overflow: hidden;} -#events-blueprint-drawer textarea:focus {outline: none;} - -#events-custom-settings table.event-groups-table{ border-left: 1px solid #D0D0D0; border-right: 1px solid #D0D0D0;} -#events-overview-table{border:1px solid #D0D0D0; overflow:auto; border-radius: 2px 2px 0 0;} -#events-overview-table table.events-table th{border-top:none;} -#event-groups-settings-table table.event-groups-table, #events-custom-settings table.events-table, #events-overview-table table.events-table{ width:100%; padding:0; margin:0;} -#event-groups-settings-table table.event-groups-table th, #events-custom-settings table.events-table th, #events-overview-table table.events-table th { padding:10px 10px; color: #484848; font-weight:normal; font:11px Ubuntu,Helvetica,sans-serif; border-right:none; background-color:#f3f3f3; text-transform: uppercase; line-height: 12px; border-bottom: 1px solid #E2E2E2; border-top: 1px solid #D0D0D0;} -#event-groups-settings-table, #events-custom-settings-table{border-top:none; margin-bottom:30px;} -#event-groups-settings-table table.event-groups-table thead tr, #events-custom-settings-table table.events-table thead tr, #events-overview-table table.events-table thead tr{ background-color:transparent; } -#event-groups-settings-table table.event-groups-table td, #events-custom-settings-table table.events-table td,#events-overview-table table.events-table td { padding: 10px 10px; margin:0; color:#6B6B6B; font-family: Ubuntu; font-size: 12px; line-height: 18px; margin: 0;} -#event-groups-settings-table table.event-groups-table td:first-child, #events-custom-settings-table table.events-table td:first-child, #events-overview-table table.events-table td:first-child{ width:30px; text-align:center; } -#event-groups-settings-table table.event-groups-table td:nth-child(2), #events-custom-settings-table table.events-table td:nth-child(2),#events-overview-table table.events-table td:nth-child(2) { width:30px; } -#event-groups-settings-table table.event-groups-table th:nth-child(2), #events-custom-settings-table table.events-table th:nth-child(2),#events-overview-table table.events-table th:nth-child(2) { padding:0; } -#event-groups-settings-table table.event-groups-table td.events-edit-name-field, #events-custom-settings-table table.events-table td.events-edit-name-field{ width:25%; word-break: break-word;} -#events-event-settings table td textarea{color:#6B6B6B; line-height: 140%;} -#events-event-settings table td input{color:#6B6B6B;} -#events-overview-table table.events-table td:last-child{width:50px; text-align:right; padding: 0px 10px;} -.delete-event-overview{color: #DDD; font-size:20px; line-height:20px;} -.delete-event-overview:hover { color:#E95C6C; transition:color 1s; cursor:pointer;} -#event-groups-settings-table table.event-groups-table tr[id] { cursor: default; } -#event-groups-settings-table table.event-groups-table td:last-child, #events-custom-settings-table table.events-table td:last-child {padding: 10px 0;} -#event-groups-settings-table table.event-groups-table td:first-child, #events-custom-settings-table table.events-table td:first-child {padding: 10px 10px;} -#event-groups-settings-table table.event-groups-table tr, #events-custom-settings-table table.events-table tr,#events-overview-table table.events-table tr{ background-color:#fff} -#event-groups-settings-table table.event-groups-table tr:nth-child(even), #events-custom-settings-table table.events-table tr:nth-child(even),#events-overview-table table.events-table tr:nth-child(even){ background-color:#F9F9F9} -#event-groups-settings-table table.event-groups-table td:last-child, #events-custom-settings-table table.events-table td:last-child{ width: 30px; text-align:center; } -#event-groups-settings-table .event-row-placeholder, #events-custom-settings-table .event-row-placeholder, #events-overview-table .event-row-placeholder { height:40px; } -#event-groups-settings-table .event-order, #events-custom-settings-table .event-order,#events-overview-table .event-order { color:#BBB; cursor:move; } -#event-groups-settings-table .event-order:hover, #events-custom-settings-table .event-order:hover,#events-overview-table .event-order:hover {color:#999999;} -#event-groups-settings-table a.check-green, #events-custom-settings-table a.check-green {position:relative; top: 2px;} -#events-event-settings div.selectize-input{ - -webkit-box-shadow:none; - box-shadow:none; - padding: 5px 5px; - border-radius:2px; -} -#events-event-settings div.selectize-input.has-items -{ - padding: 5px 5px 2px; -} -#events-event-settings div.selectize-input.items{width:286px;} -#events-event-settings div.selectize-input.items > div { -cursor: default; -position: relative; -float: left; -border-radius: 2px; -background-color: #77787b; -color: #f1f1f1; -padding: 2px 4px 2px 4px; -font-size: 12px; -padding-right: 20px !important; -} -#events-overview-table tr.moving {} -#events-overview-table th:nth-child(2){width: 45%;} -#event-groups-settings-table table.event-groups-table .event_visibility_row_visible, #events-custom-settings-table table.events-table .event_visibility_row_visible {color:#83C985;} -#event-groups-settings-table table.event-groups-table .event_visibility_row_hidden, #events-custom-settings-table table.events-table .event_visibility_row_hidden {color:#DB6E6E} -#events-custom-settings-table tr.moving {border-left: 1px solid #D0D0D0; } - -#event-groups-settings-table .dataTables_wrapper, #events-custom-settings-table .dataTables_wrapper {margin-top:0px;} -#event-groups-settings-table .dataTable-top, #events-custom-settings-table .dataTable-top {border-top-left-radius: 0px; border-top-right-radius: 0px;} -#edit-events-button { padding: 4px 1px; } -#edit-events-button i { font-size: 23px; margin: 0; line-height: 16px; } -.overview_empty{color: #a2a2a2; -vertical-align: text-bottom; -font-size: 16px; -text-align: center; -margin: 50px 0;} -#events-general-action,#event-groups-general-action{ background-color: #2FA732; border-color: #2FA732;} -#events-general-action .text,#event-groups-general-action .text{color: #fff;} -#events-general-action .right.combo::before,#event-groups-general-action .right.combo::before{color: #fff;} -#events-general-action.disabled,#event-groups-general-action.disabled{ background-color: #FDFDFD; border-color: #D0D0D0; } -#events-general-action.disabled .text,#event-groups-general-action.disabled .text{color: #444;} -#events-general-action.disabled .right.combo::before,#event-groups-general-action.disabled .right.combo::before {color: #717171;} - - -.delete-event, .delete-event-selected { color:#D67678; cursor:pointer; font-size:16px;} -.delete-event:hover, .delete-event-selected:hover { color:#D63E40; } - -#events-settings-table table tr td table td{padding: 15px 20px;} -#events-custom-settings .events-general-description, -#event-main .events-general-description { background-color: #f9f9f9;padding: 9px 14px 8px 14px;color: #868686;font-size: 13px; line-height: 16px; min-height:17px; border: 1px solid #d0d0d0; border-bottom:none;} -#events-custom-settings .events-general-description:empty, -#event-main .events-general-description:empty { background-color: white; border-bottom: 1px solid white; margin-bottom: -1px; position: relative; } -#events-apply-changes {margin-top:8px;} -#events-apply-order {margin-top:7px; margin-right: 10px; display:none;} -#eventOverviewWidgets{ margin: -1px;} -#eventOverviewWidgets>table {border-collapse: separate;border-spacing: 0; border-radius: 0 0 2px 2px;} -#eventOverviewWidgets .cly-widget{background-color: #ffffff; padding:25px 25px 25px 25px;margin:0px; min-height:180px; border: 1px solid #d0d0d0; border-collapse: separate;border-spacing: 0; border-top:none; border-left:none;} -#eventOverviewWidgets .cly-widget:hover{cursor: pointer; } -#eventOverviewWidgets>table tr td:last-child {border-right:none;} -#eventOverviewWidgets>table tr:last-child td{border-bottom:none;} -#eventOverviewWidgets .cly-widget .value {color: #3a3a3a; font-size:38px;} -#eventOverviewWidgets .cly-widget .title {color: #3a3a3a; max-width:80%; float:left; text-overflow: ellipsis;white-space: nowrap;overflow: hidden; margin-right:8px;} -#eventOverviewWidgets .cly-widget:hover .title{color:#2FA732;} -#eventOverviewWidgets .cly-widget td{padding: 0 10px;} -#eventOverviewWidgets .cly-widget>table>tr {display:block;} -#eventOverviewWidgets .cly-widget .spark {margin-top:20px; margin-bottom: 20px;} -#eventOverviewWidgets .cly-widget .title {padding:0;} -#eventOverviewWidgets .cly-widget .trend {color: #aedab7; text-align:center; padding-left:10px;} -#eventOverviewWidgets .cly-widget .trend .val {display:block;} -#eventOverviewWidgets .cly-widget .d.trend {color:rgba(201, 76, 76, 0.8);} -#eventOverviewWidgets .cly-widget .overview-item-property {color:#636363; text-transform: uppercase; padding-left:10px; max-width:95%; text-overflow: ellipsis;white-space: nowrap;overflow: hidden; font-size:12px;} -#eventOverviewWidgets .tooltip_templates{display:none;} -#eventOverviewWidgets .show-my-event-description{color:#cccccc; cursor:pointer; visibility:hidden; position:relative; top:-2px;} -#eventOverviewWidgets .cly-widget:hover .show-my-event-description{visibility:visible;} -#eventOverviewWidgets .empty_cell{ border-left:none; border-right:none; background-color:#F9F9F9; } -#eventOverviewContainer {padding: 0px 0px; border-radius: 0 0 2px 2px;} -#eventOverviewWidgets .cly-widget>table {width:100%;} -#eventOverviewWidgets .cly-widget>table td table td {padding: 0px;} - -#event-overview-drawer .cly-select,#event-overview-drawer .cly-select .select-items {width:100%;} -#event-overview-drawer .adding-to-overview{ margin: 0;} -#event-overview-drawer .adding-to-overview:after { - content: ""; - display: table; - clear: both; -} -#event-overview-drawer .adding-to-overview>div {float:left; width:38%; margin:0; padding:0;} -#event-overview-drawer .adding-to-overview>div:last-child {width: 24%;} -#event-overview-drawer .wrap-overview-item {padding: 0 4px 0 0 ;} -#add_to_overview{display:inline-block; text-align:center; float:none; margin-left: 0px; width: 75px;} -#event-overview-drawer .buttons{background-color:#ffffff;} -#events-overview-table table.events-table td:nth-child(2) { word-break: break-word; } -#events-overview-show-configure{float:right; margin-top:6px;} -.show-event-description:hover + .event-overview-description-wrapper .event-overview-description {border: 1px solid black; display:block} -#event-blueprint-nav-title {padding-top:4px;} -.events-empty-block{ max-width: 586px; margin: 75px auto 0 auto;} -.events-empty-block table{width:100%; table-layout:fixed} -.events-empty-block table td {padding: 0 25px 0 25px;} -.events-empty-block .events-empty-image {width:242px; height:242px;} -.events-empty-block .events-overview-noevents{ background-image:url('../images/dashboard/events-overview-noevents.svg');} -.events-empty-block .events-overview-configure{ background-image:url('../images/dashboard/events-overview-configure.svg');} -.events-empty-block .all-events-empty{ background-image:url('../images/dashboard/all-events-empty.svg');} -.events-empty-block p {color:#A2A2A2; font-size:14px; line-height:20px; } -.events-empty-block p.events-empty-title {margin-bottom:25px; font-size:18px; font-weight:400; color:#636363;} - -#event-group-drawer .use-description {display:inline; float: left; margin-left: 0px; margin-top: -10px;} -#event-group-drawer .use-description .container { - display: block; - position: relative; - margin-right: 20px; - margin-bottom: 12px; - line-height: 20px; - cursor: pointer; - font-size: 13px; - color: #636363; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -#event-group-drawer .use-description .container input { - position: absolute; - opacity: 0; - cursor: pointer; -} -#event-group-drawer .use-description .container input + .fa-square:before { - color: #32B630 !important; - font-size: 13px; - font-weight: 400; -} -#event-group-drawer .use-description .container input:checked + .fa-square:before { - content: "\f14a"; - display: inline-block; - font-size: 13px; - font-weight: 800; -} - /* EVENTS END */ #help-toggle { float:right; width:34px; height:18px; margin-top:4px; margin-right:16px; cursor:pointer; } @@ -1474,194 +633,9 @@ margin: 50px 0;} .percent-bar { height:11px; float:left; background-color:#AEE8B0; margin-right:4px; margin-top:2px; } /* EXPORT */ -#export-checkbox-container { padding:10px; padding-bottom:2px; overflow:auto; } -.export-checkbox { width:14%; float:left; margin-bottom:8px; font:16px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#444; } -.export-description { font:15px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#999; padding:10px; padding-bottom:5px; } .stretch {} -#export-button { border: 1px solid #ccc; background-color: #f5f5f5; padding: 4px 10px; cursor: pointer; font-size: 11px; border-radius: 2px; } -#cly-export.dialog.export-dialog{display: none;} -.export-dialog {padding: 15px; width: 270px; overflow: visible; display: inline-block;} -.export-dialog .cly-select {width: 100%; margin:0px auto; box-sizing:border-box; margin-bottom: 10px; height:30px;} -.export-dialog .cly-select .select-items {width: 101%;} -.export-dialog p {margin:0px; font:14px Ubuntu,Helvetica,sans-serif; font-weight: bold; line-height:111%; margin-bottom: 10px;} -.export-dialog p.details {margin:0px; font:11px Ubuntu,Helvetica,sans-serif; color:#B7B6B6; margin-bottom: 10px;} -.export-dialog .export-data {width: 100%; margin:0px auto; padding-left:0px; padding-right:0px; text-align: center; height:30px;} -#export-type-selector {width: 100%; float: none; margin:0px auto; margin-bottom: 10px; height:30px;} -#export-type-selector .button {width: 33%; text-align: center;} -.export-dialog .export-columns-selector { - overflow:hidden; - margin: 0 -15px 10px -15px; - display:none; -} -.export-columns-selector .export-columns-search { - padding: 7px 15px; - border-top: 1px solid #D0D0D0; - background-color: #fbfbfb; -} - -.export-columns-selector .export-columns-search table, .data-table-column-selector .export-columns-search table{ - width:100%; - margin:0px; -} -.data-table-column-selector .export-columns-search table td{ - padding:0px; - width:auto; - -} - -.data-table-column-selector .export-columns-search table td:nth-child(1){ - padding-right:10px; -} - -.data-table-column-selector .export-columns-search{ - padding: 7px 15px; - border-bottom: 1px solid #D0D0D0; - background-color: #fbfbfb; -} -.export-columns-selector .export-columns-search i, .data-table-column-selector .export-columns-search i{ - font-size: 15px; - color: #BBB; - line-height:15px; - position:relative; - top:2px; -} - -.export-columns-selector .export-columns-search td:nth-child(2) { - width:13px; - -} -.export-columns-selector .export-columns-search input, .data-table-column-selector .export-columns-search input { - border: none; - background-color: #ffffff; - width:100%; - border-radius:2px; - color:#6B6B6B; - padding: 0 4px; - height: 27px; -} - -.export-columns-selector .export-columns-search input::placeholder, .data-table-column-selector .export-columns-search input::placeholder { -color: #dddddd; -} - -.export-dialog .columns-height-wrapper { - height: 240px; - border-bottom: 1px solid #D0D0D0; -} -.export-dialog .export-columns-selector p, .export-dialog .export-format-option{ - font-size:12px; - color:#6b6b6b; - padding:7px 15px; - font-weight: normal; -} - -.export-dialog .export-columns-selector p:first-child{ - font-size:13px; - padding-bottom:0px; - margin-top:4px; - -} -.export-dialog .export-columns-selector p:nth-child(even){ - cursor:pointer; -} -.export-dialog .export-columns-selector p:nth-child(even):hover { - color:#444444; -} -.export-dialog .export-columns-selector p:nth-child(even) a{ - position: relative; - top: 2px; -} -.export-dialog .export-columns-selector p:first-child span { - float:right; -} - -.export-dialog .export-columns-selector .columns-wrapper { - border-top:1px solid #D0D0D0; - background-color:#FBFBFB; - -} -.export-dialog .export-columns-selector p .check-green, .export-dialog .export-format-option .check-green { - margin-right: 10px; -} -.export-dialog .export-format-option{ - margin: 0 -20px 10px -15px; - cursor:pointer; - font-size:12px; - display:none; -} -.export-dialog .export-format-option span { - position:relative; - top:-2px; -} - -.export-dialog .export-format-option i{ - color: #cccccc; - font-size: 14px; - margin-left: 5px; - top:-1px; - position:relative; - -} -.export-dialog .export-columns-selector .columns-wrapper div{ - font-size:12px; - color:#6b6b6b; - padding:7px 15px; - cursor:pointer; -} -.export-dialog .export-columns-selector .columns-wrapper div:hover { - color:#444444; -} -.export-dialog .export-columns-selector .columns-wrapper div div { - display: inline-block; - margin-right: 10px; - padding:0px; - position:relative; - top:2px; -} - -.export-dialog .hide-column-selectors .columns-height-wrapper{ - display: none; -} -.export-dialog .hide-column-selectors .export-columns-search{ - display:none; -} /* EXPORT END */ - -.cly-button-group .icon-button { border-radius:0; margin:0; border-left:none; } - .cly-button-group .icon-button:first-child, .cly-button-group .icon-button.first { border-radius:4px 0 0 4px; border-left: 1px solid #A5A5A5} - .cly-button-group .icon-button.dark:first-child, .cly-button-group .icon-button.dark.first { border-left-color:#1B1B1B; } - .cly-button-group .icon-button:last-child, .cly-button-group .icon-button.last { border-radius:0 4px 4px 0; } - -.button-selector { font:13px Ubuntu,Helvetica,sans-serif; line-height:111%; color:#6B6B6B; padding:0;overflow:auto; user-select:none; } -.button-selector .button { cursor:pointer; user-select:none; background-color:#ececec; float:left; padding:7px; padding-top:6px; border:1px solid #D0D0D0; margin-left:-1px; } -.button-selector .button:nth-child(1), -.button-selector .button.first { margin-left:0; border-left:1px solid #D0D0D0; border-top-left-radius:2px; border-bottom-left-radius:2px; } -.button-selector .button:last-child, -.button-selector .button.last { border-top-right-radius:2px; border-bottom-right-radius:2px; border-right:1px solid #D0D0D0; } -.button-selector .button:hover { background-color:#F9F9F9; } -.button-selector .button:active { background-color:#F9F9F9; } -.button-selector .button.active { background-color:#F9F9F9; } -.button-selector .button.disabled { opacity:0.3; cursor:default; } -.button-selector .button.icon { padding:5px; line-height: 12px; width: 18px; text-align: center; } -.button-selector .button.icon i.material-icons { font-size: 16px; } -.button-selector .button.icon span.ion-icons { font-size: 17px; } -.button-selector .button.icon i.fa { font-size: 18px; line-height: 14px; padding-bottom: 3px; } -.button-selector.light .button { cursor:pointer; user-select:none; background-color:#fbfbfb; float:left; padding:7px; padding-top:6px; border:1px solid #D0D0D0; margin-left:-1px; } -.button-selector.light .button:nth-child(1), -.button-selector.light .button.first { margin-left:0; border-top-left-radius:2px; border-bottom-left-radius:2px; } -.button-selector.light .button:last-child, -.button-selector.light .button.last { border-top-right-radius:2px; border-bottom-right-radius:2px; } -.button-selector.light .button:hover { background-color:#FFF; } -.button-selector.light .button:active { background-color:#FFF; } -.button-selector.light .button.active { background-color:#FFF; border:1px solid #2EB52B; position: relative; z-index:10;} -.button-selector.light .button.disabled { opacity:0.3; cursor:default; } - -.cly-list-options-row{color: #6B6B6B;border-radius: 2px;border: solid 1px #d0d0d0;padding: 2px 10px} -#content .cly-list-options {cursor: pointer; color:#a7a7a7; font-size: 20px; vertical-align: middle; line-height: 12px; } -#content .cly-list-options:hover {color:#6B6B6B;} -#content .cly-list-options:before { font-family: 'Ionicons'; content: "\f396"; } -.cly-button-menu-trigger.active { opacity: 0.8; } -.cly-button-menu-trigger.active + .cly-button-menu, .cly-button-menu.active { opacity: 1; transition: opacity 0.2s; z-index: 2; } + .cly-button-menu.active { opacity: 1; transition: opacity 0.2s; z-index: 2; } .cly-button-menu { padding:10px 0; opacity: 0; transition: opacity 0.3s, z-index 0.9s; z-index: -1; position: absolute; background-color: #FFF; right:0; top:37px; border-radius: 2px; outline:none; border: 1px solid #d0d0d0;} .cly-button-menu .item { cursor:pointer; padding: 8px 20px; font-size: 13px; white-space: nowrap; color:#474747; display: block;} .cly-button-menu .item:hover { background-color: #f3f3f3; } @@ -1677,42 +651,9 @@ color: #dddddd; /* GRAPH NOTES */ -.graph-key-event-label, -.graph-note-label { z-index:2; font-family:Oswald; cursor:pointer; width:14px; height:14px; line-height: 14px; text-align:center; background-color:#E66; color:#FFF; font-size:8px; border-radius:40px; font-weight:normal; opacity:0.8; } - .time-picker span { display: block; padding:5px 10px 5px 5px; text-align: center; cursor:pointer; color:#777; } .time-picker span:hover { font-size: 16px; } .time-picker span.selected { font-weight: 500; font-size: 17px; } - -#graph-tooltip { pointer-events:none; padding:4px 7px; overflow:hidden; border:1px solid #3C3C3C; border-radius:2px; background-color:rgba(60, 63, 64, 0.86); color:#FFF; font-size:11px; display:none; position:absolute; z-index:100; } - #graph-tooltip.v2 { padding:0; } -#graph-tooltip>span { display: block; padding:4px 7px; text-align: center; } -#graph-tooltip .graph-tooltip-content { padding:8px 10px; font-size:12px; } -#graph-tooltip .label-value { text-align: center; } -#graph-tooltip .separator { margin:5px 0; border-top:1px solid #222; border-bottom:1px solid #666; height:0; opacity:0.6; } -#graph-tooltip .note-line { padding:2px 10px; margin-bottom:5px; text-align:left; font-size:11px; color:#BBB; max-width: 200px; } -#graph-tooltip .note-line:first-child { border-top:1px solid #3C3C3C; } -#graph-tooltip .note-line:last-child { } -#graph-tooltip-title { color:#CCC; border-bottom:1px solid #3C3C3C; font-size:10px; } - -#graph-tooltip.white { background-color: #FFF; border:1px solid #D0D0D0; color:#333; } - #graph-tooltip.white .title { text-align: center; padding:0px 5px 5px 5px; color:#636363; font-size:12px; } - #graph-tooltip.white .separator { border-top-color:#D0D0D0; border-bottom: none; opacity: 1; } - -#graph-tooltip .inner { margin:6px 0; padding:0 1px; overflow: hidden; color:#636363; font-size:12px; text-transform:uppercase; } -#graph-tooltip .inner .color { float:left; width:12px; height:12px; margin-right:10px; } -#graph-tooltip .inner .series { color:#636363; text-transform:uppercase; float:left; line-height:12px; font-size:12px; margin-right:20px; } -#graph-tooltip .inner .value { color:#636363; float:right; line-height:12px; font-size:12px; } - -.note-list .note { border-bottom:1px solid #EEE; width:100%; padding:7px 0; position:relative; } -.note-list .note .date { color:#999; font-size:11px; } -.note-list .note .content { margin-top:3px; max-width:220px; text-overflow: ellipsis; white-space: nowrap; overflow:hidden; } -.note-list .note .delete-note { display:none; position:absolute; right:0; width:20px; height:20px; top:23px; } -.note-list .note .delete-note i { color:#D67678; cursor:pointer; } -.note-list .note .delete-note i:hover { color:#D63E40; } -.note-list .note:hover .delete-note { display:block; } - -.note-create .text-count-wrapper { margin-top:1px; font-size:11px; text-align: right; height:16px; color:#BBB; display: block; } /* GRAPH NOTES END */ /* DRAWER UI */ @@ -1745,88 +686,21 @@ color: #dddddd; /* DRAWER UI END */ /* MISC */ -#edit-account-details { display:none; } - #edit-account-details .title { float:left; width:100px; } - #edit-account-details .input { margin-left:105px; } -.tickLabel { color:#999; } - .xAxis .tickLabel { font-family:Oswald; overflow: hidden; text-overflow: ellipsis; max-width: 100px; max-height: 60px; white-space: pre-wrap; } - .yAxis .tickLabel { font-family:Oswald; text-align: right !important; font-size:11px; color:#CCC; z-index:-1; } #no-app-warning { display:none; margin-left:187px; } -#first-app-success { display:none; margin-left:187px; margin-top:-5px; } -#add-app-button .text { overflow:hidden; text-overflow:clip; white-space:nowrap; max-width:60px; } -#listof-apps .icon-button { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:47px; } - -.item .beta-button { opacity:0; transition:opacity 0.2s; background-color:#222; background-image:linear-gradient(top, #222 10%, #111 100%); background-image:linear-gradient(to bottom, #222 10%, #111 100%); border:1px solid #000; color:#CCC; box-shadow:inset 0 1px 0 #333; float:right; margin-top:7px; margin-right:7px; font-size:9px; border-radius:10px; padding:3px 5px; } -.item.active .beta-button { opacity:0.8; transition:opacity 0.2s; background-color:#D63E40; background-image:linear-gradient(top, #E95C6C 10%, #D63E40 100%); background-image:linear-gradient(to bottom, #E95C6C 10%, #D63E40 100%); border:1px solid #AD0303; color:#FFF; box-shadow:inset 0 1px 0 #F196A0; } -.item.active .beta-button:hover { opacity:0.9; } - -#total-user-estimate-ind { vertical-align:text-top; font-size:9px; margin-left:-7px; } -#total-user-estimate-ind:hover { color:#6BB96E; } - -.rotated-tick { margin-top:-16px; font:normal 17px Oswald; } - -.messenger-message-inner { line-height: 17px; } -.messenger-message-inner a { text-decoration: underline; } -.owner-indicator {font-size:16px; margin-left:9px; padding-top:11px; float:left; display:none; } -.resource-link {cursor:pointer;} - -.popup-link { float:left; font-family:Ubuntu; font-size:13px; color:#999; padding-top:7px; cursor:pointer; } -.popup-link:hover { text-decoration: underline; } - -.required-border { border-color:#B94A48 !important; } .options {display: none; background-color:#FFF; position: absolute; top:52px; right: 62px; list-style: none; margin:0; padding:10px 0; border-radius:2px; border:1px solid #D0D0D0; } .options:before { border: 6px solid rgba(194, 225, 245, 0); border-bottom-color: #D0D0D0; right: 9px; top: -13px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } .options:after { border: 5px solid rgba(194, 225, 245, 0); border-bottom-color: #FFF; right: 10px; top: -10px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } .options li { font:13px Ubuntu,Helvetica,sans-serif; color: #474747; padding: 8px 20px; cursor:pointer; } .options li:hover{ background-color: #D63E40; color:#FFF; } -.options li:hover span.li-explanation { color: #f7f7f7; } .options li span { line-height:23px; } -.options li span.li-explanation{ color:#828282; display:block; font-size: 11px;} - -.web-10{width: 10%;} -.web-15{width: 15%;} -.web-20{width: 20%;} -.web-25{width: 25%;} -.web-30{width: 30%;} -.web-35{width: 35%;} -.web-40{width: 40%;} -.web-45{width: 45%;} -.web-50{width: 50%;} /* ALL APPS */ -.allapps .dataTable-top {border-radius: 0;} -.allapps .logo{width: 20px; height: 20px; background-size: 20px 20px; float: left; margin-right: 10px; margin-top: -2px; background-position: center; border-radius: 4px; border: 1px solid #555;} -.allapps .trend { width:12px; height:9px; display: inline-block; margin-top: 5px; margin-right: 5px;} -.allapps tbody tr {cursor: pointer;} -.allappview .widget-content .big-numbers .inner{height: 30px;} -.allappview .widget-footer{border-radius: 0;} -.allappview #empty-graph { position: absolute; text-align: center; font-size: 15px; width:100%; top:50%; margin-top: -20px; display: none; height: 20px; line-height: 20px; text-shadow: none; color: #B3B3B3; } -.allapps div.color{ width: 10px; height: 10px; float: left; margin: 1px 10px 0 0; } -.allapps .material-icons { font-size: 16px; vertical-align: middle; margin-right: 10px; line-height: 6px; height: 8px; } -.allapps .material-icons.up { color:#6BB96E; } -.allapps .material-icons.down { color:#C94C4C; } /* Styles for horizontal d3 bar charts */ -.hsb-container { margin:20px 30px; position:relative; } -.hsb-container.top { margin-bottom:30px; } -.hsb-container .label { text-align:left; font-size: 12px; margin-bottom: 3px; color:#777; } -.hsb-container text { fill: #FFF; font: 10px sans-serif; text-anchor: initial; } -.hsb-tip { background-color: transparent; text-align: center; padding:9px 0; color:transparent; font-size:11px; cursor: default; overflow: hidden; } -.hsb-tip:hover { color:#FFF; } -.hsb-container foreignobject:hover + text { display: none; } -.hsb-container .no-data { color:#C5C5C5; text-align: center; font-size: 11px; padding:9px 0; user-select:none; cursor: default; } /* Styles tabs */ -.ui-tabs .ui-tabs-nav li { width:50%; margin:0; padding:0; background-color: #f8f8f8; border-radius:0; } -.ui-tabs .ui-tabs-nav li a { display: block; float:none; padding:12px 0 15px 0; font-size:13px; font-family: Ubuntu; text-transform: uppercase; color:#636363; } -.ui-tabs.ui-widget-content .ui-tabs-nav > .ui-state-default { border:none; background-image: none; padding:0; border-top: 3px solid #f8f8f8; } -.ui-tabs.ui-widget-content .ui-tabs-nav > li.ui-tabs-active { background-color: white; border-top: 3px solid #19cc63; border-bottom:1px solid #FFF !important; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active a { cursor:default; } -.ui-tabs .ui-tabs-nav { height: auto; background-image: none; background-color: transparent; border: none; padding: 0; margin: 0; border-radius: 0; margin-top:-1px; } -.ui-tabs { border-radius:0; border:none; } -.ui-tabs .ui-tabs-nav li { border-bottom:1px solid #eaeaea !important; } .back-link, .back-link:visited { cursor:pointer; margin-bottom: 16px; color:#616161; font-size:12px; display: inline-block; text-transform: uppercase; } @@ -1848,65 +722,13 @@ td.details table tr:first-child th { border:none; font-family:Ubuntu; font-size: td.details table td { padding:5px 10px; border-top: 1px solid #e8e8e8; } td.details:before { border: 8px solid rgba(194, 225, 245, 0); border-top-color: #FFE4C9; left: 20px; top: 0px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } -.graph-description { background-color: #f9f9f9; padding: 10px 14px; color: #868686; font-size: 13px; border: 1px solid #d0d0d0; border-bottom-color: #e9e9e9; overflow:auto; } -.graph-description + .widget-content { border-top:none; } - -.nav-search { background-color: #fbfbfb; position:relative; border-bottom: 1px solid #d0d0d0; } -.nav-search i { position: absolute; top: 11px; right: 13px; color: #d2d2d2; font-size: 10px; } -.nav-search input { outline: none; font-size: 13px; border: none; padding: 8px 10px; margin-right: 1px; width: 158px; background-color: #fbfbfb; color: #6b6b6b; } - .table-link { color:#2FA732; text-decoration: underline; cursor: pointer; text-transform: lowercase; } -.table-link-user { color:#2FA732; text-decoration: underline; cursor: pointer;} -.table-link.green, .table-link-user.green { color:#2FA732; } +.table-link.green { color:#2FA732; } .table-link.red { color:#D63E40; } .table-link.external { float: right; margin-right: 10px} -.extable-link i { font-size:13px !important; line-height: 18px !important;} -.extable-link { float: right; margin-right:5%;} - -.check-green { color:#9e9e9e; font-size:16px;} -.check-green:hover { color:inherit; } -.check-green.fa-square-o { color:#9e9e9e; } -.check-green.fa-check-square { color:#2FA732; } - -.grouped-numbers .inner { padding:0; margin-left:8px; margin-right:8px; } -.grouped-numbers .item:first-child .inner { margin-right:8px; margin-left:0; } -.grouped-numbers .item:last-child .inner { margin-right:0; margin-left:8px; } -.grouped-numbers table td { padding:5px 10px; text-align: center; color:#666; } -.grouped-numbers table tr:first-child td { background-color: #ECECEC; border-bottom:1px solid #D0D0D0; color:#9c9c9c; padding:6px 10px; padding-bottom: 3px; } -.grouped-numbers table tr:nth-child(2) td { font-size: 25px; } -.grouped-numbers table tr:nth-child(3) td { border-top: 1px solid #eaeaea; width: 50%; } -.grouped-numbers div:first-child {border-left: none;} -.grouped-numbers table {width: 100%; border-spacing: 1px; border-collapse: separate;} -.grouped-numbers table td span { font-size: 14px; display: block; color:#b1b1b1; } -.grouped-numbers table td { font-size: 18px;} -.grouped-numbers table td.range-main { text-transform: uppercase; } -.grouped-numbers table td.range-main i { font-size: 22px; } -.grouped-numbers table td.range-main span { display: inline-block; padding-top: 0; vertical-align: text-top; margin-left: 3px; font-size: 15px; color: #848484; } - -#clear-app-data .up, -#clear-app-data .down { display: inline-block; margin-left: 7px; opacity: 0.8; font-size: 10px; line-height: 12px; } -#clear-app-data .up { display: none; } -#clear-app-data.active .up { display: inline-block; } -#clear-app-data.active .down { display: none; } - -.status-color {white-space:nowrap;} -.status-color i { margin-right: 5px; font-size: 9px; vertical-align: bottom; margin-bottom: 3px; } /* Syntax highlighting - Highlight.js GoogleCode theme */ .hljs{display:block;overflow-x:auto;background:#fff;color:#000} -.hljs-comment,.hljs-quote{color:#800} -.hljs-keyword,.hljs-selector-tag,.hljs-section,.hljs-title,.hljs-name{color:#008} -.hljs-variable,.hljs-template-variable{color:#660} -.hljs-string,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-regexp{color:#080} -.hljs-literal,.hljs-symbol,.hljs-bullet,.hljs-meta,.hljs-number,.hljs-link{color:#066} -.hljs-title,.hljs-doctag,.hljs-type,.hljs-attr,.hljs-built_in,.hljs-builtin-name,.hljs-params{color:#606} -.hljs-attribute,.hljs-subst{color:#000} -.hljs-formula{background-color:#eee;font-style:italic} -.hljs-selector-id,.hljs-selector-class{color:#9B703F} -.hljs-addition{background-color:#baeeba} -.hljs-deletion{background-color:#ffc8bd} -.hljs-doctag,.hljs-strong{font-weight:bold} -.hljs-emphasis{font-style:italic} /* End of syntax highlighting - Highlight.js GoogleCode theme */ /* Custom on-off switch based on input checkbox */ @@ -1965,40 +787,10 @@ td.details:before { border: 8px solid rgba(194, 225, 245, 0); border-top-color: /* End of custom on-off switch based on input checkbox */ /*Custom green checkbox for input forms */ -input.custom-styled-green-check{height: 16px; width: 16px; vertical-align: middle; margin: .2em 0.4em 0.4em 0; border: 1px solid #DFE3E9; background-color: #FFFFFF; -webkit-border-radius: 2px; border-radius: 2px; -webkit-appearance: none; -webkit-transition: box-shadow 200ms;transition: 200ms ease-in-out;padding: initial;box-sizing: border-box; -} -input.custom-styled-green-check:active,input.custom-styled-green-check:focus {border: 1px solid #DFE3E9;outline:none;} -input.custom-styled-green-check:checked:before{ - content: ''; - display: block; - width: 3px; - height: 6px; - border: solid #2FA632; - border-width: 0 2px 2px 0; - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - margin-left: 4px; - margin-top: 2px; -} -input.custom-styled-green-check:checked {border-color: #C2C2C2;} /* end of Custom green checkbox for input forms*/ -.cly-grid-1 { width: 100%; } -.cly-grid-2 { width: 50%; } -.cly-grid-3 { width: 33%; } -.cly-grid-3:nth-child(2) { width: 34%; } -.cly-grid-4 { width: 25%; } -.cly-grid-5 { width: 20%; } -.cly-grid-6 { width: 17%; } -.cly-grid-6:first-child { width: 16%; } -.cly-grid-6:last-child { width: 16%; } -.cly-grid-7 { width: 14%; } -.cly-grid-7:first-child { width: 15%; } -.cly-grid-7:last-child { width: 15%; } -.cly-grid-8 { width: 12.5%; } #top-bar { height: 59px; min-width:1024px; background-color: #FFF; user-select: none; position: fixed; width:100%; z-index: 999; box-shadow: inset 0 -1px 0 0 #E7E7E7; } -#top-bar .logo-container { padding: 14px 39px 13px 40px; float:left; } #top-bar .logo { background-image: url("../images/dashboard/countly_logo.svg"); width: 144px; height: 32px; background-position: center; background-repeat: no-repeat; background-size: contain; } #top-bar .right-menu { float:left; font-size: 18px; margin-right: 15px; } @@ -2009,33 +801,16 @@ input.custom-styled-green-check:checked {border-color: #C2C2C2;} #top-bar .dropdown.large { width: 180px; padding: 21px 25px; } #top-bar .dropdown.active { box-shadow: inset 0 1px 0 0 #2fa732; } #top-bar .dropdown.active .selected { display: block; } -#top-bar .dropdown.active .empty-state { display: none; } -#top-bar .dropdown.active.no-selection .selected { display: none; } -#top-bar .dropdown.active.no-selection .empty-state { display: block; } -#top-bar .dropdown .selected, -#top-bar .dropdown .empty-state { font-size: 14px; color:#474747; } -#top-bar .dropdown.icon .selected, -#top-bar .dropdown.icon .empty-state { color:#7d7d7d; } -#top-bar .dropdown.icon:hover .selected, -#top-bar .dropdown.icon:hover .empty-state { color:#616161; } -#top-bar .dropdown.icon.clicked .selected, -#top-bar .dropdown.icon.clicked .empty-state, -#top-bar .dropdown.icon.force-clicked .selected, -#top-bar .dropdown.icon.force-clicked .empty-state { color:#2fa732; } +#top-bar .dropdown .selected { font-size: 14px; color:#474747; } +#top-bar .dropdown.icon .selected { color:#7d7d7d; } +#top-bar .dropdown.icon:hover .selected { color:#616161; } +#top-bar .dropdown.icon.clicked .selected { color:#2fa732; } #top-bar .dropdown .selected { display: none; } -#top-bar .dropdown .empty-state { display: block; } -#top-bar .dropdown .selected i, -#top-bar .dropdown .empty-state i { font-size: 18px; line-height: 18px; vertical-align: top; margin-top: -1px; display: inline-block; } -#top-bar .dropdown .empty-state i.fa { font-size: 16px; line-height: 18px; vertical-align: top; margin-top: -1px; display: inline-block; } -#top-bar .dropdown.large .selected:after, -#top-bar .dropdown.large .empty-state:after { font-family: 'Ionicons'; content: "\f3d0"; margin-left: 10px; font-size: 10px; line-height: 16px; vertical-align: top; } -#top-bar .dropdown.large.clicked .selected:after, -#top-bar .dropdown.large.clicked .empty-state:after, -#top-bar .dropdown.large.force-clicked .selected:after, -#top-bar .dropdown.large.force-clicked .empty-state:after { content: "\f3d8"; color:#2fa732; } +#top-bar .dropdown .selected i { font-size: 18px; line-height: 18px; vertical-align: top; margin-top: -1px; display: inline-block; } +#top-bar .dropdown.large .selected:after { font-family: 'Ionicons'; content: "\f3d0"; margin-left: 10px; font-size: 10px; line-height: 16px; vertical-align: top; } +#top-bar .dropdown.large.clicked .selected:after { content: "\f3d8"; color:#2fa732; } #top-bar .dropdown .menu { box-shadow: 0 3px 7px rgba(0,0,0,.08); border: 1px solid #d0d0d0; color:#474747; opacity: 0; cursor:default; position: absolute; top:67px; left: 50%; width: 280px; margin-left:-140px; background-color: #FFF; border-radius: 2px; visibility: hidden; } -#top-bar .dropdown.clicked .menu, -#top-bar .dropdown.force-clicked .menu { opacity: 1; transition:opacity 0.3s, visibility 0.3s; visibility: visible; } +#top-bar .dropdown.clicked .menu { opacity: 1; transition:opacity 0.3s, visibility 0.3s; visibility: visible; } #top-bar .dropdown .menu:before { border: 6px solid rgba(194, 225, 245, 0); border-bottom-color: #FFF; left: 50%; margin-left: -6px; top: -12px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; z-index: 2; } #top-bar .dropdown .menu:after { border: 7px solid rgba(194, 225, 245, 0); border-bottom-color: #D0D0D0; left: 50%; margin-left: -7px; top: -15px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; z-index: 1; } #top-bar .dropdown .menu .action { cursor: pointer; padding: 10px; padding-bottom: 13px; border-bottom: 1px solid #d0d0d0; font-size: 13px; text-align: center; } @@ -2046,7 +821,6 @@ input.custom-styled-green-check:checked {border-color: #C2C2C2;} #top-bar .dropdown .menu .search input { width: 100%; box-sizing: border-box; position: relative; padding-right: 32px; margin: 0; } #top-bar .dropdown .menu .list { max-height: 350px; overflow: auto; } #top-bar .dropdown .menu .list .item { display: block; cursor: pointer; border-bottom: 1px solid #d0d0d0; text-align: left; padding:10px; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -#top-bar .dropdown .menu .list #user-menu .item div{ display:inline; } #top-bar .dropdown .menu .list .item:last-child { border-bottom: none; } #top-bar .dropdown .menu .list .item:hover { background-color: #f3f3f3; } #top-bar .dropdown .menu .list .item .icon { margin-right: 5px; color: #8e8e8e; width: 15px; display: inline-block; text-align: center; font-size: 15px; line-height: 15px; vertical-align: top; } @@ -2054,2660 +828,226 @@ input.custom-styled-green-check:checked {border-color: #C2C2C2;} #top-bar .dropdown .menu.dark .list .item { border-bottom: 1px solid #2A2A2A; } #top-bar .dropdown .menu.dark .list .item:hover { background-color:#171717; } #top-bar .dropdown .menu.dark:before { border-bottom-color:#202020; } -#top-bar .dropdown .menu.dark .nav-search input { background-color: #171717; color:#FFF; } #top-bar .dropdown .menu.dark .search:after { color:#525252; } -#top-bar .dropdown .menu.dark .nav-search { box-shadow:inset -1px 0 0 0 #000; border-bottom-color:#2A2A2A; } #top-bar .dropdown .menu.dark .create { border-bottom-color:#2A2A2A; } #top-bar .dropdown .menu.dark .create:hover { background-color:#171717; } #top-bar .dropdown .menu.right { right:0; transform: none; left: auto; } #top-bar .dropdown .menu.right:before { left:auto; right: 15px; } #top-bar .dropdown .menu.right:after { left:auto; right:14px; } #top-bar .dropdown.large .menu.right:before { right:115px; } -#top-bar .dropdown .item_info { color: #969696; display: block; cursor: pointer; border-bottom: 1px solid #d0d0d0; text-align: left; padding:10px; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default;} -#top-bar .dropdown .sub_info { font-weight: normal; color: #808080;} -#top-bar .dropdown .item_info .user_name div:first-child { color: #676464;font-weight: 500;font-size:14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -#top-bar .dropdown .item_info .user_name div:last-child { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -#top-bar .dropdown .item_info .api_key { margin-top: 10px;} -#top-bar .dropdown .item_info .api_key div:first-child { color: #676464; font-size: 11px; text-transform: uppercase;font-weight: 500;} -#user_api_key_item {display: flex;cursor: pointer;} -#user_api_key_item input {width:100%; border:none; color: #969696; font-size: 10px; font-family: Ubuntu,Helvetica,sans-serif; cursor:pointer;margin-left: 5px;} -#user_api_key_item input::-moz-selection {background: #2FA732;color:#ffffff;} -#user_api_key_item input:hover {color:#0166D6;} -#manage-menu {background-color:#0B131A; color: #FFF;} -#top-bar .dropdown .menu #manage-menu.list .item{border: none; background-image: none; padding-top: 5px; padding-bottom: 5px; width: 180px;} -#top-bar .dropdown .menu #manage-menu.list .item:hover {background-color:#0B131A;} -#top-bar .dropdown .menu #manage-menu.list .item:hover .logo-icon { color: #FFF; } -#top-bar .dropdown .menu #manage-menu.list .item:hover .text { color: #FFF; } -#top-bar .dropdown .menu #manage-menu.list{ - max-height: none; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - border: none; - padding-bottom: 16px; - width: auto; -} -#top-bar .dropdown .menu #manage-menu.list.columns { - -moz-column-count: 2; - -moz-column-gap: 12px; - -webkit-column-count: 2; - -webkit-column-gap: 12px; - column-count: 2; - column-gap: 12px; -} -#top-bar .dropdown .menu.manage-menu {border: none; width: auto; background-color:#0B131A} -#top-bar .dropdown .menu.manage-menu:before {border: 6px solid rgba(194, 225, 245, 0); border-bottom-color:#0B131A; } -#top-bar .dropdown .menu.manage-menu:after {border: 6px solid rgba(194, 225, 245, 0); border-bottom-color:transparent; } -#top-bar .dropdown .menu #manage-menu.list .item .logo-icon { color:#9F9F9F; width:25px; height:22px; float:left; margin-left:16px; margin-top:2px; font-size: 18px; text-align: center; } -#top-bar .dropdown .menu #manage-menu.list .item .logo-icon .material-icons { font-size:17px; margin-top:1px; } /* Fix for old .fa icons, this can be removed once all enterprise plugins have updated icons */ -#top-bar .dropdown .menu #manage-menu.list .item .logo-icon.fa { - width: 24px !important; - height: 25px !important; - line-height: 24px !important; - font-size: 16px !important; - margin-left: 17px !important; -} -#top-bar .dropdown .menu #manage-menu.list .item .text { margin-left:12px; float:left; padding-top:6px; font:14px Ubuntu,Helvetica,sans-serif; line-height:100%; color:#9F9F9F; max-width: 125px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } -#top-bar .dropdown .menu.manage-menu .menu-category-title{padding-left:25px; padding-right:15px; padding-top:16px; font:13px Ubuntu,Helvetica,sans-serif; color:#9F9F9F; width: 100%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; display:block; text-transform: uppercase; padding-bottom: 4px; text-align:left;} #app-navigation.dropdown.large { margin-left: 80px; padding:21px 25px 19px 25px; box-sizing:border-box; height:59px; width:230px; white-space: nowrap; } -#app-navigation #active-app-name { text-overflow:ellipsis; white-space:nowrap; overflow:hidden; display: inline-block; max-width: 125px; } -#app-navigation #active-app-icon { vertical-align:top; display:inline-block; width:20px; height:20px; background-size:22px 22px; margin-right:10px; margin-top:-3px; background-position:center; border-radius:4px; border:1px solid #555; } -#app-navigation .list .item .app-icon { width: 20px; height: 20px; background-position:center; background-size:22px 22px; border-radius:4px; display: inline-block; margin-right:10px; vertical-align: top; margin-top: 1px; } #app-navigation .list .item .name { display: inline-block; vertical-align: top; margin-top:4px; white-space:nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 210px; } -#app-navigation .empty-state { padding:1px 0; } - -#version-info { position: absolute; bottom: 0; font-size: 10px; color: #747474; width: 100%; padding: 12px 0; box-sizing: border-box; text-align: center; background-color: #0B131A; z-index: 1; height: 36px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-top: 1px solid #2A2F33;} -#version-info span {} - -#notification-icon { position: relative; } -#notification-icon.unread:after { content: " "; width: 4px; height: 4px; position: absolute; top: 0; right: 0; border-radius: 4px; background-color: #FF8700; } #main-views-container .main-view.active { display: block; } -#sidebar, -/* #main-views-container #analytics-main-view.active #sidebar.hidden { transform:translate(-230px); opacity:0.8; transition: opacity 0.1s 0.2s, transform 0.55s; } */ -/* #main-views-container #analytics-main-view.active #sidebar { transform:translate(0); opacity:1; transition: opacity 0.1s 0.2s, transform 0.55s; } */ -#hide-sidebar-button { position: absolute; left: 16px; top: 21px; cursor: pointer; width: 21px; height: 18px; background-image: url("../images/dashboard/collapse-sprite.svg"); background-repeat: no-repeat;} -#hide-sidebar-button:hover { background-position: -21px 0px; } -#hide-sidebar-button.active { background-position: -42px 0px; } -#hide-sidebar-button.active:hover { background-position: -63px 0px; } +#sidebar { position: absolute; left: 16px; top: 21px; cursor: pointer; width: 21px; height: 18px; background-image: url("../images/dashboard/collapse-sprite.svg"); background-repeat: no-repeat;} .dashboard-summary .inner{ margin-left: 0; } -.dashboard-summary .inner-new{ -background-color: #ffffff; -padding: 25px 10px; -} -.dashboard-summary .device-bar-item{ - width: calc(33.3% - 1px) !important; -} +/*Status tot used in token manager and report manager */ +/* Customize the label (the container) */ -.dashboard-summary .device-bar-item { - border-top:1px solid #DBDBDB; - border-right:1px solid #DBDBDB; - border-bottom:1px solid #DBDBDB; -} +/* Hide the browser's default checkbox */ -.dashboard-summary .device-bar-item:last-child { - border-top:1px solid #DBDBDB; - border-bottom:1px solid #DBDBDB; -} +/* Create a custom checkbox */ -.dashboard-summary .device-bar-item:first-child { - border-top:1px solid #DBDBDB; - border-bottom:1px solid #DBDBDB; - border-left:1px solid #DBDBDB; -} +/* On mouse-over, add a grey background color */ -.dashboard-summary .overview-new-item{ -width: calc(25% - 1.5px); -} +/* When the checkbox is checked, add a blue background */ -.dashboard-summary .overview-new-item { - border-top:1px solid #DBDBDB; - border-right:1px solid #DBDBDB; - border-bottom:1px solid #DBDBDB; -} +/* Create the checkmark/indicator (hidden when not checked) */ + +/* Show the checkmark when checked */ -.dashboard-summary .overview-new-item:last-child { - border-top:1px solid #DBDBDB; - border-bottom:1px solid #DBDBDB; +/* Style the checkmark/indicator */ +#view-app .widget-header:first-child .left { + display: flex; + flex-direction: column; } -.dashboard-summary .overview-new-item:first-child { - border-top:1px solid #DBDBDB; - border-bottom:1px solid #DBDBDB; - border-left:1px solid #DBDBDB; +#view-app .widget-header:first-child .left > .title { + padding-top: 0; + font-size: 17px; + margin-bottom: 8px; } -.dashboard-summary .item .bar-new{ -height: auto !important; -width: 95%; +#view-app .cly-button-menu { + max-width: 320px; + top: 50px; + right: 15px; } -.dashboard-sumamry .device-bar:first { - border-right:1px solid #DBDBDB; +#view-app .cly-button-menu .item { + white-space: normal; } -.dashboard-sumamry .device-bar:first { - border-left:1px solid #DBDBDB; +#view-app .cly-button-menu .item.back > i { + font-size: 8px; + vertical-align: center; + margin-right: 4px; } -.dashboard-summary .item .bar-no-data{ +#view-app .cly-button-menu .item.back > span { font-size: 12px; - color: #5F5F5F; - font-family: Ubuntu; - border-radius:2px; - text-align:center; - width:90%; - height:20px; - padding-top:3px; - overflow:auto; - background-color:#f9f9f9 !important; - margin:0 auto; - margin-top:5px; - margin-bottom:5px; } -.dashboard-summary .item .title-new{ - font: 14px Ubuntu,Helvetica,sans-serif; - color: #5F5F5F; - margin-bottom: 20px; - font-weight: 500; - text-align: left; - margin-left: 2.5%; +#view-app .cly-button-menu .item span { + font-size: 14px; } -.dashboard-summary .item .bar .bar-inner-new{ - float: none !important; - height: 20px; - font-family: Ubuntu,Helvetica,sans-serif; - margin-top: 15px; - margin-left: 35px; - box-shadow: 0 0 0 transparent; - display: block; - position: relative; - background: #ECECEC; - border-radius: 2px; - /*overflow: hidden;*/ -} -#bar-summary { - border-radius: 2px !important; -} -.dashboard-summary .item .bar .bar-inner-new:first-child{ - margin-top: 0; -} -.dashboard-summary .item .bar .bar-inner-new:first-child:hover{ - margin-top: 0; -} -.dashboard-summary .item .bar .bar-inner-new:hover{ - height: 20px; - margin-bottom: 0; - margin-top: 15px; -} -.dashboard-summary .item .bar .bar-inner-new .bar-inner-percent{ - position: absolute; - top: 0; - font-size: 11px; - left: -35px; - width: 30%; - height: 18px; - display: block; - z-index: 4; - padding: 2px 0 0 0; -} -.dashboard-summary .item .bar .bar-inner-new::before{ - content: attr(data-item); - text-indent: 3px; - position: absolute; - font-size: 13px; - white-space: nowrap; - height: 20px; - overflow: hidden; - color: #fff; - z-index: 8; - height: 18px; - padding: 2px 0 0 0; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; +#view-app .cly-button-menu .item span.red { + color: #C43132; } -.dashboard-summary .item .bar .bar-inner-new::after{ -content: attr(data-item); -text-indent: 3px; -position: absolute; -font-size: 13px; -white-space: nowrap; -overflow: hidden; -color: #888; -height: 18px; -padding: 2px 0 0 0; +#view-app .cly-button-menu .item.inactive * { + color: #E2E2E2 !important; } -.dashboard-summary .item .bar .bar-inner-new:nth-child(2){background: #ececec;} -.dashboard-summary .item .bar .bar-inner-new:nth-child(3){background: #ececec;} - -.dashboard-summary .item .bar .bar-inner-new[data-percent='0%']::before{ width: 0% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='1%']::before{ width: 1% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='2%']::before{ width: 2% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='3%']::before{ width: 3% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='4%']::before{ width: 4% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='5%']::before{ width: 5% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='6%']::before{ width: 6% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='7%']::before{ width: 7% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='8%']::before{ width: 8% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='9%']::before{ width: 9% } -.dashboard-summary .item .bar .bar-inner-new[data-percent='10%']::before{ width: 10%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='11%']::before{ width: 11%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='12%']::before{ width: 12%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='13%']::before{ width: 13%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='14%']::before{ width: 14%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='15%']::before{ width: 15%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='16%']::before{ width: 16%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='17%']::before{ width: 17%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='18%']::before{ width: 18%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='19%']::before{ width: 19%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='20%']::before{ width: 20%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='21%']::before{ width: 21%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='22%']::before{ width: 22%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='23%']::before{ width: 23%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='24%']::before{ width: 24%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='25%']::before{ width: 25%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='26%']::before{ width: 26%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='27%']::before{ width: 27%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='28%']::before{ width: 28%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='29%']::before{ width: 29%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='30%']::before{ width: 30%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='31%']::before{ width: 31%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='32%']::before{ width: 32%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='33%']::before{ width: 33%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='34%']::before{ width: 34%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='35%']::before{ width: 35%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='36%']::before{ width: 36%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='37%']::before{ width: 37%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='38%']::before{ width: 38%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='39%']::before{ width: 39%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='40%']::before{ width: 40%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='41%']::before{ width: 41%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='42%']::before{ width: 42%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='43%']::before{ width: 43%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='44%']::before{ width: 44%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='45%']::before{ width: 45%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='46%']::before{ width: 46%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='47%']::before{ width: 47%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='48%']::before{ width: 48%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='49%']::before{ width: 49%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='50%']::before{ width: 50%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='51%']::before{ width: 51%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='52%']::before{ width: 52%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='53%']::before{ width: 53%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='54%']::before{ width: 54%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='55%']::before{ width: 55%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='56%']::before{ width: 56%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='57%']::before{ width: 57%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='58%']::before{ width: 58%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='59%']::before{ width: 59%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='60%']::before{ width: 60%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='61%']::before{ width: 61%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='62%']::before{ width: 62%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='63%']::before{ width: 63%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='64%']::before{ width: 64%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='65%']::before{ width: 65%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='66%']::before{ width: 66%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='67%']::before{ width: 67%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='68%']::before{ width: 68%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='69%']::before{ width: 69%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='70%']::before{ width: 70%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='71%']::before{ width: 71%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='72%']::before{ width: 72%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='73%']::before{ width: 73%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='74%']::before{ width: 74%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='75%']::before{ width: 75%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='76%']::before{ width: 76%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='77%']::before{ width: 77%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='78%']::before{ width: 78%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='79%']::before{ width: 79%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='80%']::before{ width: 80%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='81%']::before{ width: 81%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='82%']::before{ width: 82%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='83%']::before{ width: 83%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='84%']::before{ width: 84%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='85%']::before{ width: 85%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='86%']::before{ width: 86%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='87%']::before{ width: 87%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='88%']::before{ width: 88%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='89%']::before{ width: 89%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='90%']::before{ width: 90%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='91%']::before{ width: 91%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='92%']::before{ width: 92%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='93%']::before{ width: 93%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='94%']::before{ width: 94%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='95%']::before{ width: 95%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='96%']::before{ width: 96%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='97%']::before{ width: 97%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='98%']::before{ width: 98%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='99%']::before{ width: 99%} -.dashboard-summary .item .bar .bar-inner-new[data-percent='100%']::before{ width: 100%} - -.date-picker-component{ - display: inline-block; - height: 27px; - margin-right: 5px; - position: relative; - width: 230px; -} -.date-picker-component .date-value { cursor: pointer } -.date-picker-component .date-picker, -.date-picker-component .date-picker-ext-wrapper{ - padding: 0; - right: 0; - top: 33px; - border: 1px solid #d0d0d0; - background-color: #ffffff; -} -.date-picker-component .date-picker .calendar-container, .date-picker-component .date-picker-ext-wrapper .calendar-container { padding: 14px } -.date-picker-component .string-input { - margin: 0; - outline: none; - border: 1px solid #CCC; - border-radius: 3px; - padding: 6px 9px; - box-sizing: border-box; - width: 100% !important; - font: 13px Ubuntu,Helvetica,sans-serif; - line-height: 111%; -} -.date-picker-component .date-picker, .date-picker-component .date-picker-ext-wrapper { - padding: 0; - right: 0; - top: 33px; - border: 1px solid #d0d0d0; - background-color: #ffffff; -} - -.date-picker-component.extended .date-picker-ext-wrapper { - background-color: #0b131a; - display: block; - top: 0px; -} - -.date-picker-component.extended:not(.collapsible){ - height: 266px; - width: 240px; -} - -.date-picker-component.extended:not(.collapsible) .date-picker-ext-wrapper{ - border: none; -} - -.date-picker-component.extended.collapsible .date-picker-ext-wrapper{ - display: none; - top: 33px; -} - -.date-picker-component .date-picker .calendar-container, -.date-picker-component .date-picker-ext-wrapper .calendar-container { - padding: 14px; -} - -.app-details-plugins > div.ui-accordion { - border: 1px solid #D0D0D0; - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - width: auto; -} -.app-details-plugins > div.ui-accordion > h3.ui-accordion-header .ui-icon { - position: relative; - margin-right: 4px; - float: left; - top: auto; - margin-top: 3px; - left: auto; -} - -.app-details-plugins > div > h3.ui-accordion-header.ui-state-default { - font-family: Ubuntu,Helvetica,sans-serif; - height: 21px; - padding: 16px 8px; - color: #666; - text-align: left; - font-size: 14px; - line-height: 22px; - border-radius: 0; - border-top: 1px solid #D0D0D0; - background-color: #ECECEC; - margin: 0px; - vertical-align: middle; -} - -.app-details-plugins > div > h3.ui-accordion-header.ui-state-default:first-child, .app-details-plugins > div > h3.ui-accordion-header.ui-state-active:first-child { - border-top: none; -} - -.app-details-plugins > div > h3.ui-accordion-header.ui-state-active { - font-family: Ubuntu,Helvetica,sans-serif; - height: 21px; - padding: 16px 8px; - color: #666; - text-align: left; - font-size: 14px; - line-height: 22px; - border-radius: 0; - background: #ECECEC; - margin-top: 0; - vertical-align: middle; - font-weight: normal; - border: none; - border-top: 1px solid #D0D0D0; -} - -.app-details-plugins .ui-accordion .ui-accordion-content { - padding: 0; -} - -.app-details-plugins > div > form.ui-accordion-content.ui-widget-content.ui-accordion-content-active { - padding: 0 0 0 0 !important; - border-radius: 0; - margin-bottom: 0; - border: 1px solid #D0D0D0; - border-width: 1px 0 0 0; -} - -.app-details-plugins > div > form.ui-accordion-content.ui-widget-content.ui-accordion-content-active.overflow-visible { - overflow: visible !important; -} - -.app-details-plugins > div > form.ui-accordion-content.ui-widget-content:last-child { - border-bottom-width: 1px; -} -.app-details-plugins a { - color: #2FA732; -} - -.mgmt-plugins h4 { - color: #2FA732; - padding: 1em 3em; - border-top: 1px solid #D0D0D0; - font-size: 15px; - line-height: 12px; - font-weight:normal; -} - -.mgmt-plugins h4:first-child { - border-top: none; -} - -.mgmt-plugins-row { - display: table; - table-layout: fixed; - width: 100%; - padding: 1em 0; - font-family: Ubuntu,Helvetica,sans-serif; -} - -.mgmt-plugins-row > div { - display: table-cell; - font-weight: normal; - padding: 0 5em; - font-size: 11px; - vertical-align:middle; -} - -.mgmt-plugins-row label { - font-size: 15px; - line-height: 12px; - font-weight: normal; - color: #6B6B6B; -} -.mgmt-plugins-row label.on-off-switch-label { - font-size:13px; - padding:0; -} - -.mgmt-plugins-row span { - font-weight: normal; - font-size: 13px; - color: #929292; - padding-top: 10px; - display: block; - line-height: 17px; -} -.mgmt-plugins-row span > span { - display: inline-block; -} -.mgmt-plugins-row .on-off-switch span.text { - padding:0; -} -.mgmt-plugins-row input + span.help { - padding-left: 0; - padding-bottom: 0; -} - -.mgmt-plugins-row input:not([type='file']) { - border-radius: 2px; - margin: 0; - font: 14px Ubuntu,Helvetica,sans-serif; - line-height: 111%; - padding: 5px; - border: 1px solid #D0D0D0; - width: 274px; -} -.mgmt-plugins-row .cly-select .search input { - height: 14px; - padding: 0; - margin: 0; - border: none; - outline: none; - width: 100%; - font: 13px Ubuntu; - line-height: 111%; -} -.mgmt-plugins-row .selectize-control.multi .selectize-input > div { - padding-right: 20px !important; -} -.mgmt-plugins-row + h4 { - padding-top: 2em; - margin-bottom: 1em; -} -h4 + .mgmt-plugins-row { -padding-top: 0; -} - -.mgmt-plugins > form { - background-color: white; -} -.mgmt-plugins > form > div:nth-child(even) { - background-color: white; -} - -.mgmt-plugins > form > div:nth-child(odd) { - background-color: #F9F9F9; -} - -.mgmt-plugins > form > h4 { - background-color: white; -} - -.mgmt-plugins a.icon-button { - float: right; - margin-right: 10px; - position:relative; - bottom: 4px; - color:#FFF; -} - -.mgmt-plugins-row .selectize-input.items { - box-shadow: none; - border-radius: 2px; - margin: 0; - font: 14px Ubuntu,Helvetica,sans-serif; - line-height: 111%; - padding: 5px; - border: 1px solid #D0D0D0; - width: 274px; - z-index: 0; -} - -.mgmt-plugins-row .selectize-dropdown [data-selectable] { - padding: 0 11px; - background-color: white; -} - -.mgmt-plugins-row .selectize-dropdown [data-selectable] span { - padding: 0; - height: 33px; - line-height: 33px; -} - -.mgmt-plugins-row .selectize-dropdown [data-selectable]:hover span { - color: #444; -} - -#report-manager-view .ui-tabs .ui-tabs-nav{height: 40px; border: none; background-color:transparent; padding-left: 12px;} -#report-manager-view .report-tab{padding:0;} -#report-manager-view .ui-tabs .ui-tabs-panel{padding:0;} -#report-manager-view .ui-tabs .ui-tabs-nav li a{background-color: transparent; color: #666; padding: 0px 0px 6px 0px; font-size:15px} -#report-manager-view .ui-tabs.ui-widget-content .ui-tabs-nav > .ui-state-default {border-top: none;} -#report-manager-view .ui-tabs .ui-tabs-nav li.ui-tabs-active {border-top: none; border-bottom: none !important; background-color:transparent;} -#report-manager-view .ui-tabs .ui-tabs-nav li.ui-tabs-active a{color:#333; border-bottom: 2px solid #19cc63 !important;} -#report-manager-view .ui-tabs .ui-tabs-nav li {border-bottom:none !important; width: auto; margin-right: 30px;} -#report-manager-view .ui-tabs .ui-tabs-nav {margin-top:0px; margin-top:10px; margin-bottom: 10px} -.report-manager-table td { line-height: 15px; } -.report-manager-break { word-wrap: normal; word-break: normal; } -.report-manager-data-col { width: 15%; } -.report-manager-data-col.report-manager-automatically-created { width: 55%; } -.report-manager-report-desc { color: #AAA; margin-top:5px;} -.extable-link i { margin-right:10px; font-size:13px !important; line-height: 18px !important;} -#report-manager-view .left {width:500px;} - -.orange-side-notification-banner-wrapper{ - position: absolute; - width: 500px; - right: 29px; - top: -7px; - display:none; -} -.orange-side-notification-banner { - position: relative; - border:1px solid #e3af79; - color: #ce8a43; - background-color:#fcf5ed; - padding: 7px; - font-size:12px; - border-radius: 2px; - float:right; - border-left:4px solid #e3af79; - -} - -.orange-side-notification-banner:before { - border: 6px solid rgba(194, 225, 245, 0); - border-left-color: #e3af79; - right: -13px; - margin-left: -6px; - top: 8px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 2; -} - -.orange-side-notification-banner:after { - border: 6px solid rgba(194, 225, 245, 0); - border-left-color: #fcf5ed; - right:-12px; - margin-left: -6px; - top: 8px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 2; -} - -.dashboard-summary .item .bar .bar-inner-new-e{ - font-size: 12px; - line-height: 20px; - float: none !important; - height: 20px; - font-family: Ubuntu,Helvetica,sans-serif; - margin-top: 15px; - margin-left: 30px; - box-shadow: 0 0 0 transparent; - display: block; - position: relative; - background: #ECECEC; - border-radius: 2px; - /*overflow: hidden;*/ -} -#bar-summary { - border-radius: 2px !important; -} -.dashboard-summary .item .bar .bar-inner-new-e:first-child{ - margin-top: 0; -} -.dashboard-summary .item .bar .bar-inner-new-e:first-child:hover{ - margin-top: 0; -} -.dashboard-summary .item .bar .bar-inner-new-e:hover{ - height: 20px; - margin-bottom: 0; - margin-top: 15px; -} - -.dashboard-summary .item .bar .bar-inner-new-e .bar-inner-percent{ - position: absolute; - top: 0; - font-size: 11px; - left: -30px; - width: 30%; - height: 18px; - display: block; - z-index: 4; - padding: 2px 0 0 0; -} -.dashboard-summary .item .bar .bar-inner-new-e::before{ - content: attr(data-item); - /*text-indent: 3px;*/ - position: absolute; - font-size: 13px; - white-space: nowrap; - height: 20px; - overflow: hidden; - color: #fff; - z-index: 8; - height: 18px; - padding: 2px 0 0 0; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; -} - -.dashboard-summary .item .bar .bar-inner-new-e::before{ background-color:#ececec;margin-left:-25px;color:black; } -.dashboard-summary .item .bar .bar-inner-new-e:nth-child(2)::before{background-color:#ececec;} -.dashboard-summary .item .bar .bar-inner-new-e:nth-child(3)::before{ background-color:#ececec;} -.dashboard-summary .item .bar .bar-inner-new-e .bar-inner-percent{ color:#000; } -.dashboard-summary .item .bar .bar-inner-new-e:nth-child(2) .bar-inner-percent{color:#ececec;} -.dashboard-summary .item .bar .bar-inner-new-e:nth-child(3) .bar-inner-percent{ color:#ececec;} - - -.dashboard-summary .item .bar .bar-inner-new-e::after{ -/*content: attr(data-item);*/ -/*text-indent: 3px;*/ -position: absolute; -font-size: 13px; -white-space: nowrap; -overflow: hidden; -color: #888; -height: 18px; -padding: 2px 0 0 0; -} - -.remove-before:before { display: none; } - -.expand-row-icon { float: left; font-size: 18px !important; margin-right: 3px; position: relative; top: 1px;} - -.big-numbers.top .trend.u.inverse-trend, -.big-numbers.top .trend.u.inverse-trend .change, -.trend.u.inverse-trend, -.trend.u.inverse-trend .change { color:#DB6E6E!important; } - -.big-numbers.top .trend.d.inverse-trend, -.big-numbers.top .trend.d.inverse-trend .change, -.trend.d.inverse-trend, -.trend.d.inverse-trend .change { color:#83C986!important; } - -.allapps .material-icons.up.inverse-trend { color:#C94C4C!important; } -.allapps .material-icons.down.inverse-trend { color:#6BB96E!important; } - -.compare-view.d-table .up.inverse-trend { color: #D63E40!important; } -.compare-view.d-table .down.inverse-trend { color: #2fa732!important; } -#create-token-drawer .desc -{ - color: #A0A0A0; - padding: 0; - margin: 0 0 4px 0; - font-size: 11px; - line-height: 17px; -} -#create-token-drawer textarea -{ - border-radius: 2px; border: 1px solid #d6d6d6; outline: none; padding: 7px; font-size: 12px; height: 50px; width: 100%; box-sizing: border-box; -} - -#create-token-drawer .delete-param , #create-token-drawer .delete-endpoint{ - color: #dddddd; - cursor: pointer; -} -#create-token-drawer .delete-param:hover, #create-token-drawer .delete-endpoint:hover { -color:#E95C6C; transition:color 1s; -} - -#create-token-drawer .token_endpoint_block { - border: 1px solid #dddddd; - border-radius: 2px; - position:relative; - padding: 15px; - background-color: #ffffff; - font-size:13px; - margin-bottom:5px; -} -#create-token-drawer .param_blocks_wrapper { - margin-bottom: 5px; -} - -#create-token-drawer .token_endpoint_block .delete-endpoint-block { - position:absolute; - top:0; - right:0; - width: 25px; - height:25px; - padding-top:10px; -} - -#create-token-drawer .endpoint_blocks_wrapper { - margin-top: 11px; -} -#create-token-drawer .delete-endpoint-block-item i{ - margin-left: -6px; -} -#create-token-drawer .delete-endpoint-block-item span{ - margin-left: 10px; -} - -#create-token-drawer .delete-new-endpoint-block-menu { - padding: 10px 0; - opacity: 0; - transition: opacity 0.3s, z-index 0.9s; - z-index: -1; - position: absolute; - background-color: #FFF; - right: 0; - top: 37px; - border-radius: 2px; - outline: none; - border: 1px solid #d0d0d0; -} -#create-token-drawer .delete-new-endpoint-block-menu .item { - cursor: pointer; - padding: 8px 20px; - font-size: 13px; - white-space: nowrap; - color: #474747; - display: block; -} -#create-token-drawer .delete-new-endpoint-block-menu.active { - opacity: 1; - transition: opacity 0.2s; - z-index: 2; - right: 0; - top: 37px; -} -#create-token-drawer .delete-new-endpoint-block-menu:before { - border: 4px solid rgba(194, 225, 245, 0); - border-bottom-color: #FFF; - right: 7px; - top: -8px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 2; -} -#create-token-drawer .delete-new-endpoint-block-menu:after { - border: 5px solid rgba(194, 225, 245, 0); - border-bottom-color: #d0d0d0; - right: 6px; - top: -10px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 1; -} -#create-token-drawer .delete-new-endpoint-block-menu .item:hover { background-color: #f3f3f3; } - -.param_block td { - padding: 0px 0px 5px 0px; -} -.param_block td:nth-child(2){ - padding-left:5px; - padding-right: 5px; -} - -#create-token-drawer .cly-list-options {cursor: pointer; color:#a7a7a7; font-size: 20px; vertical-align: middle; line-height: 12px; } -#create-token-drawer .cly-list-options:hover {color:#6B6B6B;} -#create-token-drawer .cly-list-options:before { font-family: 'Ionicons'; content: "\f396"; } - -#create-token-drawer .add-query-block, #create-token-drawer .add-endpoint-block { - margin: 10px 0 20px 0; -} -#create-token-drawer .add-query-block { - font-size:13px; - margin-top:20px; - cursor: pointer; - line-height: 22px; -} - -.token-menu {display:none;} -.token-menu.active {display:block;} -#token-manager-view .dataTable-top .server-export {display:none;} -#token-manager-view table tr td:nth-child(2){width: 100px;} -#token-manager-view table tr td:nth-child(6){width: 70px;} -#token-manager-view table tr td:nth-child(4){min-width: 100px;} -#token-manager-view table tr td:nth-child(5){min-width: 100px;} -#token-manager-view table tr td:nth-child(3){width: 100px;} -#create-token-drawer #limit_life>div:nth-child(2){width:40%; float:left;} -#create-token-drawer #limit_life>div:nth-child(3){width:60%; margin-left: 40%;} -#create-token-drawer #select_limit_value{border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-right:none; height:29px;} -#create-token-drawer #select_limit_span{border-top-left-radius: 0px;border-bottom-left-radius: 0px; height:29px;} - -/*Status tot used in token manager and report manager */ -.table_status_dot { - line-height: 20px; - -} -.table_status_dot span { - display: block; - width: 8px; - height: 8px; - border-radius: 4px; - background-color: #14ca5f; - position: relative; - float: left; - margin: 7px 10px 3px 0px; -} - -.table_status_dot_green span{ - background-color: #14ca5f; -} -.table_status_dot_red span{ - background-color: #ff4b29; -} -.table_status_dot_blue span{ - background-color: #55a8ed; -} -p.error_message_div { - margin:5px; - line-height: 12px; -} - -#token-manager-view .tokenvalue{float:left; cursor:pointer; - text-align: center; - border: none; - color: #a2a2a2; - font-size: 13px; - font-family: Ubuntu,Helvetica,sans-serif; - padding:0; - width:290px; - text-align:left; - background-color:transparent; - margin-top:5px; -} -#token-manager-view .tokenvalue:active, #token-manager-view .tokenvalue:focus{ - border:none; - outline: none; -} -#token-manager-view .tokenvalue::selection { - background: #2EB52B; - color: #636363; -} -#token-manager-view .tokenvalue::-moz-selection { -background: #2EB52B; /* Gecko Browsers */ -color: #636363; -} -#token-manager-view .tokenvalue_wrapper{ display:block; width:100%; min-height:15px;} -.copy-tokenvalue{cursor:pointer;} - -.data-table-column-selector { - box-shadow: 0 3px 7px rgba(0,0,0,.08); - border: 1px solid #d0d0d0; - color: #474747; - cursor: default; - position: absolute; - top: 41px; - left: 2px; - min-width: 280px; - max-height: 212px; - margin-left: 0px; - background-color: #FFF; - border-radius: 2px; - font-size:12px; - line-height:15px; - color:#6B6B6B; - display:none; - padding-top:46px; -} -.data-table-column-selector .slimScrollDiv { - height:170px !important; -} -.select-column-table-data.active +.data-table-column-selector{ - display:block; -} - -.data-table-column-selector:active, .data-table-column-selector:focus{ - outline:0; -} -.data-table-column-selector:before { border: 6px solid rgba(194, 225, 245, 0); border-bottom-color: #FFF; left: 14px; margin-left: -6px; top: -12px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; z-index: 2; } -.data-table-column-selector:after { border: 7px solid rgba(194, 225, 245, 0); border-bottom-color: #D0D0D0; left: 14px; margin-left: -7px; top: -15px; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; z-index: 1; } - -.data-table-column-selector table { - max-width:100%; - margin: 7px; -} -.data-table-column-selector td { - padding:7px 7px 7px 30px; - text-align:left; - position: relative; - width: 50%; - cursor:pointer; -} -.data-table-column-selector td.disabled { - cursor:default; -} -.data-table-column-selector td div { - position: absolute; - width:14px; - height: 14px; - top: 50%; - margin-top:-8px; - left: 7px; -} -.data-table-column-selector td:first-child, .data-table-column-selector td:nth-child(3) { - width:14px; - padding-right:3px; -} -.data-table-column-selector .columncounter {float:right;} -.data-table-column-selector .columncounter.red { - color: #ED6262; -} -.select-column-table-data { - float:left; - border-right: 1px solid #D0D0D0; - width: 32px; - height:32px; - text-align:center; - display: table-cell; - vertical-align:middle; - overflow:hidden; - cursor:pointer; - -} -.select-column-table-data p{ font-size: 23px; line-height:23px; margin:5px; padding:0;} -.data-table-column-selector .title { - border-bottom: 1px solid #D0D0D0; - padding:15px 0px; - text-align:left; - position: absolute; - top:0; - left:0; - width: 100% -} - -.fa-check-square.check-green.disabled { - color: #d0d0d0; - cursor:default; -} -.data-table-column-selector.full-select .fa-square-o.data-table-toggle-column { - color: #d0d0d0; - cursor: default; -} - -.data-table-column-selector.full-select .not-checked { - cursor: default; - color: #d0d0d0; -} - -.data-table-column-selector.full-select .fa-square-o.data-table-toggle-column:hover { - color: #d0d0d0; -} -.event-settings-menu .item i{ -margin-left:-6px; -} - -.event-settings-menu .item span{ -margin-left:10px; - -} - -#first-app-welcome-header { font-family: Ubuntu; font-size: 36px; font-weight: normal; color:black; } -#first-app-description { color: #636363; font-size:18px; line-height: 1.5; } -#add-first-app { display: none; background-color: white; padding: 30px 60px 30px 60px; border-radius: 2px; border:1px solid #dbdbdb;} -#first-app-welcome { float: left;} -.add-app-input-wrapper {padding:5px;margin-bottom:5px;} -.add-app-input-label { - display: inline-block; - width:50%; - font-size: 14px; - color: #2fa732; - margin-bottom:5px; -} -.add-app-input-text { - width: calc(100% - 10px); - padding: 8px 5px 8px 5px; - font-size: 12px; - font-family: 'Ubuntu'; - border-radius: 2px; - border: 1px solid #DBDBDB; - outline: none; -} -.add-app-input-select { - width: 100%; - font-size: 12px; - font-family: 'Ubuntu'; - border-radius: 2px; - border: 1px solid #DBDBDB; - outline: none; -} -.add-app-input-optional-text { - font-size: 13px; - color: #636363a8; - text-align: right; - display: inline-block; - width: 50%; -} -.add-first-app-button { - background-color: #2FA732; - color:white; - padding:11px 0px 11px 0px; - width: 100%; - display: block; - text-align: center; - border:none !important; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - cursor:pointer; - margin-top:5px; -} -.add-first-app-button:hover { - color:white !important; - background-color:#2f9732 !important -} -.add-app-checkbox { - display: inline-block; -} -#populate-after-app-description { - font-size:13px; - color:#636363; - float: left; - margin-left: 20px; -} -/* Customize the label (the container) */ -.populate-checkbox-container { -display: block; -position: relative; -padding-left: 35px; -margin-bottom: 12px; -cursor: pointer; -font-size: 13px; --webkit-user-select: none; --moz-user-select: none; --ms-user-select: none; -user-select: none; -} - -/* Hide the browser's default checkbox */ -.populate-checkbox-container input { -position: absolute; -opacity: 0; -cursor: pointer; -height: 0; -width: 0; -} - -/* Create a custom checkbox */ -.checkmark { -position: absolute; -border-radius: 3px; -border: 1px solid #9e9e9e; -top: 0; -left: 0; -height: 12px; -width: 12px; -} - -/* On mouse-over, add a grey background color */ -.populate-checkbox-container:hover input ~ .checkmark { -} - -/* When the checkbox is checked, add a blue background */ -.populate-checkbox-container input:checked ~ .checkmark { -background-color: #2FA732; -border: 1px solid #2FA732; -} - -/* Create the checkmark/indicator (hidden when not checked) */ -.checkmark:after { -content: ""; -position: absolute; -display: none; -} - -/* Show the checkmark when checked */ -.populate-checkbox-container input:checked ~ .checkmark:after { -display: block; -} - -/* Style the checkmark/indicator */ -.populate-checkbox-container .checkmark:after { -left: 3px; -top: 1px; -width: 4px; -height: 5px; -border: solid white; -border-width: 0 2px 2px 0; --webkit-transform: rotate(45deg); --ms-transform: rotate(45deg); -transform: rotate(45deg); -} -.required-first-app { - color: #B94A48; - display: none; - float: left; -} -.manage-app-no-rights { - width: 30%; - margin-left:35%; - text-align:center; - margin-top:10%; -} -.manage-app-no-rights-title { - font-weight: normal !important; - font-size:2.3em; -} -.manage-app-no-rights-description { - color: #636363; -} -#top-events-widget-container > .top-events-widget { - border: 1px solid #D0D0D0; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - background-color: #FFF; - margin-bottom: 20px; -} -#top-events-widget-container > .top-events-widget .top-events-widget-header { - border: none; - border-bottom: 1px solid #D0D0D0; - color: #636363; - font-size: 12px; - padding: 5px 13px; - height: unset; - text-transform: uppercase; -} -#top-events-widget-container > .top-events-widget > .outer { - margin-bottom: 20px; - padding: 0px 20px; -} -#top-events-widget-container > .top-events-widget > .outer .row { - overflow: auto; - padding: 10px; - padding-bottom: 0; - padding-left: 0; - padding-right: 0; -} -#top-events-widget-container > .top-events-widget > .outer .border { - border-bottom: solid 1px #D0D0D0; -} -#top-events-widget-container > .top-events-widget > .outer .row .left { - float:left; -} -#top-events-widget-container > .top-events-widget > .outer .row .title{ - font-weight: 400; - color: #3a3a3a; - margin-right: 8px; - text-transform: uppercase; - font-size: 16px; - margin: 0; - min-width: 130px; - padding: 10px; - padding-left: 0; - margin-right: 5px; - text-transform: uppercase; -} -#top-events-widget-container > .top-events-widget > .outer .row .right { - float:left; - width:80%; - padding-top: 10px; -} -#top-events-widget-container > .top-events-widget > .outer .row .right .col:hover {cursor: pointer;} -#top-events-widget-container > .top-events-widget > .outer .row .right .col:hover > label {cursor: pointer;} - -#top-events-widget-container > .top-events-widget > .outer > .row > .right > .col:hover > h4{color:#2FA732;} -#top-events-widget-container > .top-events-widget > .outer .row .right .col { - float:left; - width:17%; - height: 50px; - padding-left: 15px; -} -#top-events-widget-container > .top-events-widget > .outer > .row > .right > .col > h4 { - color: #3a3a3a; - max-width: 200px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - font-weight: 400; - font-size: 13px; - margin: 0; - margin-bottom: 4px; -} -#top-events-widget-container > .top-events-widget > .outer > .row > .right > .col > label { - color: #3a3a3a; - font-size: 17px; - font-weight: 500; -} -#top-events-widget-container > .top-events-widget > .outer > .row > .right > .col > span { - font-size: 13px; - margin-left: 5px; - margin-top: 5px; - font-weight: 400; - color: rgba(107, 185, 110, 0.8); -} -#top-events-widget-container > .top-events-widget > .outer > .row > .right > .col > .down { - color: rgba(201, 76, 76, 0.8); -} -#top-events-widget-container > .top-events-widget > .outer > .row > .right > .col > .up { - color: rgba(107, 185, 110, 0.8); -} -#top-events-widget-container > .top-events-widget > .outer > .info_text{ - color: #b5b5b5; - font-size: 12px; - margin-bottom: -8px; -} -@media only screen and (min-width : 1255px) { - #top-events-widget-container > .top-events-widget > .outer .row .title{ - margin-right: 50px; - } - #top-events-widget-container > .top-events-widget > .outer .row .right .col { - padding-left:22px; - } -} -#view-app .widget-header:first-child .left { - display: flex; - flex-direction: column; -} - -#view-app .widget-header:first-child .left > .title { - padding-top: 0; - font-size: 17px; - margin-bottom: 8px; -} - -#view-app .widget-header:first-child .left > .lock-status { - margin-left: 4px; - color: #474747; - font-size: 13px; - margin-top: -4px; - cursor: default; -} - -#view-app .widget-header:first-child .left > .lock-status > span { - margin-left: 4px; - border-bottom: 1px dotted; -} - -#view-app .cly-button-menu { - max-width: 320px; - top: 50px; - right: 15px; -} - -#view-app .cly-button-menu .item { - white-space: normal; -} - -#view-app .cly-button-menu .item.back > i { - font-size: 8px; - vertical-align: center; - margin-right: 4px; -} - -#view-app .cly-button-menu .item.back > span { - font-size: 12px; -} - -#view-app .cly-button-menu .item span { - font-size: 14px; -} - -#view-app .cly-button-menu .item span.red { - color: #C43132; -} - -#view-app .cly-button-menu .item.inactive * { - color: #E2E2E2 !important; -} - -#view-app .lock-status i { - font-size: 13px; -} - -.tooltipster-base { - font-size : 12px; -} - -#app-clear-button { - display: flex; - flex-direction: row; -} - -#app-clear-button > i { - width: 1rem; - align-self: center; - text-align: right; - font-size: 12px; - color: #D0D0D0; - margin-right: -10px; -} - -.member_image { - position: absolute; - right: 10px; - top: 10px; - background-color: black; - width: 30px; - height: 30px; - border-radius: 50px; -} -#notes-button-group.cly-button-menu-group{ - float: right; - margin-left: 0px; -} -#notes-button-group .cly-button-menu-trigger{ - line-height: 29px; - font-size: 20px; -} -#notes-button-group.cly-button-menu-group .cly-button-menu-trigger:after { - font-family: 'Ionicons'; - content: "\f396"; -} -#notes-button-group .cly-button-menu { - right:2px; -} -.graph-note-create { - width : 473px; - border: none !important; - background-color: #FFF; - z-index: 10001; - text-align: center; - color: #717171; - border: none; - border-radius: 2px; - padding: 0px; - box-sizing: border-box; - box-shadow: 0 2px 14px 0 rgba(0,0,0,0.25); -} -.graph-note-create .indicator { - display: none; -} - -.graph-note-create .title { - border-top-left-radius: 2px; - border-top-right-radius: 2px; - padding: 20px; - color: #636363; - background-color: #fff; - width: 100%; - box-sizing: border-box; - top: 0px; - font-size: 20px; - text-align: left; - margin: 0px; - font-weight: normal; -} -.graph-note-create .footer { - text-align: right; - overflow: auto; - width: 100%; - background-color: #fff; - margin: 0px; - padding: 15px 15px 11px; - box-sizing: border-box; - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} -.graph-note-create .footer .add-note { - float: none; - border: none; - padding: 12px 20px; - box-shadow: none; - display: inline-block; - margin: 0; - background-color: #2EB52B; - color: #fff; - border-radius: 2px; - margin-left: 10px; -} -.graph-note-create .footer .cancel-add-note { - background-color: #fff; - color: #929292; - text-decoration: underline; - float: none; - border: none; - padding: 12px; - box-shadow: none; - display: inline-block; - margin: 0; -} - - -.graph-note-create .section { - margin-bottom: 25px; -} - -.graph-note-create .fields { - height: 100%; - text-align: left; - background-color: #f9f9f9; - padding: 20px; -} - -.graph-note-create .fields .label { - font-size: 12px; - margin-bottom: 8px; - color: #636363; -} - -.graph-note-create .colors .color { - border-radius: 2px; - float: left; - width: 20px; - height: 20px; - position: relative; - margin-right: 10px; - cursor: pointer; -} -.graph-note-create .colors .color.alt1 { - background-color: #79a3e9; -} -.graph-note-create .colors .color.alt2 { - background-color: #70bbb8; -} -.graph-note-create .colors .color.alt3 { - background-color: #e2bc33; -} -.graph-note-create .colors .color.alt4 { - background-color: #a786cd; -} -.graph-note-create .colors .color.alt5 { - background-color: #dd6b67; -} -.graph-note-create .colors .color.alt6 { - background-color: #ece176; -} - -.graph-note-create .colors .color.selected:after { - font-family: Ionicons; - content: "\f3fd"; - position: absolute; - top: -2px; - font-size: 23px; - color: #fff; - left: 5px; -} - -.graph-note-create .fields .note::placeholder{ - font-size:14px; -} -.graph-note-create .fields .note { - border-radius: 2px; - border-color: #dcdbdb; - display: block; - width: calc(100% - 14px); - z-index: auto; - position: relative; - line-height: normal; - font-size: 11px; - transition: none 0s ease 0s; - background: #fff !important; - resize: none; - font-size:14px; - padding-left: 10px; -} - -.graph-note-create .button { - visibility: visible; - cursor: pointer; - user-select: none; - background-color: #ececec; - float: left; - border: 1px solid #d0d0d0; - margin-right: -1px; - color: #636363; - width: 68px; - height: 30px; - text-align: center; - width: 32.8%; - line-height: 30px; - font-size: 13px; -} -.graph-note-create .note-types-selector .button:nth-child(2) { - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; -} -.graph-note-create .button:last-child { - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; - border-right: 1px solid #d0d0d0; -} -.graph-note-create .calendar { - display: flex; - flex-direction: row; - align-items: center; -} -.graph-note-create .date-time-selector-container i { - font-size: 14px; - margin: 5px 5px; -} -.graph-note-create .date-time-selector-container .date-time-value-show { - flex-grow: 1; - padding-left: 10px; -} -.graph-note-create .button.active { - background-color: #ffffff; -} -.graph-note-create .selectize-control.multi .selectize-input > div { - padding: 3px 22px 3px 10px !important; - line-height: 14px !important; - background-color: #777; - color: #f1f1f1; -} -.note-table-view-navigator .back-link { - cursor: pointer; - margin-bottom: 25px; - color: #616161; - font-size: 12px; - display: inline-block; - text-transform: uppercase; -} -.note-table-view-navigator .back-link:before { - content: "←"; - margin-right: 5px; - color: #616161; -} - -.graph-note-create .date-time-selector-container { - width: 90%; - border: 1px solid #C5C5C5; - background-color: #fff; - color: #636363; - font-size: 14px; - line-height: 30px; - height: 30px; - border-radius: 2px; -} -.graph-note-create .date-time-selector-container .time-field { - padding: 3px 10px 15px 10px; - font-size: 13px; - display: flex; - align-items: center; -} -.graph-note-create .date-time-selector-container .time-label { - color: #fff; - flex-grow: 1; -} -.graph-note-create .date-time-selector-container .time-split { - color: #fff; -} -.graph-note-create .date-time-selector-container .time-input { - width: 40px; - height: 24px; - background-color: #192733; - border: none; - outline: 0; - font-size: 13px; - color: #fff; - text-align: center; - border-radius: 2px; - line-height: 2; -} -.graph-note-create .date-time-selector-container .date-time-picker { - display: none; - white-space: nowrap; - position: absolute; - z-index: 1000; - padding: 2px 3px 14px 3px; - background-color: #0b131a; - border-radius: 2px; - top: -54px; - left: 20px; - flex-direction: column-reverse; -} -.tipsy-for-note .tipsy-inner {max-width: 400px !important; } - -.tipsy-for-note .tipsy-inner .note-header { height: 14px; } -.tipsy-for-note .tipsy-inner .note-title { float:left; font-size:10px; color: #D0D0D0; text-align: left; font-weight: 400; margin-bottom: 10px;} -.tipsy-for-note .tipsy-inner .note-app { float:right; margin-left: 10px; font-size:10px; color: #D0D0D0;} -.tipsy-for-note .tipsy-inner .note-content {min-width:150px; display: block; font-size:11px; text-align: left; font-weight: 600; max-width: 300px; margin: 10px 0px;} -.tipsy-for-note .tipsy-inner .note-content .notes-view-link { color: #2EB52B} -.tipsy-for-note .tipsy-inner .note-content .notes-view-link:hover { cursor: pointer; } - -.tipsy-for-note .tipsy-inner .note-footer {font-size:10px; color: #D0D0D0; text-align: left;} -.tipsy-for-note .tipsy-inner .note-footer .note-owner {text-align: left; } -.tipsy-for-note .tipsy-inner .note-footer .note-type {text-align: left; height:30px; text-transform: capitalize;} - - -.notes-manage-options-item {float: right;} -.notes-manage-options-item .edit { display: block; right: 10px; top: 0; font-size: 17px; cursor: pointer; color: #a7a7a7; padding: 7px 10px; line-height: 15px; background-color: rgba(255,255,255,0.03); transition: background-color 1s; } -.notes-manage-options-item .edit:before { font-size:20px; font-family: 'Ionicons'; content: "\f396"; } -.notes-manage-options-item .edit:hover { color: #6B6B6B; background-color: rgba(255,255,255,0.06); transition: background-color 1s; } -.notes-manage-options-item :hover .edit { display: block; } -.notes-manage-options-item .edit-menu { - margin: -6px -95px; - display: none; - float:left; - z-index: 10; - position:absolute; - font-size: 13px; - white-space: nowrap; - background-color: #fff; - border-radius: 2px; - width: 121px; - padding:10px 0 10px 0; - border: 1px solid #d0d0d0; -} -.notes-manage-options-item .edit-menu .item { - cursor: pointer; - padding: 8px 20px; - font-size: 24px; - white-space: nowrap; - cursor:pointer; font-size: 13px; white-space: nowrap; color:#474747; } -.notes-manage-options-item .edit-menu .item:hover { background-color: #f3f3f3; } - -.notes-manage-options-item .edit-menu:before { - border: 4px solid rgba(194, 225, 245, 0); - border-bottom-color: #FFF; - right: 7px; - top: -8px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 2; -} -.notes-manage-options-item .edit-menu .fa{ - margin-right: 7px; -} -.notes-manage-options-item .edit-menu:after { - border: 5px solid rgba(194, 225, 245, 0); - border-bottom-color: #d0d0d0; - right: 6px; - top: -10px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 1; -} - -.routename-graphNotes .filter1-segmentation {outline: none;} -.graph-notes-popup {border:none !important;} -.graph-note-popup { background-color: #f9f9f9; min-width:400px;} -.graph-note-popup .title { - height: 70px; - background-color: #ffffff; - font: 25px Ubuntu,Helvetica,sans-serif; - color: #636363; - float: left; - font-weight: 400; - line-height: 3; - width: 100%; - margin-top: -18px; -} -.graph-note-popup .title span { margin-left: 20px;} -.graph-note-popup .popup-content {margin: 10px 20px; padding-top: 70px;} -.graph-note-popup .note-time { color: #9c9c9c; font-weight: 300; font-size: 12px; line-height: 19px; display: inline-block; margin-top:8px;} -.graph-note-popup .note-content { margin-top: 10px; color: #636363; font-size:14px; font-weight: 400; } -.graph-note-popup .note-app { float: right; color: #9c9c9c; display: inline-block; font-size: 12px; margin-top: 8px;} -.graph-note-popup .note-footer { color: #9c9c9c; font-size: 12px; margin-top: 20px;} -.graph-note-popup .note-footer .note-type {text-transform: capitalize;} -.graph-note-popup .note:not(:last-child){ padding-bottom:10px; padding-bottom: 10px;border-bottom: 0.2px solid #DEDEDE; } -.graph-note-popup .popup-footer { height: 70px; background-color: #fff; } -.graph-note-popup .popup-footer .close-note-popup-button { - border: 1px solid #DEDEDE; - float: right; - margin-right: 20px; - margin-top: 20px; -} -.note-table-view-navigator { - color: #636363; -} -.routename-graphNotes .dataTable-top { - border-top-left-radius: 0px; - border-top-right-radius: 0px; -} -.note-type-tip-title { - text-transform: uppercase; - text-align: left; - font-size: 12px; - margin: 5px 0 0 5px; - color: #D0D0D0; -} -.note-type-tip-content { - text-align: left; - font-size: 10px; - margin: 5px 10px 5px 5px; - min-width: 160px; -} - -.model { - display:none; - position:fixed; - left:50%; - top:50%; - background-color:#FFF; - z-index:10001; - text-align:center; - max-width:700px; - color:#717171; - width:660px; - border:none; - border-radius: 2px; - padding:0px; - box-sizing: border-box; - box-shadow: 0 2px 14px 0 rgba(0,0,0,0.25); -} - -.model .body { - height: 430px; - text-align: left; - background-color: #f9f9f9; - padding: 20px; -} - -.model .title { - padding: 20px; - color: #636363; - width: 100%; - box-sizing: border-box; - top: 0px; - font-size:20px; - text-align:left; - margin: 0px; - font-weight: normal; -} - -.model .buttons { - text-align: right; - overflow:auto; - width: 100%; - margin: 0px; - padding: 15px 15px 11px; - box-sizing: border-box; -} - -.model #model-continue { - background-color:#2EB52B; - color:#ffffff; - border-radius:2px; -} - -.model #model-cancel { - background-color: #fff; - color:#929292; - text-decoration: underline; -} - -.model .buttons .icon-button { - float: none; - border: none; - padding: 12px; - box-shadow: none; - display: inline-block; - margin:0; - background-color: none; -} - -.model .details { height:100%; float:none; overflow-y:auto; padding: 0px 20px; } -.model .details .section { margin-bottom: 25px; } -.model .details .section .label { font-size: 12px; margin-bottom: 8px; color:#636363; } -.model .details .section > .description { font-size: 11px; margin-top: 4px; color: #9c9c9c; line-height: 17px; } -.model .details .section input[type=text].input { width: 100%; box-sizing: border-box; border-radius: 2px; border: 1px solid #d6d6d6; outline: none; padding: 7px; font-size: 12px; } -.model .details .section .colors .color { border-radius:2px; float:left; width:20px; height: 20px; position: relative; margin-right: 10px; cursor: pointer; } -.model .details .section .colors .color.selected:after { font-family: 'Ionicons'; content: "\f3fd"; position: absolute; top: -2px; font-size: 23px; color: #fff; left: 5px; } -.model .details .section .colors .color.alt1 { background-color: #6fa3ef; } -.model .details .section .colors .color.alt2 { background-color: #55bdb9; } -.model .details .section .colors .color.alt3 { background-color: #ef8800; } -.model .details .section .colors .color.alt4 { background-color: #ae83d2; } -.model .panel { background-color: #ffffff; border: 1px solid #D0D0D0; font-size: 13px; border-radius: 2px; } -.model .panel .panel-heading { padding: 8px 20px; background-color: #ECECEC; color: #636363; text-transform: uppercase; border-bottom: 1px solid #D0D0D0; font-weight: 500; } -.model .panel .panel-body { padding: 20px; position: relative; } - -.model .details .section input::placeholder { - font: 13px Ubuntu,Helvetica,sans-serif; -} -.model .details .section input::-webkit-input-placeholder { - font: 13px Ubuntu,Helvetica,sans-serif; -} -.model .details .section input::-moz-placeholder { - font: 13px Ubuntu,Helvetica,sans-serif; -} -.model .details .section input:-ms-input-placeholder { - font: 13px Ubuntu,Helvetica,sans-serif; -} -.model .details .section input { - font: 13px Ubuntu,Helvetica,sans-serif; - color: #444; -} - -.json-dialog { display:none; position:fixed; max-width:600px; left:50%; top:50%; background-color:#FFF; border:1px solid #999; border-radius:2px; z-index:10001; } -.json-dialog .header { padding: 20px; padding-bottom: 10px; box-shadow: 0px 5px 10px #d2d1d170; overflow: auto; position: relative; z-index: 10000; } -.json-dialog .body { height: 400px; overflow: scroll; text-align: left; } -.json-dialog .title { padding-bottom: 13px; border-bottom: 2px solid #d2d1d170; } -.json-dialog .buttons { text-align: right; overflow:auto; padding:0; } -.json-dialog .buttons .icon-button { float:right; } -.json-dialog .json-options { margin-top: 15px; } -.json-dialog .json-status { font-size: 13px; float: left; } -.json-dialog .valid-json .material-icons { color: #2EB52B; vertical-align: middle; margin-top: -5px; } -.json-dialog .invalid-json .material-icons { color: #D63E40; vertical-align: middle; margin-top: -5px; } - -.json-dialog.popStyleGreen{ text-align:center; color:#717171; width:600px; border:none; border-radius: 2px; padding:0px; max-width:600px; box-sizing: border-box; box-shadow: 0 2px 14px 0 rgba(0,0,0,0.25);} -.json-dialog.popStyleGreen .title{ color:#636363; font-size:20px; text-align:left; margin: 0px; font-weight: normal; } -.json-dialog.popStyleGreen #dialog-continue { background-color:#2EB52B;color:#ffffff; border-radius:2px; } -.json-dialog.popStyleGreen #dialog-cancel{ background-color:none; color:#929292; text-decoration: underline; background-color:#ffffff;} -.json-dialog.popStyleGreen #dialog-format{ background-color:none; color:#929292; background-color:#ffffff; border: 1px solid #d2d1d170; padding: 5px 10px; float: right; margin-top: -5px; } -.json-dialog.popStyleGreen .icon-button { float:none; border:none; padding:12px; box-shadow:none; display: inline-block; margin:0; } -.json-dialog.popStyleGreen .buttons { margin: 0px; padding: 10px; padding-right: 15px; border-top: 2px solid #d2d1d170; } -.json-braces { - position: absolute; - right: 7px; - color: #868686; - cursor: pointer; - top: 7px; -} -.highlighted-app-item { - background-color: #ebebeb; -} - -.routename-loyalty #label-container .labels { position: relative; margin-top:20px; width:100%; text-align:center; } -.routename-loyalty #label-container .label { cursor:pointer; overflow:hidden; max-width:128px; margin:2px 10px; position: relative; display: inline-block; } -.routename-loyalty #label-container .label.hidden { opacity:0.3; } -.routename-loyalty #label-container .label .color { float:left; margin-right:8px; height:15px; width:15px; border-radius:1px; } -.routename-loyalty #label-container .label .text { float:left; font: 13px Ubuntu; line-height:111%; color:#666; max-width:105px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;} - -.zoom { width: 102px; display: flex; margin: 0 auto; margin-top: -18px; } -.zoom *:before { content: none; position: initial; } -.zoom .zoom-button { visibility: hidden; user-select: none; cursor: pointer; padding: 4px 10px 3px 10px; font-size: 14px; font-family: "Ionicons"; position: relative !important; margin: 0; color: #666; background-color: rgba(0, 0, 0, 0.05); border: solid 1px rgba(0, 0, 0, 0.1); } -.zoom .zoom-button:hover { opacity: 0.7; } -.zoom .zoom-out { border-radius: 100px 0 0 100px; text-align: right; padding-left: 12px; } -.zoom .zoom-out:before { content: "\f209"; } -.zoom .zoom-reset { text-align: center; padding-left: 11px; border-left: none; border-right: none; } -.zoom .zoom-reset:before { content: "\f21c"; } -.zoom .zoom-in { border-radius: 0 100px 100px 0; text-align: left; padding-right: 12px; } -.zoom .zoom-in:before { content: "\f218"; } -.graph.pannable { cursor: grab; } -*:not(.hide-zoom):hover > .zoom .zoom-button { visibility: visible; } -#dashboard-export-graph .zoom { margin-top: 18px; } -#dashboard-purge-graph .zoom { margin-top: 18px; } - -.routename-user .zoom { margin-top: -25px; } -.routename-sessions .zoom { margin-top: -25px; } -.routename-events #event-main .events-general-description:empty ~ .widget-content > .zoom { margin-top: -45px } -.routename-events #event-main .events-general-description ~ .widget-content > .zoom { margin-top: -10px } -.routename-revenue .zoom { margin-top: -12px; } -.routename-attribution .zoom { margin-top: -25px; } -.routename-compliance .zoom { margin-top: -12px; } -.routename-messagingDashboardView .zoom { left: calc(50% - 51px); position: absolute; z-index: 999; top: 7%;} - -.clip { max-height: 60px; line-height: 20px; text-overflow: ellipsis; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;} -.clip.nothing { color: #bbb;} - -#jobs-menu:hover svg g { - fill: #fff; -} - -.view-more::after { - content: url('../images/dashboard/vm-arrow.svg'); - background-repeat: no-repeat; - position: relative; - top: 2px; - margin-left: 5px; -} - -.view-more:hover::after { - content: url('../images/dashboard/vm-arrow-hover.svg'); - background-repeat: no-repeat; -} - -.view-more:hover { - color: #2FA732; -} -.cly-menu-component .menu-toggler{ - cursor: pointer; - padding: 6px 9px; - padding-right: 25px; - overflow: hidden; - white-space: nowrap; - color: #444; - font-weight: normal; - font: 13px Ubuntu,Helvetica,sans-serif; - line-height: 111%; -} - -.cly-menu-component .menu-toggler .label-wrapper { - display: inline-block; -} - -.cly-menu-component.empty .menu-toggler .label-wrapper{ - color: #d0d0d0; - border-bottom: 1px dotted #444; -} - -.cly-menu-component .menu-toggler .label-wrapper .text{ - max-width: 181px; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -.cly-menu-component .menu-toggler .right { - opacity: 0.8; - right: auto; - position: absolute; - width: 8px; - height: 100%; - line-height: 27px; - margin-left: 18px; - margin-top: -6px; - display: inline-block; -} - -.cly-menu-component .menu-toggler .right.combo:before { - color: #717171; - font-family: 'Ionicons'; - content: "\f123"; - font-size: 9px; - position: absolute; - right: 8px; -} - -.cly-menu-component .menu-toggler:hover .right.combo:before{ - color: #2fa732; -} - -.cly-menu-component.shown .menu-toggler .right.combo:before{ - content: "\f126"; - color: #2fa732; -} - -.cly-menu-component .menu-toggler:hover { - color: #2FA732; -} - -.cly-menu-component .menu-content{ - position: absolute; - /*border: 1px solid #D0D0D0;*/ -} - -.cly-menu-component .menu-content::before { - border: 6px solid rgba(194, 225, 245, 0); - border-bottom-color: #0b131a; - right: 9px; - top: -12px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; -} - -.event-remind-tooltip { - height: 40px; - background-color: #fcf5ed; - margin-bottom: 10px; - display: none; - border: 1px solid #e3af7f; - border-radius: 2px; -} - -.event-remind-tooltip:last-of-type { - margin-bottom: 20px; -} - -.event-remind-tooltip .content { - font-size: 14px; - color: #e3af7f; - display: flex; - align-items: center; -} - -.event-remind-tooltip .content .prefix { - width: 5px; - background: #e3af7f; - height: 40px; -} - -.event-remind-tooltip .content .remind-context { - margin-left: 10px; - flex-grow: 1; -} - -.event-remind-tooltip .content .remind-context a{ - text-decoration: underline; -} - -.event-remind-tooltip .content .remind-context a:hover{ - color:#e29c5b; -} - -.event-remind-tooltip .content i:hover{ - color:#e29c5b; -} -.event-remind-tooltip .content i { - margin-right:10px; -} - -.event-remind-tooltip .content i:hover { - cursor: pointer; -} - -.routename-events .event-title { - display: inline-block; -} - -.routename-events .tag { - display: inline-block; - margin-left: 10px; - border-radius: 2px; - position: absolute; - padding: 0 5px; - font-size: 10px; - color: #8e8e8e; - border: 1px solid #d4d4d4; -} - -.routename-events .group-badge { - font-size: 10px; - margin-top: 2px; - color: gray; -} - - -.select-items .item .group-badge { - font-size: 9px; - margin-top: 0px; - color: gray; - display:inline; - margin-right: 5px; - border: 1px solid #D0D0D0; - padding: 1px 5px; - border-radius: 3px; - margin: -2px 5px -4px 5px; - text-transform: uppercase; -} -.select-items .item .group-badge span { - display:none; -} - -#events-blueprint-drawer .panel-body .section:last-child { - margin-bottom: 0px; -} - -#events-blueprint-drawer .label-desc { - color: #696969; - opacity: 0.68; - font-size: 11px; - margin-bottom: 8px; - line-height: 15px; -} -/*Bug for when on off switch is vertical-align: middle*/ -#eb-event-visibility .on-off-switch-label:before { - top: 1px; -} - -#event-groups-settings-table .edit-event, #events-custom-settings-table .edit-event { - width: 54px; - height: 29px; - border-radius: 2px; - border: solid 1px #d0d0d0; - background-color: #ffffff; - visibility: hidden; - cursor: pointer; - margin-right: 15px; - color: #6B6B6B; -} - - - - #event-groups-settings-table tr:hover .edit-event, #events-custom-settings-table tr:hover .edit-event { - width: 54px; - height: 29px; - border-radius: 2px; - border: solid 1px #d0d0d0; - background-color: #ffffff; - visibility: visible; - cursor: pointer; - margin-right: 15px; - color: #6B6B6B; - } - - -.user-config-danger-zone { - display: none; -} - -.routename-user-settings .user-config-danger-zone { - display: block; -} - -#eb-event-desc-input { - display: block; -} - -.cly-select .drop-icn { - width: 13px; - height: 12px; - background-color: #444; - border-radius: 4px; - overflow: hidden; - font-size: 0; - opacity: .8; - position: absolute; - right: 8px; - top: 7px; -} - -.cly-select .drop-icn:before { - content: " "; - width: 6px; - top: 5px; - transform: rotate(40deg); - position: absolute; - height: 2px; - background-color: #fff; - left: 2px; - border-radius: 1px; -} - -.cly-select .drop-icn:after { - content: " "; - width: 6px; - top: 5px; - transform: rotate(140deg); - position: absolute; - right: 2px; - height: 2px; - background-color: #fff; - border-radius: 1px; -} - -.cly-select.active .drop-icn:before { - transform: rotate(140deg); -} - -.cly-select.active .drop-icn:after { - transform: rotate(40deg); -} - -.cly-select:hover .drop-icn { - background-color: #2FA732; -} - -.selectize-right-drop .selectize-input::after { - font-family: 'Ionicons'; - font-size: 10px; - float: right; - color: #717171; - content: "\f123"; - position: absolute; - right: 6px; - top: 8px; -} - -.selected.selectize-right-drop .selectize-input::after { - content: "\f126"; - color: #2fa732; -} - -.selectize-input ::placeholder { - color: #dddddd; -} - -.mgmt-plugins-row ::placeholder { - color: #dddddd; -} - -.mgmt-plugins-row .selectize-dropdown [data-selectable] .highlight { - background: #fff; -} - -.routename-manageUsers .create-user-drawer-bottom { - background-color: white; - height: 45px; - padding-top: 10px; - padding-bottom: 10px; - width: 100%; - position: absolute; - bottom: 0; - right: 0; -} - -.routename-manageUsers .create-user-drawer { - width: 641px; - height: 100%; - right: 0; - transform: translateX(641px); - transition: transform 0.3s; - top: 0; - background-color: #f9f9f9; - border-left: 1px solid #d0d0d0; - z-index: 10000; -} - -.routename-manageUsers .create-user-drawer .left-area { - float:left; -} - -.routename-manageUsers .create-user-drawer .right-area { - float: left; - margin-left: 15px; -} - -.routename-manageUsers .create-user-drawer label { - height: 12px; - font-family: Ubuntu; - font-size: 12px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: 1; - letter-spacing: normal; - color: #636363; -} - -.routename-manageUsers .create-user-drawer .img-upload { - width: 190px; - height: 232px; - border-radius: 2px; - border: dashed 2px #ebebeb; - background-color: #ffffff; - margin-top: 4px; -} - -.routename-manageUsers .create-user-drawer .img-preview { - height: 72px; - margin-top: 5px; - width: 72px; - border-radius: 50%; - display: inline-block; -} - -.routename-manageUsers .create-user-drawer .drawer-input { - display: block; - width: 351px; - height: 28px; - border-radius: 2px; - border: solid 1px #d6d6d6; - background-color: #ffffff; - margin-bottom: 15px; - margin-top: 4px; - padding: 0px 8px; - font-family: Ubuntu; -} - -.routename-manageUsers .create-user-drawer .drawer-input::placeholder { - color: #a9a9a9; - font-style: 13px; -} - -.routename-manageUsers .create-user-drawer-detail { - padding: 21px; -} - -.routename-manageUsers .create-user-drawer .upload-message { - width: 126px; - margin-left: 33px; - margin-top: 100px; - height: 32px; - font-family: Ubuntu; - font-size: 12px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: 1.33; - letter-spacing: normal; - text-align: center; - color: #737373; -} - -.routename-manageUsers .create-user-drawer .access-area .header { - width: calc(100% - 34px); - border-top-left-radius: 2px; - border-top-right-radius: 2px; - border: solid 1px #dbdbdb; - background-color: #ececec; - padding: 9px 12px; - font-family: Ubuntu; - font-size: 13px; - font-weight: 500; - color: #656565; - font-stretch: normal; - font-style: normal; -} - -.routename-manageUsers .create-user-drawer .access-area .content { - width: calc(100% - 36px); - padding: 20px 13px; - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - border-left: solid 1px #dbdbdb; - border-right: solid 1px #dbdbdb; - border-bottom: solid 1px #dbdbdb; - background-color: #ffffff; -} - -.routename-manageUsers .create-user-drawer .checkbox-container { - display: block; - color: gray; - position: relative; - cursor: pointer; - font-size: 13px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.routename-manageUsers .create-user-drawer .checkbox-container input { - position: absolute; - opacity: 0; - cursor: pointer; - border-radius: 2px; - left: 0px; -} - -.routename-manageUsers .create-user-drawer .checkbox-checkmark { - position: absolute; - top: 0; - left: 0; - height: 11px; - width: 11px; - border-radius: 3px; - border: 1px solid #636363; -} - -.routename-manageUsers .create-user-drawer .countly-checkbox-container:hover input ~ .checkbox-checkmark { - border: 1px solid #217923; -} - -.routename-manageUsers .create-user-drawer .countly-checkbox-container input:checked ~ .checkbox-checkmark { - background-color: #2EB52B; - border: 1px solid #2eb52b; -} - -.routename-manageUsers .create-user-drawer .checkbox-container input:checked:hover { - background-color: #217923; -} - -.routename-manageUsers .create-user-drawer .checkbox-checkmark:after { - content: ""; +.member_image { position: absolute; - display: none; -} - -/* Show the checkmark when checked */ -.routename-manageUsers .create-user-drawer .checkbox-container input:checked ~ .checkbox-checkmark:after { - display: block; -} - -/* Style the checkmark/indicator */ -.routename-manageUsers .create-user-drawer .checkbox-container .checkbox-checkmark:after { - left: 2.5px; - top: 0.6px; - width: 2.5px; - height: 5px; - border: solid white; - border-width: 0 3px 3px 0; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} - -.routename-manageUsers .create-user-drawer .check-green { - font-size: medium !important; - float:left; + right: 10px; + top: 10px; + background-color: black; + width: 30px; + height: 30px; + border-radius: 50px; } -.routename-manageUsers .create-user-drawer .checkbox-label { - /* font-family: Ubuntu; */ - font-size: 12px; - /* font-weight: normal; */ - margin-top: 2px; - margin-left: 3px; - font-stretch: normal; - cursor: default; - /* font-style: normal; */ - /* line-height: normal; */ - /* letter-spacing: normal; */ - color: #666666; - float:left; - border-bottom: 1px dashed #979797; +.model { + display:none; + position:fixed; + left:50%; + top:50%; + background-color:#FFF; + z-index:10001; + text-align:center; + max-width:700px; + color:#717171; + width:660px; + border:none; + border-radius: 2px; + padding:0px; + box-sizing: border-box; + box-shadow: 0 2px 14px 0 rgba(0,0,0,0.25); } -.routename-manageUsers .create-user-drawer .permission-header .checkbox-label { - border-bottom: none; +.model .body { + height: 430px; + text-align: left; + background-color: #f9f9f9; + padding: 20px; } -.routename-manageUsers .create-user-drawer .drawer-header { - font-family: Ubuntu; - font-size: 15px; - font-weight: 500; - font-stretch: normal; - font-style: normal; - line-height: 0.87; - letter-spacing: normal; - color: #656565; - float:left; - width: 50%; +.model .title { + padding: 20px; + color: #636363; + width: 100%; + box-sizing: border-box; + top: 0px; + font-size:20px; + text-align:left; + margin: 0px; + font-weight: normal; } -.routename-manageUsers .create-user-drawer .drawer-information { - opacity: 0.68; - font-family: Ubuntu; - font-size: 11px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: 1.09; - letter-spacing: normal; +.model .buttons { text-align: right; - color: #696969; - float:left; - width: 50%; - margin-top: 5px; + overflow:auto; + width: 100%; + margin: 0px; + padding: 15px 15px 11px; + box-sizing: border-box; } -.routename-manageUsers .create-user-drawer #sub-header-1th { - margin-top: 48px; - width: calc(100% - 11px); +.model #model-continue { + background-color:#2EB52B; + color:#ffffff; + border-radius:2px; } -.routename-manageUsers .create-user-drawer .admin-access, .create-user-drawer .user-access, .create-user-drawer .role-section { - margin-top: 16px; +.model #model-cancel { + background-color: #fff; + color:#929292; + text-decoration: underline; } -.routename-manageUsers .create-user-drawer .header .section-title, .create-user-drawer .drawer-header { - text-transform: uppercase; +.model .buttons .icon-button { + float: none; + border: none; + padding: 12px; + box-shadow: none; display: inline-block; + margin:0; + background-color: none; } -.routename-manageUsers .create-user-drawer .header .subtitle { - opacity: 0.68; - font-family: Ubuntu; - font-size: 11px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: 1.45; - letter-spacing: normal; - color: #696969; - text-decoration: none; -} +.model .details { height:100%; float:none; overflow-y:auto; padding: 0px 20px; } +.model .details .section { margin-bottom: 25px; } +.model .details .section .label { font-size: 12px; margin-bottom: 8px; color:#636363; } +.model .details .section > .description { font-size: 11px; margin-top: 4px; color: #9c9c9c; line-height: 17px; } +.model .details .section input[type=text].input { width: 100%; box-sizing: border-box; border-radius: 2px; border: 1px solid #d6d6d6; outline: none; padding: 7px; font-size: 12px; } +.model .details .section .colors .color { border-radius:2px; float:left; width:20px; height: 20px; position: relative; margin-right: 10px; cursor: pointer; } +.model .details .section .colors .color.selected:after { font-family: 'Ionicons'; content: "\f3fd"; position: absolute; top: -2px; font-size: 23px; color: #fff; left: 5px; } +.model .details .section .colors .color.alt1 { background-color: #6fa3ef; } +.model .details .section .colors .color.alt2 { background-color: #55bdb9; } +.model .details .section .colors .color.alt3 { background-color: #ef8800; } +.model .details .section .colors .color.alt4 { background-color: #ae83d2; } +.model .panel { background-color: #ffffff; border: 1px solid #D0D0D0; font-size: 13px; border-radius: 2px; } +.model .panel .panel-heading { padding: 8px 20px; background-color: #ECECEC; color: #636363; text-transform: uppercase; border-bottom: 1px solid #D0D0D0; font-weight: 500; } +.model .panel .panel-body { padding: 20px; position: relative; } -.routename-manageUsers .create-user-drawer .app-selector { - font-family: Ubuntu; - font-size: 12px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: 1; - letter-spacing: normal; - color: #636363; - border-left: solid 1px #dbdbdb; - border-right: solid 1px #dbdbdb; - border-bottom: solid 1px #dbdbdb; - background-color: #ececec; - padding: 15px 12px; - width: calc(100% - 34px); +.model .details .section input::placeholder { + font: 13px Ubuntu,Helvetica,sans-serif; } - -.routename-manageUsers .user-access .section-title { - padding: 5px 0px; +.model .details .section input::-webkit-input-placeholder { + font: 13px Ubuntu,Helvetica,sans-serif; } - -.routename-manageUsers .user-access .permission-header { - border-left: 1px solid #dbdbdb; - border-right: 1px solid #dbdbdb; - border-bottom: 1px solid #dbdbdb; - background-color: #ececec; - width: calc(100% - 34px); - padding: 8px 12px; - height: 12px; +.model .details .section input::-moz-placeholder { + font: 13px Ubuntu,Helvetica,sans-serif; } - -.routename-manageUsers .create-user-drawer .section-close-icon { - float: right; - color: silver; +.model .details .section input:-ms-input-placeholder { + font: 13px Ubuntu,Helvetica,sans-serif; } - -.routename-manageUsers .user-access .permission-header .table-description { - font-family: Ubuntu; - text-transform: uppercase; - font-family: Ubuntu; - font-size: 11px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: normal; - letter-spacing: normal; - color: #484848; - float: left; - width: 15%; - text-align: center; - height: 10px; +.model .details .section input { + font: 13px Ubuntu,Helvetica,sans-serif; + color: #444; } -.routename-manageUsers .user-access .permission-header .first-description { - width: 40%; - text-align: left; -} +.zoom { width: 102px; display: flex; margin: 0 auto; margin-top: -18px; } +.zoom *:before { content: none; position: initial; } +.zoom .zoom-out { border-radius: 100px 0 0 100px; text-align: right; padding-left: 12px; } +.zoom .zoom-out:before { content: "\f209"; } +.zoom .zoom-reset { text-align: center; padding-left: 11px; border-left: none; border-right: none; } +.zoom .zoom-reset:before { content: "\f21c"; } +.zoom .zoom-in { border-radius: 0 100px 100px 0; text-align: left; padding-right: 12px; } +.zoom .zoom-in:before { content: "\f218"; } -.routename-manageUsers .admin-access .app-selector { - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} +.clip { max-height: 60px; line-height: 20px; text-overflow: ellipsis; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;} +.clip.nothing { color: #bbb;} -.routename-manageUsers .create-user-drawer .first-column { - width: 40% !important; - text-align: left !important; - float:left; - font-family: Ubuntu; - font-size: 12px; - font-weight: normal; - font-stretch: normal; - font-style: normal; - line-height: normal; - letter-spacing: normal; - color: #666666; -} -.routename-manageUsers .create-user-drawer .permission-column { - width: 15%; - text-align: center; - float:left; +.select-items .item .group-badge { + font-size: 9px; + margin-top: 0px; + color: gray; + display:inline; + margin-right: 5px; + border: 1px solid #D0D0D0; + padding: 1px 5px; + border-radius: 3px; + margin: -2px 5px -4px 5px; + text-transform: uppercase; } - -.routename-manageUsers .create-user-drawer .permission-column .countly-checkbox-icon { - top: -6px; +.select-items .item .group-badge span { + display:none; } +/*Bug for when on off switch is vertical-align: middle*/ +/* Show the checkmark when checked */ -.routename-manageUsers .create-user-drawer .permission-column .countly-checkbox-native, .create-user-drawer #user-drawer-global-admin .countly-checkbox-native { - top: -22px; -} - -.routename-manageUsers .countly-checkbox-wrapper .fa-check { - color: white; -} +/* Style the checkmark/indicator */ /* .routename-manageUsers .mark-all .countly-checkbox-native { @@ -4715,286 +1055,12 @@ transform: rotate(45deg); } */ -.routename-manageUsers .create-user-drawer .permission-column .countly-checkbox-wrapper { - margin-left: 25%; -} - -.routename-manageUsers .create-user-drawer .permission-item { - background-color: white; - padding: 12px 12px; - width: calc(100% - 24px); -} - -.routename-manageUsers .create-user-drawer .gray { - background-color: #f7f7f7; -} - -.routename-manageUsers .create-user-drawer .permission-table { - border: 1px solid #dbdbdb; - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - width: calc(100% - 10px); - height: 200px; - overflow-y: scroll; -} - -.routename-manageUsers .create-user-drawer .permission-header .checkbox-container { - margin-left: 5px; -} - -.routename-manageUsers .create-user-drawer .permission-column .checkbox-container { - margin-left: 30px; -} - -.routename-manageUsers .create-user-drawer .selector-label { - float:left; - width: 7%; - margin-top:8px; -} - -.routename-manageUsers .create-user-drawer .selector-wrapper { - float:left; - width: 93%; -} - -.routename-manageUsers .create-user-drawer .create-user-button { - border: none; - border-radius: 2px; - font-size: 14px !important; - padding: 10px 25px 10px 25px; - outline: none; - margin-right: 5px; - float: right; - margin-right: 30px; - margin-top: 5px; -} - -.routename-manageUsers .create-user-drawer .selectize-input { - min-height: 30px !important; - height: 30px !important; - padding: 4px !important; -} - -.routename-manageUsers .create-user-drawer #new-user-group-select { - width: calc(100% - 2px); - height: 24px; - padding: 2px 0px; - margin-top: 7px; -} - -.routename-manageUsers .create-user-drawer #new-user-group-select .select-items { - width: 100% !important; -} - -.routename-manageUsers .create-user-drawer .red-text, .create-user-drawer .green-text { - padding-left: 0px; - vertical-align: middle; -} - -.routename-manageUsers .create-user-drawer .file-selected { - border:2px solid #2EB52B; -} - -.routename-manageUsers .create-user-drawer .create-new-user { - float: right; - border: none; - margin-right: 25px; - margin-top: 10px; -} - -.routename-manageUsers .add-new-permission-set { - margin-left: 0px; - margin-top: 15px; - background-color: #ef9c42; - color: white; - border: none; -} - -.routename-manageUsers .manage-users-options-item .edit { - display: block; - right: 10px; - top: 0; - /* font-size: 17px; - */ - cursor: pointer; - color: #a7a7a7; - background-color: rgba(255, 255, 255, 0.03); - transition: background-color 1s; - padding-top: 17px; - padding-left: 17px; - width: 34px; - height: 34px; -} - -.routename-manageUsers .manage-users-options-item .edit:before { - font-size: 20px; - font-family: 'Ionicons'; - content: "\f396"; -} - -.routename-manageUsers .manage-users-options-item .edit:hover { - color: #6B6B6B; - background-color: rgba(255, 255, 255, 0.06); - transition: background-color 1s; -} - -.routename-manageUsers .manage-users-options-item:hover .edit { - display: block; -} - -.routename-manageUsers .manage-users-options-item .edit-menu { - margin: -16px -195px; - display: none; - float: left; - z-index: 10; - position: absolute; - font-size: 13px; - white-space: nowrap; - background-color: #fff; - border-radius: 2px; - width: 210px; - padding: 10px 0 10px 0; - border: 1px solid #d0d0d0; -} - -.routename-manageUsers .manage-users-options-item .edit-menu .item { - cursor: pointer; - padding: 8px 20px; - font-size: 24px; - white-space: nowrap; - cursor: pointer; - font-size: 13px; - white-space: nowrap; - color: #474747; -} - -.routename-manageUsers .manage-users-options-item .edit-menu .item:hover { - background-color: #f3f3f3; -} - -.routename-manageUsers .manage-users-options-item .edit-menu:before { - border: 4px solid rgba(194, 225, 245, 0); - border-bottom-color: #FFF; - right: 7px; - top: -8px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 2; -} - -.routename-manageUsers .manage-users-options-item, .edit-menu { - margin-left: 75%; -} - -.routename-manageUsers .manage-users-options-item .edit-menu:after { - border: 5px solid rgba(194, 225, 245, 0); - border-bottom-color: #d0d0d0; - right: 6px; - top: -10px; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - z-index: 1; -} - -.routename-manageUsers .create-user-drawer .edit-picture { - color: #2EB52B; - font-size: 12px; - font-weight: bold; - float: right; - margin-top: 25px; - margin-left: 20px; - cursor: pointer; -} - -.routename-manageUsers .discard-changes { - border: none; - font-size: 13px; - background-color: white; - font-family: 'UBUNTU'; - float: right; - margin-top: 15px; -} - -.routename-manageUsers .create-user-drawer #profile-picture-label { - display: block; -} - -.routename-manageUsers .create-user-drawer .update-picture::before { - font-size: 20px; - font-family: 'Ionicons'; - content: "\f396"; - color: gray; -} - -.routename-manageUsers .create-user-drawer .drawer-loading { - display: block; - width: 20%; - margin-left: 40%; - margin-top: 25%; - text-align: center; -} - -.routename-manageUsers .create-user-drawer .drawer-loading img { - width: 50%; -} - -.routename-manageUsers .create-user-drawer .permission-column { - text-transform: capitalize; -} - -.routename-manageUsers .create-user-drawer .read-all span { - left: -10px; -} - -.routename-manageUsers #user-drawer-global-admin { - float:left; -} - -.routename-manageUsers .create-user-drawer .global-admin-checkbox-label { - margin-top: 0px; -} - -.routename-manageUsers .create-user-drawer #user-drawer-global-admin i { - top: -6px; -} - /* .routename-manageUsers .create-user-drawer #user-drawer-global-admin input { top: -35px; } */ -.routename-manageUsers .create-user-drawer .show-tooltip { - color: #c5c3c3; - font-size: 14px; -} - -.routename-manageUsers .create-user-drawer #new-image-select { - color: #2EB52B; - font-size: 12px; - font-weight: bolder; - background-color: white; - width: fit-content; - top: -120px; - left: 15px; - position: relative; - display: none; -} - -.routename-manageUsers .create-user-drawer .dz-remove { - font-size: 12px; -} - -.routename-manageUsers .manage-users-table .own-row { - opacity: 0; -} - x-vue-echarts > div:has(> .graph-tooltip-wrapper), x-vue-echarts > div:has(> .graph-notes-tooltip) { opacity: 0; } diff --git a/frontend/express/public/stylesheets/selectize/selectize.css b/frontend/express/public/stylesheets/selectize/selectize.css deleted file mode 100644 index 07fc02b1370..00000000000 --- a/frontend/express/public/stylesheets/selectize/selectize.css +++ /dev/null @@ -1,324 +0,0 @@ -/** - * selectize.css (v0.12.4) - * Copyright (c) 2013–2015 Brian Reavis & contributors - * - * 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. - * - * @author Brian Reavis - */ - - .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0, 0, 0, 0.06) !important; - border: 0 none !important; - -webkit-box-shadow: inset 0 0 12px 4px #ffffff; - box-shadow: inset 0 0 12px 4px #ffffff; -} -.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; -} -.selectize-control.plugin-drag_drop .ui-sortable-helper { - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); -} -.selectize-dropdown-header { - position: relative; - padding: 5px 8px; - border-bottom: 1px solid #d0d0d0; - background: #f8f8f8; - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.selectize-dropdown-header-close { - position: absolute; - right: 8px; - top: 50%; - color: #303030; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: #000000; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { - border-right: 0 none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:before { - display: none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup-header { - border-top: 0 none; -} -.selectize-control.plugin-remove_button [data-value] { - position: relative; - padding-right: 24px !important; -} -.selectize-control.plugin-remove_button [data-value] .remove { - z-index: 1; - /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: 2px 0 0 0; - border-left: 1px solid #d0d0d0; - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-control.plugin-remove_button [data-value] .remove:hover { - background: rgba(0, 0, 0, 0.05); -} -.selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: #cacaca; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { - background: none; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove { - border-left-color: #ffffff; -} -.selectize-control.plugin-remove_button .remove-single { - position: absolute; - right: 28px; - top: 6px; - font-size: 23px; -} -.selectize-control { - position: relative; -} -.selectize-dropdown, -.selectize-input, -.selectize-input input { - color: #303030; - font-family: inherit; - font-size: 13px; - line-height: 18px; - -webkit-font-smoothing: inherit; -} -.selectize-input, -.selectize-control.single .selectize-input.input-active { - background: #ffffff; - cursor: text; - display: inline-block; -} -.selectize-input { - border: 1px solid #d0d0d0; - padding: 8px 8px; - display: inline-block; - width: 100%; - overflow: hidden; - position: relative; - z-index: 1; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.selectize-control.multi .selectize-input.has-items { - padding: 6px 8px 3px; -} -.selectize-input.full { - background-color: #ffffff; -} -.selectize-input.disabled, -.selectize-input.disabled * { - cursor: default !important; -} -.selectize-input.focus { - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); -} -.selectize-input.dropdown-active { - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.selectize-input > * { - vertical-align: baseline; - display: -moz-inline-stack; - display: inline-block; - zoom: 1; - *display: inline; -} -.selectize-control.multi .selectize-input > div { - cursor: pointer; - margin: 0 3px 3px 0; - padding: 2px 6px; - background: #f2f2f2; - color: #303030; - border: 0 solid #d0d0d0; -} -.selectize-control.multi .selectize-input > div.active { - background: #e8e8e8; - color: #303030; - border: 0 solid #cacaca; -} -.selectize-control.multi .selectize-input.disabled > div, -.selectize-control.multi .selectize-input.disabled > div.active { - color: #7d7d7d; - background: #ffffff; - border: 0 solid #ffffff; -} -.selectize-input > input { - display: inline-block !important; - padding: 0 !important; - min-height: 0 !important; - max-height: none !important; - max-width: 100% !important; - margin: 0 2px 0 0 !important; - text-indent: 0 !important; - border: 0 none !important; - background: none !important; - line-height: inherit !important; - -webkit-user-select: auto !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; -} -.selectize-input > input::-ms-clear { - display: none; -} -.selectize-input > input:focus { - outline: none !important; -} -.selectize-input::after { - content: ' '; - display: block; - clear: left; -} -.selectize-input.dropdown-active::before { - content: ' '; - display: block; - position: absolute; - background: #f0f0f0; - height: 1px; - bottom: 0; - left: 0; - right: 0; -} -.selectize-dropdown { - position: absolute; - z-index: 10; - border: 1px solid #d0d0d0; - background: #ffffff; - margin: -1px 0 0 0; - border-top: 0 none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -webkit-border-radius: 0 0 3px 3px; - -moz-border-radius: 0 0 3px 3px; - border-radius: 0 0 3px 3px; -} -.selectize-dropdown [data-selectable] { - cursor: pointer; - overflow: hidden; -} -.selectize-dropdown [data-selectable] .highlight { - background: rgba(125, 168, 208, 0.2); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.selectize-dropdown [data-selectable], -.selectize-dropdown .optgroup-header { - padding: 5px 8px; -} -.selectize-dropdown .optgroup:first-child .optgroup-header { - border-top: 0 none; -} -.selectize-dropdown .optgroup-header { - color: #303030; - background: #ffffff; - cursor: default; -} -.selectize-dropdown .active { - background-color: #f5fafd; - color: #495c68; -} -.selectize-dropdown .active.create { - color: #495c68; -} -.selectize-dropdown .create { - color: rgba(48, 48, 48, 0.5); -} -.selectize-dropdown-content { - overflow-y: auto; - overflow-x: hidden; - max-height: 200px; - -webkit-overflow-scrolling: touch; -} -.selectize-control.single .selectize-input, -.selectize-control.single .selectize-input input { - cursor: pointer; -} -.selectize-control.single .selectize-input.input-active, -.selectize-control.single .selectize-input.input-active input { - cursor: text; -} -.selectize-control.single .selectize-input:after { - content: ' '; - display: block; - position: absolute; - top: 50%; - right: 15px; - margin-top: -3px; - width: 0; - height: 0; - border-style: solid; - border-width: 5px 5px 0 5px; - border-color: #808080 transparent transparent transparent; -} -.selectize-control.single .selectize-input.dropdown-active:after { - margin-top: -4px; - border-width: 0 5px 5px 5px; - border-color: transparent transparent #808080 transparent; -} -.selectize-control.rtl.single .selectize-input:after { - left: 15px; - right: auto; -} -.selectize-control.rtl .selectize-input > input { - margin: 0 4px 0 -2px !important; -} -.selectize-control .selectize-input.disabled { - opacity: 0.5; - background-color: #fafafa; -} \ No newline at end of file diff --git a/frontend/express/public/stylesheets/vue/clyvue.scss b/frontend/express/public/stylesheets/vue/clyvue.scss index dded6c34a1c..18a15258bd2 100644 --- a/frontend/express/public/stylesheets/vue/clyvue.scss +++ b/frontend/express/public/stylesheets/vue/clyvue.scss @@ -143,73 +143,125 @@ } .cly-vue-status-tag { - padding-right: 16.33px; - border-radius: 4px; display: inline-block; - &--small { - font-size: 12px; - line-height: 18px; - display: flex; - align-items: baseline; - font-weight: 500; - } - &--green { - background-color: #EBFAEE; - color: #12AF51; - padding: 0px 6px; + border-radius: 4px; + padding: 0px 6px; + + // .cly-vue-status-tag__blink + &__blink { + display: inline-block; + position: relative; + top: -1px; + width: 6px; + height: 6px; + border-radius: 8px; + vertical-align: middle; + margin-right: 2px; + animation: blinker 1.5s cubic-bezier(0.5, 0, 1, 1) infinite alternate; } - &--green &__blink{ - background-color: #12AF51; + + // .cly-vue-status-tag__skeleton + &__skeleton { + display: inline-block; + position: relative; + top: -1px; + background-color: #BDBDBD; + width: 40px; + height: 4px; + border-radius: 8px; + vertical-align: middle; + animation: blinker 1.5s cubic-bezier(0.5, 0, 1, 1) infinite alternate; } + + // .cly-vue-status-tag--blue &--blue { background-color: #E6F0FB; color: #017AFF; - padding: 0px 6px; - } - &--blue &__blink{ - background-color: #017AFF; + + // .cly-vue-status-tag--blue .cly-vue-status-tag__blink + & .cly-vue-status-tag__blink { + background-color: #017AFF; + } } - &--yellow { - background-color: #FCF5E5; - color: #CDAD7A; - padding: 0px 6px; + + // .cly-vue-status-tag--gray + &--gray { + background-color: #F5F5F5; + color: #BDBDBD; + + // .cly-vue-status-tag--gray .cly-vue-status-tag__blink + & .cly-vue-status-tag__blink { + background-color: #BDBDBD; + } } - &--yellow &__blink{ - background-color: #CDAD7A; + + // .cly-vue-status-tag--green + &--green { + background-color: #EBFAEE; + color: #12AF51; + + // .cly-vue-status-tag--green .cly-vue-status-tag__blink + & .cly-vue-status-tag__blink { + background-color: #12AF51; + } } + + // .cly-vue-status-tag--red &--red { background-color: #FBECE5; color: #D23F00; - padding: 0px 6px; - } - &--red &__blink{ - background-color: #D23F00; - } - &--gray { - background-color: #F5F5F5; - color: #BDBDBD; - padding: 0px 6px; + + // .cly-vue-status-tag--red .cly-vue-status-tag__blink + & .cly-vue-status-tag__blink { + background-color: #D23F00; + } } - &--gray &__blink{ - background-color: #BDBDBD; + + // .cly-vue-status-tag--small + &--small { + font-size: 12px; + line-height: 18px; + display: flex; + align-items: baseline; + font-weight: 500; + + // .cly-vue-status-tag--small .cly-vue-status-tag__blink + & .cly-vue-status-tag__blink { + /* + NOTE: This is a hack to make the blinking dot align with the blinking line + the hole component styles should be redone when working on the new UI + */ + top: 1px; + } + + // .cly-vue-status-tag--small .cly-vue-status-tag__skeleton + & .cly-vue-status-tag__skeleton { + /* + NOTE: This is a hack to make the blinking line align with the blinking dot + the hole component styles should be redone when working on the new UI + */ + top: 0px; + margin: 4px 0; + } } - &__blink { - position: relative; - top: -1px; - width: 6px; - height: 6px; - border-radius: 8px; - display: inline-block; - vertical-align: middle; - margin-right: 2px; - animation: blinker 1.5s cubic-bezier(0.5, 0, 1, 1) infinite alternate; + + // .cly-vue-status-tag--yellow + &--yellow { + background-color: #FCF5E5; + color: #CDAD7A; + + // .cly-vue-status-tag--yellow .cly-vue-status-tag__blink + & .cly-vue-status-tag__blink { + background-color: #CDAD7A; + } } + @keyframes blinker { 50% { - opacity: 0; + opacity: 0; } - } - } + } +} .cly-vue-theme-clydef { diff --git a/frontend/express/views/dashboard.html b/frontend/express/views/dashboard.html index 1c6ee63a39c..bb8c7957091 100644 --- a/frontend/express/views/dashboard.html +++ b/frontend/express/views/dashboard.html @@ -51,8 +51,6 @@ - - <% if (production) { %> @@ -62,18 +60,10 @@ <% } else { %> - - - - - - - - @@ -84,14 +74,6 @@ <% } %> - - - - - - - - @@ -99,22 +81,14 @@ - - - - - - - - @@ -135,21 +109,9 @@ - - - - - - - - - - - - <% } %> @@ -191,1572 +153,7 @@
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - check_circle - -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -

      -
      -
      .CSV
      -
      .XLSX
      -
      .JSON
      -
      -
      -

      -

      - - -
      -
      -
      -
      -

      -
      -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - <% if (production) { %> @@ -1765,22 +162,6 @@

      {{this.nam <% } else { %> - - - - - - - - - - - - - - - - @@ -1815,7 +196,6 @@

      {{this.nam - @@ -1825,8 +205,7 @@

      {{this.nam - - + diff --git a/frontend/express/views/forgot.html b/frontend/express/views/forgot.html index 6c9d281110a..61847e2e2aa 100644 --- a/frontend/express/views/forgot.html +++ b/frontend/express/views/forgot.html @@ -100,7 +100,7 @@

      - + diff --git a/frontend/express/views/login.html b/frontend/express/views/login.html index 2e3774d9f13..83a476864d5 100644 --- a/frontend/express/views/login.html +++ b/frontend/express/views/login.html @@ -106,11 +106,10 @@

      - + - - + - + - - diff --git a/plugins/two-factor-auth/frontend/public/templates/setup2fa.html b/plugins/two-factor-auth/frontend/public/templates/setup2fa.html index 54e107e7355..9fd9f82874d 100644 --- a/plugins/two-factor-auth/frontend/public/templates/setup2fa.html +++ b/plugins/two-factor-auth/frontend/public/templates/setup2fa.html @@ -95,7 +95,6 @@ - diff --git a/plugins/views/api/api.js b/plugins/views/api/api.js index 8d5d9cdbca6..6668dac8a45 100644 --- a/plugins/views/api/api.js +++ b/plugins/views/api/api.js @@ -1349,178 +1349,216 @@ const escapedViewSegments = { "name": true, "segment": true, "height": true, "wi * @param {Object} params - Default parameters object * @returns {undefined} Returns nothing */ - function getHeatmap(params) { - var result = {types: [], data: []}; + async function getHeatmap(params) { + const result = {types: [], data: [], domains: []}; - var device = {}; + let device = {}; try { device = JSON.parse(params.qstring.device); } catch (SyntaxError) { - console.log('Parse device failed: ', params.qstring.device); + log.e('Parse device failed: ', params.qstring.device); } - var actionType = params.qstring.actionType; + const actionType = params.qstring.actionType; if (!(device.minWidth >= 0) || !(device.maxWidth >= 0)) { common.returnMessage(params, 400, 'Bad request parameter: device'); return false; } - var collectionName = "drill_events" + crypto.createHash('sha1').update("[CLY]_action" + params.qstring.app_id).digest('hex'); - common.drillDb.collection(collectionName).findOne({"_id": "meta_v2"}, {_id: 0, "sg.type": 1, "sg.domain": 1}, function(err1, meta) { - if (meta && meta.sg && meta.sg.type) { - result.types = Object.keys(meta.sg.type.values); + + if (params.qstring.period) { + //check if period comes from datapicker + if (params.qstring.period.indexOf(',') !== -1) { + try { + params.qstring.period = JSON.parse(params.qstring.period); + } + catch (SyntaxError) { + log.d('Parsing custom period failed!'); + common.returnMessage(params, 400, 'Bad request parameter: period'); + return false; + } } else { - result.types = []; + switch (params.qstring.period) { + case 'month': + case 'day': + case 'yesterday': + case 'hour': + break; + default: + if (!/([0-9]+)days/.test(params.qstring.period)) { + common.returnMessage(params, 400, 'Bad request parameter: period'); + return false; + } + break; + } } - if (meta && meta.sg && meta.sg.domain) { - result.domains = Object.keys(meta.sg.domain.values).map(function(item) { - return common.db.decode(item); - }); + } + else { + common.returnMessage(params, 400, 'Missing request parameter: period'); + return false; + } + + countlyCommon.setTimezone(params.appTimezone); + countlyCommon.setPeriod(params.qstring.period); + + const periodObj = countlyCommon.periodObj; + const matchQuery = {}; + const now = params.time.now.toDate(); + + //create current period array if it does not exist + if (!periodObj.currentPeriodArr) { + periodObj.currentPeriodArr = []; + + //create a period array that starts from the beginning of the current year until today + if (params.qstring.period === 'month') { + for (let i = 0; i < (now.getMonth() + 1); i++) { + const moment1 = moment(); + const daysInMonth = moment1.month(i).daysInMonth(); + + for (let j = 0; j < daysInMonth; j++) { + periodObj.currentPeriodArr.push(periodObj.activePeriod + '.' + (i + 1) + '.' + (j + 1)); + + // If current day of current month, just break + if ((i === now.getMonth()) && (j === (now.getDate() - 1))) { + break; + } + } + } } + //create a period array that starts from the beginning of the current month until today + else if (params.qstring.period === 'day') { + for (let i = 0; i < now.getDate(); i++) { + periodObj.currentPeriodArr.push(periodObj.activePeriod + '.' + (i + 1)); + } + } + //create one day period array else { - result.domains = []; + periodObj.currentPeriodArr.push(periodObj.activePeriod); } - common.drillDb.collection(collectionName).findOne({"_id": "meta"}, {_id: 0, "sg.type": 1, "sg.domain": 1}, function(err2, meta2) { - if (meta2 && meta2.sg && meta2.sg.type) { - common.arrayAddUniq(result.types, meta2.sg.type.values); - } - if (meta2 && meta2.sg && meta2.sg.domain) { - common.arrayAddUniq(result.domains, meta2.sg.domain.values); - } - var eventHash = crypto.createHash('sha1').update("[CLY]_action" + params.qstring.app_id).digest('hex'); - var collectionMeta = "drill_meta" + params.qstring.app_id; - common.drillDb.collection(collectionMeta).findOne({"_id": "meta_" + eventHash}, {_id: 0, "sg.domain": 1}, function(err3, meta_event) { - if (meta_event && meta_event.sg && meta_event.sg.type) { - common.arrayAddUniq(result.types, Object.keys(meta_event.sg.type.values)); - } - if (meta_event && meta_event.sg && meta_event.sg.domain) { - common.arrayAddUniq(result.domains, Object.keys(meta_event.sg.domain.values)); - } + } - if (params.qstring.period) { - //check if period comes from datapicker - if (params.qstring.period.indexOf(",") !== -1) { - try { - params.qstring.period = JSON.parse(params.qstring.period); - } - catch (SyntaxError) { - log.d('Parsing custom period failed!'); - common.returnMessage(params, 400, 'Bad request parameter: period'); - return false; - } - } - else { - switch (params.qstring.period) { - case "month": - case "day": - case "yesterday": - case "hour": - break; - default: - if (!/([0-9]+)days/.test(params.qstring.period)) { - common.returnMessage(params, 400, 'Bad request parameter: period'); - return false; - } - break; - } - } - } - else { - common.returnMessage(params, 400, 'Missing request parameter: period'); - return false; - } - countlyCommon.setTimezone(params.appTimezone); - countlyCommon.setPeriod(params.qstring.period); - var periodObj = countlyCommon.periodObj, - queryObject = {}, - now = params.time.now.toDate(); + //get timestamps of start of days (DD-MM-YYYY-00:00) with respect to apptimezone for both beginning and end of period arrays + let tmpArr; + const ts = {}; - //create current period array if it does not exist - if (!periodObj.currentPeriodArr) { - periodObj.currentPeriodArr = []; + tmpArr = periodObj.currentPeriodArr[0].split('.'); + ts.$gte = moment(new Date(Date.UTC(parseInt(tmpArr[0]), parseInt(tmpArr[1]) - 1, parseInt(tmpArr[2])))); + if (params.appTimezone) { + ts.$gte.tz(params.appTimezone); + } + ts.$gte = ts.$gte.valueOf() - ts.$gte.utcOffset() * 60000; - //create a period array that starts from the beginning of the current year until today - if (params.qstring.period === "month") { - for (let i = 0; i < (now.getMonth() + 1); i++) { - var moment1 = moment(); - var daysInMonth = moment1.month(i).daysInMonth(); + tmpArr = periodObj.currentPeriodArr[periodObj.currentPeriodArr.length - 1].split('.'); + ts.$lt = moment(new Date(Date.UTC(parseInt(tmpArr[0]), parseInt(tmpArr[1]) - 1, parseInt(tmpArr[2])))).add(1, 'days'); + if (params.appTimezone) { + ts.$lt.tz(params.appTimezone); + } + ts.$lt = ts.$lt.valueOf() - ts.$lt.utcOffset() * 60000; + + matchQuery.ts = ts; + matchQuery.a = params.qstring.app_id; + matchQuery.e = '[CLY]_action'; + matchQuery['sg.width'] = {}; + matchQuery['sg.width'].$gt = device.minWidth; + matchQuery['sg.width'].$lte = device.maxWidth; + matchQuery['sg.type'] = actionType; + + const projectionQuery = { + _id: 0, + c: 1, + 'sg.type': 1, + 'sg.width': 1, + 'sg.height': 1 + }; + + if (actionType === 'scroll') { + projectionQuery['sg.y'] = 1; + matchQuery['sg.view'] = params.qstring.view; + } + else { + projectionQuery['sg.x'] = 1; + projectionQuery['sg.y'] = 1; + matchQuery['up.lv'] = params.qstring.view; + } - for (var j = 0; j < daysInMonth; j++) { - periodObj.currentPeriodArr.push(periodObj.activePeriod + "." + (i + 1) + "." + (j + 1)); + if (params.qstring.segment) { + matchQuery['sg.segment'] = params.qstring.segment; + } - // If current day of current month, just break - if ((i === now.getMonth()) && (j === (now.getDate() - 1))) { - break; - } - } - } - } - //create a period array that starts from the beginning of the current month until today - else if (params.qstring.period === "day") { - for (let i = 0; i < now.getDate(); i++) { - periodObj.currentPeriodArr.push(periodObj.activePeriod + "." + (i + 1)); - } - } - //create one day period array - else { - periodObj.currentPeriodArr.push(periodObj.activePeriod); - } - } + const aggregateQuery = [ + { $match: matchQuery }, + ]; + + const use_union_with = plugins.getConfig('drill', params.app_id && params.app && params.app.plugins, true).use_union_with; + + if (use_union_with) { + const oldCollectionName = 'drill_events' + crypto.createHash('sha1').update('[CLY]_action' + params.qstring.app_id).digest('hex'); + const eventHash = crypto.createHash('sha1').update('[CLY]_action' + params.qstring.app_id).digest('hex'); + + const metaQuery = [ + { + $facet: { + meta: [ + { $match: { _id: 'meta' } }, + { $project: { _id: 0, 'sg.type': 1, 'sg.domain': 1 } }, + { $limit: 1 }, + ], + meta_v2: [ + { $match: { _id: 'meta_v2' } }, + { $project: { _id: 0, 'sg.type': 1, 'sg.domain': 1 } }, + { $limit: 1 }, + ], + }, + }, + ]; - //get timestamps of start of days (DD-MM-YYYY-00:00) with respect to apptimezone for both beginning and end of period arrays - var tmpArr; - var ts = {}; + const metaKeys = ['meta', 'meta_v2']; + const metas = await common.drillDb.collection(oldCollectionName).aggregate(metaQuery).toArray(); + metaKeys.forEach((key) => { + if (key in metas[0]) { + const meta = metas[0][key][0]; - tmpArr = periodObj.currentPeriodArr[0].split("."); - ts.$gte = moment(new Date(Date.UTC(parseInt(tmpArr[0]), parseInt(tmpArr[1]) - 1, parseInt(tmpArr[2])))); - if (params.appTimezone) { - ts.$gte.tz(params.appTimezone); + if (meta && meta.sg && meta.sg.type && meta.sg.type.values) { + common.arrayAddUniq(result.types, meta.sg.type.values); } - ts.$gte = ts.$gte.valueOf() - ts.$gte.utcOffset() * 60000; - tmpArr = periodObj.currentPeriodArr[periodObj.currentPeriodArr.length - 1].split("."); - ts.$lt = moment(new Date(Date.UTC(parseInt(tmpArr[0]), parseInt(tmpArr[1]) - 1, parseInt(tmpArr[2])))).add(1, 'days'); - if (params.appTimezone) { - ts.$lt.tz(params.appTimezone); + if (meta && meta.sg && meta.sg.domain && meta.sg.domain.values) { + common.arrayAddUniq(result.domains, meta.sg.domain.values); } - ts.$lt = ts.$lt.valueOf() - ts.$lt.utcOffset() * 60000; + } + }); - queryObject.ts = ts; - queryObject["sg.width"] = {}; - queryObject["sg.width"].$gt = device.minWidth; - queryObject["sg.width"].$lte = device.maxWidth; - queryObject["sg.type"] = actionType; + const moreMeta = await common.drillDb.collection(`drill_meta${params.qstring.app_id}`).findOne( + { _id: `meta_${eventHash}` }, + { _id: 0, 'sg.domain': 1 }, + ); - var projections = { - _id: 0, - c: 1, - "sg.type": 1, - "sg.width": 1, - "sg.height": 1 - }; + if (moreMeta && moreMeta.sg && moreMeta.sg.domain) { + common.arrayAddUniq(result.domains, Object.keys(moreMeta.sg.domain.values)); + } - if (actionType === "scroll") { - projections["sg.y"] = 1; - queryObject["sg.view"] = params.qstring.view; - } - else { - projections["sg.x"] = 1; - projections["sg.y"] = 1; - queryObject["up.lv"] = params.qstring.view; - } + const matchQueryOld = Object.assign({}, matchQuery); + delete matchQueryOld.a; + delete matchQueryOld.e; - if (params.qstring.segment) { - queryObject["sg.segment"] = params.qstring.segment; - } - common.drillDb.collection(collectionName).find(queryObject, projections).toArray(function(err, data) { - result.data = data; - common.returnOutput(params, result, true, params.token_headers); - }); - }); + aggregateQuery.push({ + $unionWith: { coll: oldCollectionName, pipeline: [{ $match: matchQueryOld }] }, }); - }); + } + + aggregateQuery.push({ $project: projectionQuery }); + + try { + const data = await common.drillDb.collection('drill_events').aggregate(aggregateQuery, { allowDiskUse: true }).toArray(); + result.data = data; + common.returnOutput(params, result, true, params.token_headers); + } + catch (err) { + log.e(err); + common.returnMessage(params, 500, 'Error fetching drill events'); + } } plugins.register("/o/actions", function(ob) { diff --git a/plugins/views/frontend/public/javascripts/countly.views.js b/plugins/views/frontend/public/javascripts/countly.views.js index fa38f427d65..d756c3c4c20 100644 --- a/plugins/views/frontend/public/javascripts/countly.views.js +++ b/plugins/views/frontend/public/javascripts/countly.views.js @@ -1222,20 +1222,6 @@ }); - jQuery.fn.dataTableExt.oSort['view-frequency-asc'] = function(x, y) { - x = countlyViews.getFrequencyIndex(x); - y = countlyViews.getFrequencyIndex(y); - - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }; - - jQuery.fn.dataTableExt.oSort['view-frequency-desc'] = function(x, y) { - x = countlyViews.getFrequencyIndex(x); - y = countlyViews.getFrequencyIndex(y); - - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }; - app.addAppSwitchCallback(function(appId) { if (app._isFirstLoad !== true && countlyAuth.validateRead(FEATURE_NAME) && CountlyHelpers.isPluginEnabled(FEATURE_NAME)) { countlyViews.loadList(appId); diff --git a/plugins/views/scripts/omitViewSegments.js b/plugins/views/scripts/omitViewSegments.js index 4ae9bcfb482..1e03daafb5c 100644 --- a/plugins/views/scripts/omitViewSegments.js +++ b/plugins/views/scripts/omitViewSegments.js @@ -16,22 +16,19 @@ var app_list = []; //leave empty to process all apps or add specific app ids to var DRY_RUN = false; //set to true to see what will be deleted without actually deleting anything var save_list_in_database = true; //If omitting is successful, should list be saved in views setting. If saved in views setting, it will ensure segment not reappearing on incoming data. It will have effect only if upgraded to version at least 23.06.16 -var omit = ["Cats", "Dogs"];//list with segments to omit +var omitSegments = [];//list with segments to omit. If empty will check allsegments in this app and omit those with more than segmentValueLimit values. +var segmentValueLimit = 10; //segment value limit. If segment has more than this number of values, it will be omitted. Promise.all([pluginManager.dbConnection("countly")]).spread(function(countlyDb) { - if (!Array.isArray(omit) || omit.length === 0) { - console.log("No segments to omit"); - countlyDb.close(); - return; - } - else { - console.log("Validating app list: "); - getAppList({db: countlyDb}, function(err, apps) { - if (apps && apps.length > 0) { - console.log(apps.length + " apps found"); - Promise.each(apps, function(app) { - return new Promise(function(resolve) { - console.log("processing app:" + app.name); + console.log("Validating app list: "); + getAppList({db: countlyDb}, function(err, apps) { + if (apps && apps.length > 0) { + console.log(apps.length + " apps found"); + Promise.each(apps, function(app) { + return new Promise(function(resolve) { + console.log("processing app:" + app.name); + getOmitList(omitSegments, {db: countlyDb, app_id: app._id}, function(error, omit) { + omit = omit || []; var promises = []; var errCn = 0; for (var z = 0; z < omit.length; z++) { @@ -54,56 +51,107 @@ Promise.all([pluginManager.dbConnection("countly")]).spread(function(countlyDb) })); } Promise.all(promises).then(function() { - console.log("Segments omittion compleated for:" + JSON.stringify(omit)); - if (errCn > 0) { - console.log("Some errors occured while deleting collections"); - resolve(); - } - else { - if (save_list_in_database && !DRY_RUN) { - console.log("adding segments to omit list in view document. Only if upgraded to lates version this list will be taken in account on incoming data."); + if (omit.length > 0) { + console.log("Segments omittion compleated for:" + JSON.stringify(omit)); - var unset = {}; - for (var z = 0; z < omit.length; z++) { - unset["segments." + omit[z]] = ""; - } + if (errCn > 0) { + console.log("Some errors occured while deleting collections"); + resolve(); + } + else { + if (save_list_in_database && !DRY_RUN) { + console.log("adding segments to omit list in view document. Only if upgraded to lates version this list will be taken in account on incoming data."); - countlyDb.collection("views").update({_id: app._id}, {$set: {"omit": omit}, "$unset": unset}, function(err) { - if (err) { - console.log(err); + var unset = {}; + for (var z = 0; z < omit.length; z++) { + unset["segments." + omit[z]] = ""; } + + countlyDb.collection("views").update({_id: app._id}, {"$addToSet": {"omit": {"$each": omit}}, "$unset": unset}, function(err) { + if (err) { + console.log(err); + } + resolve(); + }); + } + else { resolve(); - }); - } - else { - resolve(); - } + } + } + } + else { + console.log("No segments to omit"); + resolve(); } }); }); - }).then(function() { - console.log("completed"); - countlyDb.close(); - return; - - }).catch(function(rejection) { - console.log("Error"); - console.log("Error:", rejection); - countlyDb.close(); - return; }); - } - else { - console.log("exiting as there are no apps to process."); + }).then(function() { + console.log("completed"); countlyDb.close(); return; + + }).catch(function(rejection) { + console.log("Error"); + console.log("Error:", rejection); + countlyDb.close(); + return; + }); + } + else { + console.log("exiting as there are no apps to process."); + countlyDb.close(); + return; + } + }); + + +}); + +function getOmitList(omit, options, callback) { + if (omit.length === 0) { + var segmentsToOmit = []; + options.db.collection("views").find({_id: options.db.ObjectID(options.app_id)}).toArray(function(err, result) { + if (err) { + console.log("Error getting omit list"); + callback(err, []); + } + else { + if (result && result.length > 0) { + var segCN = 0; + result = result[0]; + + for (var seg in result.segments) { + segCN++; + var cnn = 0; + try { + cnn = Object.keys(result.segments[seg]).length; + } + catch (e) { + console.log("Error getting segment count for " + seg + " in app " + options.app_id); + cnn = 0; + } + result.segments[seg] = cnn; + if (cnn > segmentValueLimit) { + segmentsToOmit.push(seg); + } + + } + console.log("App +" + options.app_id + " has " + segCN + " segments: " + JSON.stringify(result.segments)); + if (result.omit && result.omit.length > 0) { + console.log("Currently ommited:" + JSON.stringify(result.omit)); + } + } + callback(null, segmentsToOmit); } }); } - -}); + else { + return JSON.parse(JSON.stringify(omit)); + } +} function getAppList(options, callback) { var query = {}; diff --git a/plugins/views/tests/heatmaps.js.old b/plugins/views/tests/heatmaps.js.old new file mode 100644 index 00000000000..ac801f2c758 --- /dev/null +++ b/plugins/views/tests/heatmaps.js.old @@ -0,0 +1,202 @@ +const crypto = require('crypto'); + +const moment = require('moment'); +const should = require('should'); +const spt = require('supertest'); + +const pluginManager = require('../../pluginManager.js'); +const testUtils = require('../../../test/testUtils.js'); + +const request = spt(testUtils.url); +const APP_ID = testUtils.get('APP_ID'); +const API_KEY_ADMIN = testUtils.get('API_KEY_ADMIN'); +const APP_KEY = testUtils.get('APP_KEY'); + +describe('Heatmap', async() => { + const clickData = { + type: 'click', + x: 1353, + y: 230, + width: 1440, + height: 3586, + }; + + before(async() => { + await request + .get('/i') + .query({ + api_key: API_KEY_ADMIN, + app_id: APP_ID, + app_key: APP_KEY, + device_id: 'heatmap_test', + events: JSON.stringify([ + { + key: '[CLY]_view', + count: 1, + timestamp: moment('2010-01-02').valueOf(), + hour: 21, + segmentation: { + name: 'Home', + visit: 1, + start: 1, + exit: 1, + bounce: 0, + }, + }, + ]), + }) + .expect(200); + + await request + .get('/i') + .query({ + api_key: API_KEY_ADMIN, + app_id: APP_ID, + app_key: APP_KEY, + device_id: 'heatmap_test', + events: JSON.stringify([ + { + key: '[CLY]_action', + count: 1, + timestamp: moment('2010-01-02').valueOf(), + hour: 21, + segmentation: { + ...clickData, + domain: 'https://doma.in', + view: 'Home', + }, + }, + ]), + }) + .expect(200); + }); + + it('gets heatmap data from drill_events collection', async() => { + const { body } = await request.post('/o/actions') + .send({ + api_key: API_KEY_ADMIN, + app_id: APP_ID, + app_key: APP_KEY, + view: 'Home', + period: JSON.stringify([moment('2010-01-01').valueOf(), moment('2010-01-31').valueOf()]), + device: JSON.stringify({ type: 'all', displayText: 'All', minWidth: 0, maxWidth: 10240 }), + actionType: 'click', + }); + + const { data } = body; + should(data.length).equal(1); + should(data[0].sg).eql(clickData); + }); + + it('gets heatmap data from old drill_events collection if union_with is true', async() => { + const db = await pluginManager.dbConnection('countly_drill'); + const oldCollectionName = 'drill_events' + crypto.createHash('sha1').update('[CLY]_action' + APP_ID).digest('hex'); + + const resp = await request.get('/o/apps/plugins?api_key=' + API_KEY_ADMIN + '&app_id=' + APP_ID); + const drillConfig = resp.body.plugins.drill; + + drillConfig.use_union_with = true; + + await request.post('/i/apps/update/plugins') + .send({ + app_id: APP_ID, + api_key: API_KEY_ADMIN, + args: { drill: drillConfig }, + }); + + await db.collection(oldCollectionName).insertOne({ + did: 'heatmap_test', + sg: { + ...clickData, + domain: 'https://doma.in', + view: 'Home', + }, + ts: moment('2010-01-02').valueOf(), + up: { lv: 'Home' }, + }); + + const { body } = await request.post('/o/actions') + .send({ + api_key: API_KEY_ADMIN, + app_id: APP_ID, + app_key: APP_KEY, + view: 'Home', + period: JSON.stringify([moment('2010-01-01').valueOf(), moment('2010-01-31').valueOf()]), + device: JSON.stringify({ type: 'all', displayText: 'All', minWidth: 0, maxWidth: 10240 }), + actionType: 'click', + }); + + const { data } = body; + should(data.length).equal(2); + should(data[0].sg).eql(clickData); + should(data[1].sg).eql(clickData); + + await db.collection(oldCollectionName).remove({ did: 'heatmap_test' }); + + db.close(); + }); + + it('does not get heatmap data from old drill_events collection if union_with is false', async() => { + const db = await pluginManager.dbConnection('countly_drill'); + const oldCollectionName = 'drill_events' + crypto.createHash('sha1').update('[CLY]_action' + APP_ID).digest('hex'); + + const resp = await request.get('/o/apps/plugins?api_key=' + API_KEY_ADMIN + '&app_id=' + APP_ID); + const drillConfig = resp.body.plugins.drill; + + drillConfig.use_union_with = false; + + await request.post('/i/apps/update/plugins') + .send({ + app_id: APP_ID, + api_key: API_KEY_ADMIN, + args: { drill: drillConfig }, + }); + + await db.collection(oldCollectionName).insertOne({ + did: 'heatmap_test', + sg: { + ...clickData, + domain: 'https://doma.in', + view: 'Home', + }, + ts: moment('2010-01-02').valueOf(), + up: { lv: 'Home' }, + }); + + const { body } = await request.post('/o/actions') + .send({ + api_key: API_KEY_ADMIN, + app_id: APP_ID, + app_key: APP_KEY, + view: 'Home', + period: JSON.stringify([moment('2010-01-01').valueOf(), moment('2010-01-31').valueOf()]), + device: JSON.stringify({ type: 'all', displayText: 'All', minWidth: 0, maxWidth: 10240 }), + actionType: 'click', + }); + + const { data } = body; + should(data.length).equal(1); + should(data[0].sg).eql(clickData); + + drillConfig.use_union_with = true; + + await request.post('/i/apps/update/plugins') + .send({ + app_id: APP_ID, + api_key: API_KEY_ADMIN, + args: { drill: drillConfig }, + }); + + await db.collection(oldCollectionName).remove({ did: 'heatmap_test' }); + + db.close(); + }); + + after(async() => { + const db = await pluginManager.dbConnection('countly_drill'); + + await db.collection('drill_events').remove({ did: 'heatmap_test' }); + + db.close(); + }); +}); diff --git a/plugins/views/tests/index.js b/plugins/views/tests/index.js new file mode 100644 index 00000000000..9e18e762147 --- /dev/null +++ b/plugins/views/tests/index.js @@ -0,0 +1,2 @@ +require('./views.js'); +//require('./heatmaps.js'); \ No newline at end of file diff --git a/plugins/views/tests.js b/plugins/views/tests/views.js similarity index 99% rename from plugins/views/tests.js rename to plugins/views/tests/views.js index 8ec2675af0f..b1ffe532ee7 100644 --- a/plugins/views/tests.js +++ b/plugins/views/tests/views.js @@ -1,6 +1,6 @@ var request = require('supertest'); var should = require('should'); -var testUtils = require("../../test/testUtils"); +var testUtils = require("../../../test/testUtils"); request = request.agent(testUtils.url); var APP_KEY = ""; var API_KEY_ADMIN = ""; @@ -1319,4 +1319,4 @@ describe('Testing views plugin', function() { }); }); }); -}); \ No newline at end of file +}); diff --git a/ui-tests/cypress/e2e/dashboard/feedback/ratings/widgets.cy.js b/ui-tests/cypress/e2e/dashboard/feedback/ratings/widgets.cy.js index e9da320d12a..bf15e13fe9f 100755 --- a/ui-tests/cypress/e2e/dashboard/feedback/ratings/widgets.cy.js +++ b/ui-tests/cypress/e2e/dashboard/feedback/ratings/widgets.cy.js @@ -225,6 +225,8 @@ describe('Create New Widget', () => { contactViaCheckboxLabelText: widget.contactViaCheckboxLabelText, contactEmail: widgetRate.contactEmail, submitButtonText: widget.submitButtonText, + //TODO SER-1971 There is no Aggrement Checkbox in the demo page, Also Look at the line 136 in demoWidgetPage.js + //hasAggrementCheckbox: true, consentText: 'I agree to the Terms and Conditions and Privacy Policy.', selectedMainColor: widget.mainColor, selectedFontColor: widget.FontColor, diff --git a/ui-tests/cypress/lib/dashboard/analytics/events/overview.js b/ui-tests/cypress/lib/dashboard/analytics/events/overview.js index 58b3c5418d7..b40987d3d07 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/events/overview.js +++ b/ui-tests/cypress/lib/dashboard/analytics/events/overview.js @@ -18,7 +18,7 @@ const verifyStaticElementsOfPage = () => { labelElement: eventsOverviewPageElements.PAGE_SUB_TITLE, labelText: "Event Metrics", tooltipElement: eventsOverviewPageElements.PAGE_SUB_TITLE_TOOLTIP, - tooltipText: "Overview of the metrics calculated by the identified Events, in the last 30 days." + tooltipText: "An overview of the metrics calculated by the identified Events in the last 30 days." }); cy.verifyElement({ @@ -337,7 +337,7 @@ const verifyMonitorEventsMetricCard = ({ cy.verifyElement({ labelElement: eventsOverviewMonitorEventsMetricCardElements().EMPTY_MONITOR_EVENTS_TABLE_TITLE, - labelText: "This application doesn't have any custom events", + labelText: "This application does not have any custom events.", }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/geo/countries/countries.js b/ui-tests/cypress/lib/dashboard/analytics/geo/countries/countries.js index a59b6b37565..2f9a2835a4f 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/geo/countries/countries.js +++ b/ui-tests/cypress/lib/dashboard/analytics/geo/countries/countries.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: countriesPageElements.PAGE_TITLE, labelText: "Countries", tooltipElement: countriesPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "An overview of the geographical distribution of your users and their sessions in the selected time period." + tooltipText: "An overview of the geographical distribution of your users and their sessions within the selected time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/geo/languages/languages.js b/ui-tests/cypress/lib/dashboard/analytics/geo/languages/languages.js index ca137d68dd2..c01e5510ec3 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/geo/languages/languages.js +++ b/ui-tests/cypress/lib/dashboard/analytics/geo/languages/languages.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: languagesPageElements.PAGE_TITLE, labelText: "Languages", tooltipElement: languagesPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Details of the application languages your users are using, in the selected time period and as determined by their default device language settings." + tooltipText: "Details of the application's languages your users use in the selected time period, based on their default device language settings." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/loyalty/timesOfDay.js b/ui-tests/cypress/lib/dashboard/analytics/loyalty/timesOfDay.js index b2c2ee90c48..e04afc038c7 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/loyalty/timesOfDay.js +++ b/ui-tests/cypress/lib/dashboard/analytics/loyalty/timesOfDay.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: timesOfDayPageElements.PAGE_TITLE, labelText: "Times of Day", tooltipElement: timesOfDayPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Scatter plot chart with times and days of Session and Event occurrences in your application, based on users' local time." + tooltipText: "Shows a scatter plot chart with the times and days of session and event occurrences in your application, based on users' local time." }); cy.scrollPageToTop(); diff --git a/ui-tests/cypress/lib/dashboard/analytics/loyalty/userActivity.js b/ui-tests/cypress/lib/dashboard/analytics/loyalty/userActivity.js index 6203117101a..e60ef767d11 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/loyalty/userActivity.js +++ b/ui-tests/cypress/lib/dashboard/analytics/loyalty/userActivity.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: userActivityPageElements.PAGE_TITLE, labelText: "User Activity", tooltipElement: userActivityPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Overview of the total number of users who started a session on your application, distributed in pre-set categories of numbers of sessions." + tooltipText: "An overview of the total number of users who started a session on your application, distributed in pre-set categories based on the number of sessions." }); cy.scrollPageToTop(); diff --git a/ui-tests/cypress/lib/dashboard/analytics/sessions/frequency.js b/ui-tests/cypress/lib/dashboard/analytics/sessions/frequency.js index 58eba70c7a8..a6e22a2d007 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/sessions/frequency.js +++ b/ui-tests/cypress/lib/dashboard/analytics/sessions/frequency.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: sessionFrequencyPageElements.PAGE_TITLE, labelText: "Session Frequency", tooltipElement: sessionFrequencyPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Number of times users open your application, in the selected time period, distributed into frequency ranges." + tooltipText: "The number of times users open your application within the selected time period, distributed into frequency ranges." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/sessions/overview.js b/ui-tests/cypress/lib/dashboard/analytics/sessions/overview.js index 43f87832d9b..433bdeed853 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/sessions/overview.js +++ b/ui-tests/cypress/lib/dashboard/analytics/sessions/overview.js @@ -163,7 +163,7 @@ const verifySessionsOverviewChart = ({ labelElement: analyticsSessionOverviewEChartElements.CHART_TOTAL_SESSIONS_LABEL, labelText: "Total Sessions", tooltipElement: analyticsSessionOverviewEChartElements.CHART_TOTAL_SESSIONS_TOOLTIP, - tooltipText: "Number of times your application is opened, by new or returning users, in the selected time period.", + tooltipText: "The number of times your application is opened by new or returning users within the selected time period.", }); cy.verifyElement({ @@ -187,7 +187,7 @@ const verifySessionsOverviewChart = ({ labelElement: analyticsSessionOverviewEChartElements.CHART_NEW_SESSIONS_LABEL, labelText: "New Sessions", tooltipElement: analyticsSessionOverviewEChartElements.CHART_NEW_SESSIONS_TOOLTIP, - tooltipText: "Number of times your application is opened by a new user, in the selected time period. It is equal to the number of New Users and it only counts the first session the user had.", + tooltipText: "The number of times your application is opened by a new user within the selected time period. This is equal to the number of New Users and only counts the user's first session.", }); cy.verifyElement({ @@ -211,7 +211,7 @@ const verifySessionsOverviewChart = ({ labelElement: analyticsSessionOverviewEChartElements.CHART_UNIQUE_SESSIONS_LABEL, labelText: "Unique Sessions", tooltipElement: analyticsSessionOverviewEChartElements.CHART_UNIQUE_SESSIONS_TOOLTIP, - tooltipText: "Number of times your application is opened by a new or returning user from a unique device, in the selected time period. It is equal to the number of Total Users.", + tooltipText: "The number of times your application is opened by a new or returning user from a unique device within the selected time period. This is equal to the number of Total Users.", }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/technology/carriers.js b/ui-tests/cypress/lib/dashboard/analytics/technology/carriers.js index b6aeaaabd11..c4fdec29251 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/technology/carriers.js +++ b/ui-tests/cypress/lib/dashboard/analytics/technology/carriers.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: carriersPageElements.PAGE_TITLE, labelText: "Carriers", tooltipElement: carriersPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Detailed information on the network carriers of the devices through which your users access your application, in the selected time period." + tooltipText: "Detailed information on the network carriers of the devices through which your users access your application within the selected time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/technology/devicesAndTypes.js b/ui-tests/cypress/lib/dashboard/analytics/technology/devicesAndTypes.js index 1148ab595ac..e7ee269d590 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/technology/devicesAndTypes.js +++ b/ui-tests/cypress/lib/dashboard/analytics/technology/devicesAndTypes.js @@ -11,7 +11,7 @@ const verifyStaticElementsOfPage = () => { labelElement: devicesAndTypesPageElements.PAGE_TITLE, labelText: "Devices and Types", tooltipElement: devicesAndTypesPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Details of the device models and types from which your users access your application, in the selected time period." + tooltipText: "Details of the device models and types from which your users access your application within the selected time period." }); cy.verifyElement({ @@ -66,21 +66,21 @@ const verifyStaticElementsOfPage = () => { labelElement: devicesEGraphElements().TOP_PLATFORMS_LABEL, labelText: "Top Platforms", tooltipElement: devicesEGraphElements().TOP_PLATFORMS_TOOLTIP, - tooltipText: "Top 5 versions of the platforms of your users’ sessions, in the selected time period." + tooltipText: "The top 5 platform versions of your users’ sessions within the selected time period." }); cy.verifyElement({ labelElement: devicesEGraphElements().TOP_PLATFORMS_VERSIONS_LABEL, labelText: "Top Platform Versions", tooltipElement: devicesEGraphElements().TOP_PLATFORMS_VERSIONS_TOOLTIP, - tooltipText: "Top 3 versions of the platforms of your users' sessions, in the selected time period." + tooltipText: "The top 3 platform versions of your users' sessions within the selected time period." }); cy.verifyElement({ labelElement: devicesEGraphElements().TOP_RESOLUTIONS_LABEL, labelText: "Top Resolutions", tooltipElement: devicesEGraphElements().TOP_RESOLUTIONS_TOOLTIP, - tooltipText: "Top 5 resolution settings of the devices used your users' sessions, in the selected time period." + tooltipText: "The top 5 resolution settings of the devices used in your users' sessions within the selected time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/technology/platforms.js b/ui-tests/cypress/lib/dashboard/analytics/technology/platforms.js index 770aae7fd2b..4524a392a0f 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/technology/platforms.js +++ b/ui-tests/cypress/lib/dashboard/analytics/technology/platforms.js @@ -10,7 +10,7 @@ const verifyStaticElementsOfPage = () => { labelElement: platformsPageElements.PAGE_TITLE, labelText: "Platforms", tooltipElement: platformsPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Details of the platforms on which yours users access your application, in the selected time period." + tooltipText: "Details of the platforms on which your users access your application within the selected time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/technology/resolutions.js b/ui-tests/cypress/lib/dashboard/analytics/technology/resolutions.js index 242f8bc4cbe..e1d19a95e53 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/technology/resolutions.js +++ b/ui-tests/cypress/lib/dashboard/analytics/technology/resolutions.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: resolutionsPageElements.PAGE_TITLE, labelText: "Resolutions", tooltipElement: resolutionsPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Detailed information on the resolution settings of the devices through which your users access your application, in the selected time period." + tooltipText: "Detailed information on the resolution settings of the devices through which your users access your application within the selected time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/technology/versions.js b/ui-tests/cypress/lib/dashboard/analytics/technology/versions.js index b6843b90f06..1fc391b471f 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/technology/versions.js +++ b/ui-tests/cypress/lib/dashboard/analytics/technology/versions.js @@ -9,7 +9,7 @@ const verifyStaticElementsOfPage = () => { labelElement: versionsPageElements.PAGE_TITLE, labelText: "App Versions", tooltipElement: versionsPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Detailed information on the application versions of your application accessed by your users, in the selected time period." + tooltipText: "Detailed information on the application versions of your application accessed by your users within the selected time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/analytics/users/overview.js b/ui-tests/cypress/lib/dashboard/analytics/users/overview.js index dbb842fc861..c424979176a 100644 --- a/ui-tests/cypress/lib/dashboard/analytics/users/overview.js +++ b/ui-tests/cypress/lib/dashboard/analytics/users/overview.js @@ -143,7 +143,7 @@ const verifyUsersOverviewChart = ({ labelElement: usersOverviewEChartElements.CHART_TOTAL_USERS_LABEL, labelText: "Total Users", tooltipElement: usersOverviewEChartElements.CHART_TOTAL_USERS_TOOLTIP, - tooltipText: "The number of users (unique devices/IDs) who have opened your application in the selected time period.", + tooltipText: "The number of users (unique devices/IDs) who have opened your application within the selected time period.", }); cy.verifyElement({ @@ -167,7 +167,7 @@ const verifyUsersOverviewChart = ({ labelElement: usersOverviewEChartElements.CHART_NEW_USERS_LABEL, labelText: "New Users", tooltipElement: usersOverviewEChartElements.CHART_NEW_USERS_TOOLTIP, - tooltipText: "The number of first-time users (unique devices/IDs) in the selected time period.", + tooltipText: "The number of first-time users (unique devices/IDs) within the selected time period.", }); cy.verifyElement({ @@ -191,7 +191,7 @@ const verifyUsersOverviewChart = ({ labelElement: usersOverviewEChartElements.CHART_RETURNING_USERS_LABEL, labelText: "Returning Users", tooltipElement: usersOverviewEChartElements.CHART_RETURNING_USERS_TOOLTIP, - tooltipText: "Number of users using your application for the second or later time, in the selected time period, calculated as Total Users (less) New Users.", + tooltipText: "The number of users using your application for the second or later time within the selected time period, calculated as Total Users minus New Users.", }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/crashes/crashes.js b/ui-tests/cypress/lib/dashboard/crashes/crashes.js index 455c1d009e8..4c925411fe5 100644 --- a/ui-tests/cypress/lib/dashboard/crashes/crashes.js +++ b/ui-tests/cypress/lib/dashboard/crashes/crashes.js @@ -33,7 +33,7 @@ const verifyStaticElementsOfCrashGroupsPage = () => { labelElement: crashGroupsPageElements.ENABLED_LABEL, labelText: "Enabled", tooltipElement: crashGroupsPageElements.AUTO_REFRESH_IS_ENABLED_TOOLTIP, - tooltipText: "Automatically refresh can be adjusted through this switch" + tooltipText: "Automatic refresh can be adjusted through this switch." }); cy.verifyElement({ @@ -222,7 +222,7 @@ const verifyStaticElementsOfCrashStatisticsPage = () => { labelElement: crashStatisticsEChartElements.TOTAL_OCCURENCES_LABEL, labelText: "Total Occurences", tooltipElement: crashStatisticsEChartElements.TOTAL_OCCURENCES_TOOLTIP, - tooltipText: "Timeline of all occurrences of all crashes. Same crash may occurred multiple times for same or different users." + tooltipText: "Timeline of all occurrences of all crashes. The same crash may have occurred multiple times for the same or different users." }); cy.verifyElement({ @@ -233,7 +233,7 @@ const verifyStaticElementsOfCrashStatisticsPage = () => { labelElement: crashStatisticsEChartElements.UNIQUE_CRASHES_LABEL, labelText: "Unique Crashes", tooltipElement: crashStatisticsEChartElements.UNIQUE_CRASHES_TOOLTIP, - tooltipText: "Timeline of crash types. Only the first ocurrence of each crash time recorded here." + tooltipText: "Timeline of crash types. Only the first occurrence of each crash time is recorded here." }); cy.verifyElement({ @@ -255,7 +255,7 @@ const verifyStaticElementsOfCrashStatisticsPage = () => { labelElement: crashStatisticsEChartElements.CRASH_FREE_USERS_LABEL, labelText: "Crash-free Users", tooltipElement: crashStatisticsEChartElements.CRASH_FREE_USERS_TOOLTIP, - tooltipText: "Number of users who have not experienced a crash for the applied filter in the selected time period, expressed as a percentage of the total number of users within that time period." + tooltipText: "The number of users who have not experienced a crash for the applied filter in the selected time period, expressed as a percentage of the total number of users within that time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/feedback/ratings/widgets.js b/ui-tests/cypress/lib/dashboard/feedback/ratings/widgets.js old mode 100644 new mode 100755 index 6a50c3c2abc..78ac728313f --- a/ui-tests/cypress/lib/dashboard/feedback/ratings/widgets.js +++ b/ui-tests/cypress/lib/dashboard/feedback/ratings/widgets.js @@ -80,11 +80,11 @@ const verifySettingsPageElements = ({ labelText: "Internal Name", element: feedbackRatingWidgetsPageElements.WIDGET_NAME_INPUT, value: widgetName, - elementPlaceHolder: "Widget Name" + elementPlaceHolder: "Enter an Internal Name" }); cy.verifyElement({ labelElement: feedbackRatingWidgetsPageElements.WIDGET_NAME_DESC, - labelText: "Name survey for internal purposes. It is not going to be shown on survey.", + labelText: "This name is internal and will not be shown to your end user.", }); cy.verifyElement({ labelElement: feedbackRatingWidgetsPageElements.QUESTION_LABEL, diff --git a/ui-tests/cypress/lib/dashboard/home/home.js b/ui-tests/cypress/lib/dashboard/home/home.js index 3f0f4275384..c77f4e8dff0 100644 --- a/ui-tests/cypress/lib/dashboard/home/home.js +++ b/ui-tests/cypress/lib/dashboard/home/home.js @@ -63,7 +63,7 @@ const verifyStaticElementsOfPage = () => { labelElement: homePageElements.AUDIENCE.NEW_SESSIONS_LABEL, labelText: "New Sessions", tooltipElement: homePageElements.AUDIENCE.NEW_SESSIONS_TOOLTIP, - tooltipText: "The number of first-time users (unique devices/IDs) in the selected time period." + tooltipText: "The number of first-time users (unique devices/IDs) within the selected time period." }); cy.verifyElement({ @@ -84,7 +84,7 @@ const verifyStaticElementsOfPage = () => { labelElement: homePageElements.AUDIENCE.AVG_REQUESTS_RECEIVED_LABEL, labelText: "Avg. Requests Received", tooltipElement: homePageElements.AUDIENCE.AVG_REQUESTS_RECEIVED_TOOLTIP, - tooltipText: "Number of write API requests Countly Server receives for each session (includes sessions, session extensions, events, etc)" + tooltipText: "The number of write API requests the Countly Server receives for each session (includes sessions, session extensions, events, etc.)." }); cy.verifyElement({ @@ -159,7 +159,7 @@ const verifyStaticElementsOfPage = () => { labelElement: homePageElements.TECHNOLOGY().LABEL, labelText: "Technology", tooltipElement: homePageElements.TECHNOLOGY().TOOLTIP, - tooltipText: "Overview details of your app or website traffic by your users’ technology, such as platform, device, resolution, browsers and app version." + tooltipText: "Overview details of your app or website traffic based on your users’ technology, such as platform, device, resolution, browsers, and app version." }); cy.verifyElement({ @@ -176,35 +176,35 @@ const verifyStaticElementsOfPage = () => { labelElement: homePageElements.TECHNOLOGY().TOP_PLATFORMS_LABEL, labelText: "Top Platforms", tooltipElement: homePageElements.TECHNOLOGY().TOP_PLATFORMS_TOOLTIP, - tooltipText: "Top 5 versions of the platforms of your users’ sessions, in the selected time period." + tooltipText: "The top 5 platform versions of your users’ sessions within the selected time period." }); cy.verifyElement({ labelElement: homePageElements.TECHNOLOGY().TOP_DEVICES_LABEL, labelText: "Top Devices", tooltipElement: homePageElements.TECHNOLOGY().TOP_DEVICES_TOOLTIP, - tooltipText: "Top 5 devices of your users’ based on their sessions, in the selected time period." + tooltipText: "The top 5 devices of your users based on their sessions within the selected time period." }); cy.verifyElement({ labelElement: homePageElements.TECHNOLOGY().TOP_APP_VERSIONS_LABEL, labelText: "Top App Versions", tooltipElement: homePageElements.TECHNOLOGY().TOP_APP_VERSIONS_TOOLTIP, - tooltipText: "Top 5 App versions of your users’ based on their sessions, in the selected time period." + tooltipText: "The top 5 app versions of your users based on their sessions within the selected time period." }); cy.verifyElement({ labelElement: homePageElements.TECHNOLOGY().TOP_DEVICE_TYPES_LABEL, labelText: "Top Device types", tooltipElement: homePageElements.TECHNOLOGY().TOP_DEVICE_TYPES_TOOLTIP, - tooltipText: "Top 5 device types of your users’ based on their sessions, in the selected time period." + tooltipText: "The top 5 device types of your users based on their sessions within the selected time period." }); cy.verifyElement({ labelElement: homePageElements.COUNTRIES.LABEL, labelText: "Countries", tooltipElement: homePageElements.COUNTRIES.TOOLTIP, - tooltipText: "An overview of the geographical distribution of your users and their sessions in the selected time period." + tooltipText: "An overview of the geographical distribution of your users and their sessions within the selected time period." }); cy.verifyElement({ @@ -270,7 +270,7 @@ const verifyStaticElementsOfPage = () => { labelElement: homePageElements.CRASH_STATISTICS.LABEL, labelText: "Crash Statistics", tooltipElement: homePageElements.CRASH_STATISTICS.TOOLTIP, - tooltipText: "See actionable information about crashes and exceptions including which users are impacted" + tooltipText: "See actionable information about crashes and exceptions, including which users are impacted." }); cy.verifyElement({ @@ -313,7 +313,7 @@ const verifyStaticElementsOfPage = () => { labelElement: homePageElements.CRASH_STATISTICS.CRASH_FREE_USERS_LABEL, labelText: "Crash-free Users", tooltipElement: homePageElements.CRASH_STATISTICS.CRASH_FREE_USERS_TOOLTIP, - tooltipText: "Number of users who have not experienced a crash for the applied filter in the selected time period, expressed as a percentage of the total number of users within that time period." + tooltipText: "The number of users who have not experienced a crash for the applied filter in the selected time period, expressed as a percentage of the total number of users within that time period." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/manage/alerts/alerts.js b/ui-tests/cypress/lib/dashboard/manage/alerts/alerts.js index 60034e4f5c5..fbe1d7e6692 100644 --- a/ui-tests/cypress/lib/dashboard/manage/alerts/alerts.js +++ b/ui-tests/cypress/lib/dashboard/manage/alerts/alerts.js @@ -79,7 +79,7 @@ const verifyAlertDrawerPageElements = ({ if (!isEditPage) { cy.verifyElement({ labelElement: alertDrawerPageElements.DRAWER_PAGE_TITLE, - labelText: "Create new alert" + labelText: "Create New Alert" }); } else { @@ -99,7 +99,7 @@ const verifyAlertDrawerPageElements = ({ labelText: "Alert Name", element: alertDrawerPageElements.DRAWER_ALERT_NAME_INPUT, value: alertName, - elementPlaceHolder: "Enter alert name" + elementPlaceHolder: "Enter Alert Name" }); cy.verifyElement({ @@ -107,7 +107,7 @@ const verifyAlertDrawerPageElements = ({ labelText: "Application", element: alertDrawerPageElements.DRAWER_APPLICATION_SELECT, value: application, - elementPlaceHolder: "Select an application" + elementPlaceHolder: "Select an Application" }); cy.verifyElement({ @@ -537,7 +537,7 @@ const verifyAlertsDataFromTable = ({ cy.verifyElement({ labelElement: alertDataTableElements().COLUMN_NAME_CREATED_BY_LABEL, isElementVisible: false, - labelText: "Created by", + labelText: "Created By", }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/manage/apps/apps.js b/ui-tests/cypress/lib/dashboard/manage/apps/apps.js index 4012350993e..baa26b761d8 100644 --- a/ui-tests/cypress/lib/dashboard/manage/apps/apps.js +++ b/ui-tests/cypress/lib/dashboard/manage/apps/apps.js @@ -58,7 +58,7 @@ const verifyStaticElementsOfPage = () => { labelElement: applicationsPageElements.SALT_FOR_CHECKSUM_LABEL, labelText: "Salt for checksum", element: applicationsPageElements.SALT_FOR_CHECKSUM_DESCRIPTION_LABEL, - elementText: "Will only accept requests where checksum is signed with the same salt in SDK", + elementText: "Will only accept requests where the checksum is signed with the same salt in the SDK.", }); cy.verifyElement({ @@ -72,7 +72,7 @@ const verifyStaticElementsOfPage = () => { labelElement: applicationsPageElements.APP_KEY_LABEL, labelText: "App Key", element: applicationsPageElements.APP_KEY_DESCRIPTION_LABEL, - elementText: "You'll need this key for SDK integration", + elementText: "You will need this key for SDK integration.", }); cy.verifyElement({ @@ -84,7 +84,7 @@ const verifyStaticElementsOfPage = () => { cy.verifyElement({ labelElement: applicationsPageElements.ADD_UPLOAD_INSRUCTIONS_LABEL, - labelText: "Only jpg, png and gif image formats are allowed", + labelText: "Only JPG, PNG, and GIF image formats are allowed.", }); }; diff --git a/ui-tests/cypress/lib/dashboard/manage/configurations/configurations.js b/ui-tests/cypress/lib/dashboard/manage/configurations/configurations.js index a73db448a55..558de3b930d 100644 --- a/ui-tests/cypress/lib/dashboard/manage/configurations/configurations.js +++ b/ui-tests/cypress/lib/dashboard/manage/configurations/configurations.js @@ -1155,7 +1155,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.DASHBOARD.ALLOW_DASHBOARD_SHARING }).SELECTED_SUBFEATURE_DESCRIPTION, - labelText: "Enable dashboard sharing for users to share a dashboard with other users. If set to off, a dashboard cannot be shared with others.", + labelText: "Enable dashboard sharing for users to share a dashboard with other users. If set to off, dashboards cannot be shared with others.", }); cy.verifyElement({ @@ -1179,7 +1179,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.HOOKS.ACTION_BATCH_PROCESING_SIZE }).SELECTED_SUBFEATURE_TITLE, - labelText: "Action batch procesing size", + labelText: "Action Batch Processing Size", }); cy.verifyElement({ @@ -1195,7 +1195,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.HOOKS.ACTION_PIPELINE_INTERVAL }).SELECTED_SUBFEATURE_TITLE, - labelText: "Action pipeline interval", + labelText: "Action Pipeline Interval", }); cy.verifyElement({ @@ -1211,7 +1211,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.HOOKS.REFRESH_RULES_PERIOD }).SELECTED_SUBFEATURE_TITLE, - labelText: "Refresh rules period", + labelText: "Refresh Rules Period", }); cy.verifyElement({ @@ -1227,7 +1227,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.HOOKS.REQUEST_LIMIT }).SELECTED_SUBFEATURE_TITLE, - labelText: "Request limit", + labelText: "Request Limit", }); cy.verifyElement({ @@ -1243,7 +1243,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.HOOKS.TIME_WINDOW_FOR_REQUEST_LIMIT }).SELECTED_SUBFEATURE_TITLE, - labelText: "Time window for request limit", + labelText: "Time Window for Request Limit", }); cy.verifyElement({ @@ -1294,7 +1294,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.INCOMING_DATA_LOGS.DATA_LOGGING_STATE }).SELECTED_SUBFEATURE_DESCRIPTION, - labelText: "If incoming data logging state is set to \"On\", only the last 1000 requests will be saved. When the state is set to \"Automatic\", requests will continue to be logged until the limit per minute is reached.", + labelText: "If the incoming data logging state is set to \"On\", only the last 1000 requests will be saved. When the state is set to \"Automatic\", requests will continue to be logged until the limit per minute is reached.", }); cy.verifyElement({ @@ -1701,7 +1701,7 @@ const verifyPageElements = () => { cy.verifyElement({ labelElement: configurationsListBoxElements({ subFeature: SETTINGS.AUDIT_LOGS.DISABLE_IP_TRACKING }).SELECTED_SUBFEATURE_DESCRIPTION, - labelText: "Do not record IP address of actions taken by the users", + labelText: "Do not record the IP address of actions taken by the users.", }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/dashboard/manage/hooks/hooks.js b/ui-tests/cypress/lib/dashboard/manage/hooks/hooks.js index c57386319e9..8f6f64d968d 100644 --- a/ui-tests/cypress/lib/dashboard/manage/hooks/hooks.js +++ b/ui-tests/cypress/lib/dashboard/manage/hooks/hooks.js @@ -73,7 +73,7 @@ const verifyStaticElementsOfPage = () => { cy.verifyElement({ labelElement: hooksDataTableElements().COLUMN_NAME_CREATE_BY_LABEL, - labelText: "Create by", + labelText: "Created by", element: hooksDataTableElements().COLUMN_NAME_CREATE_BY_SORTABLE_ICON, }); }; diff --git a/ui-tests/cypress/lib/dashboard/manage/logger/logger.js b/ui-tests/cypress/lib/dashboard/manage/logger/logger.js index 110f93f93a1..7f667bbac68 100644 --- a/ui-tests/cypress/lib/dashboard/manage/logger/logger.js +++ b/ui-tests/cypress/lib/dashboard/manage/logger/logger.js @@ -8,12 +8,12 @@ const verifyStaticElementsOfPage = (isEnabled) => { labelElement: loggerPageElements.PAGE_TITLE, labelText: "Incoming Data Logs", tooltipElement: loggerPageElements.PAGE_TITLE_TOOLTIP, - tooltipText: "Log requests made to the write API to review and debug incoming data" + tooltipText: "Logs requests made to the write API to review and debug incoming data." }); cy.verifyElement({ labelElement: loggerPageElements.PAGE_SUB_TITLE, - labelText: "Only up to last 1000 incoming data logs are stored" + labelText: "Only up to the last 1000 incoming data logs are stored" }); if (isEnabled) { @@ -23,7 +23,7 @@ const verifyStaticElementsOfPage = (isEnabled) => { element: loggerPageElements.ENABLED_LABEL, elementText: "Enabled", tooltipElement: loggerPageElements.AUTO_REFRESH_IS_ENABLED_TOOLTIP, - tooltipText: "Automatically refresh can be adjusted through this switch", + tooltipText: "Automatic refresh can be adjusted through this switch.", }); cy.verifyElement({ @@ -37,7 +37,7 @@ const verifyStaticElementsOfPage = (isEnabled) => { labelElement: loggerPageElements.ENABLE_AUTO_REFRESH_LABEL, labelText: "Enable Auto-refresh", tooltipElement: loggerPageElements.ENABLE_AUTO_REFRESH_TOOLTIP, - tooltipText: "Automatically refresh can be adjusted through this switch" + tooltipText: "Automatic refresh can be adjusted through this switch." }); } diff --git a/ui-tests/cypress/lib/dashboard/manage/logs/systemlogs.js b/ui-tests/cypress/lib/dashboard/manage/logs/systemlogs.js index a6b4fae86d6..be9f39de4bf 100644 --- a/ui-tests/cypress/lib/dashboard/manage/logs/systemlogs.js +++ b/ui-tests/cypress/lib/dashboard/manage/logs/systemlogs.js @@ -109,7 +109,7 @@ const verifySystemLogsDataTable = ({ cy.verifyElement({ element: systemLogsDataTableElements(index).EXPAND_ROW, - elementText: "Following data was changed", + elementText: "The following data was changed", }); }; diff --git a/ui-tests/cypress/lib/dashboard/messaging/messaging.js b/ui-tests/cypress/lib/dashboard/messaging/messaging.js index cf07a486bad..ff63e2497b6 100644 --- a/ui-tests/cypress/lib/dashboard/messaging/messaging.js +++ b/ui-tests/cypress/lib/dashboard/messaging/messaging.js @@ -49,7 +49,7 @@ const verifyStaticElementsOfPage = () => { labelElement: messagingMetricCardElements.ENABLED_USERS_PERCENTAGE_LABEL, labelText: "Enabled Users Percentage", tooltipElement: messagingMetricCardElements.ENABLED_USERS_PERCENTAGE_PROGRESS_TOOLTIP, - tooltipText: "Number of users who have agreed to receive notifications, expressed as a percentage over the total number of app users." + tooltipText: "The number of users who have agreed to receive notifications, expressed as a percentage of the total number of app users." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/onboarding/initialSetup.js b/ui-tests/cypress/lib/onboarding/initialSetup.js index 60108163002..9a45579b27f 100644 --- a/ui-tests/cypress/lib/onboarding/initialSetup.js +++ b/ui-tests/cypress/lib/onboarding/initialSetup.js @@ -113,7 +113,7 @@ const verifyDefaultPageElements = (isDemoApp) => { cy.verifyElement({ labelElement: initialSetupPageElements.PAGE_SUB_TITLE, - labelText: "After adding your first application, you'll be ready to start collecting data" + labelText: "After adding your first application, you will be ready to start collecting data." }); cy.verifyElement({ @@ -129,7 +129,7 @@ const verifyDefaultPageElements = (isDemoApp) => { element: initialSetupPageElements.APPLICATION_KEY_INPUT, elementPlaceHolder: "App Key", tooltipElement: initialSetupPageElements.APPLICATION_KEY_TOOLTIP, - tooltipText: "You'll need this key for SDK integration" + tooltipText: "You will need this key for SDK integration." }); cy.verifyElement({ diff --git a/ui-tests/cypress/lib/onboarding/setup.js b/ui-tests/cypress/lib/onboarding/setup.js index 0518ed8fd9e..c9d3e459278 100644 --- a/ui-tests/cypress/lib/onboarding/setup.js +++ b/ui-tests/cypress/lib/onboarding/setup.js @@ -74,7 +74,7 @@ const verifyConfirmPasswordHintSymbolMessage = () => { cy.verifyElement({ element: setupPageElements.CONFIRM_PASSWORD_ERROR_DOT, labelElement: setupPageElements.CONFIRM_PASSWORD_ERROR, - labelText: "Confirmation password has to be the same as password.", + labelText: "The confirmation password has to be the same as the password.", }); }; @@ -135,7 +135,7 @@ const verifyDefaultPageElements = () => { cy.verifyElement({ labelElement: setupPageElements.EMAIL_ADDRESS_ERROR, - labelText: "Please enter a valid email adress.", + labelText: "Please enter a valid email address.", }); cy.verifyElement({ @@ -168,7 +168,7 @@ const verifyDefaultPageElements = () => { cy.verifyElement({ element: setupPageElements.CONFIRM_PASSWORD_ERROR_DOT, labelElement: setupPageElements.CONFIRM_PASSWORD_ERROR, - labelText: "Confirmation password has to be the same as password.", + labelText: "The confirmation password has to be the same as the password.", }); }; diff --git a/ui-tests/cypress/support/elements/dashboard/manage/hooks/hooks.js b/ui-tests/cypress/support/elements/dashboard/manage/hooks/hooks.js index b743956e0f1..7f3ee3482b1 100644 --- a/ui-tests/cypress/support/elements/dashboard/manage/hooks/hooks.js +++ b/ui-tests/cypress/support/elements/dashboard/manage/hooks/hooks.js @@ -26,8 +26,8 @@ const hooksDataTableElements = (index = 0) => ({ COLUMN_NAME_TRIGGER_COUNT_SORTABLE_ICON: 'datatable-hooks-sortable-icon-trigger-count', COLUMN_NAME_LAST_TRIGGERED_LABEL: 'datatable-hooks-label-last-triggered', COLUMN_NAME_LAST_TRIGGERED_SORTABLE_ICON: 'datatable-hooks-sortable-icon-last-triggered', - COLUMN_NAME_CREATE_BY_LABEL: 'datatable-hooks-label-create-by', - COLUMN_NAME_CREATE_BY_SORTABLE_ICON: 'datatable-hooks-sortable-icon-create-by', + COLUMN_NAME_CREATE_BY_LABEL: 'datatable-hooks-label-created-by', + COLUMN_NAME_CREATE_BY_SORTABLE_ICON: 'datatable-hooks-sortable-icon-created-by', //Columns' Rows' Datas Elements STATUS: 'datatable-hooks-status-' + index + '-el-switch-wrapper', diff --git a/ui-tests/package-lock.json b/ui-tests/package-lock.json index db7923a9b97..e9e2bc5c0e3 100644 --- a/ui-tests/package-lock.json +++ b/ui-tests/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@faker-js/faker": "^8.2.0", + "@faker-js/faker": "^9.7.0", "base-64": "^1.0.0", "chai": "^5.1.1", "cypress-file-upload": "^5.0.8", @@ -75,18 +75,19 @@ } }, "node_modules/@faker-js/faker": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.2.0.tgz", - "integrity": "sha512-VacmzZqVxdWdf9y64lDOMZNDMM/FQdtM9IsaOPKOm2suYwEatb8VkdHqOzXcDnZbk7YDE2BmsJmy/2Hmkn563g==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.7.0.tgz", + "integrity": "sha512-aozo5vqjCmDoXLNUJarFZx2IN/GgGaogY4TMJ6so/WLZOWpSV7fvj2dmrV6sEAnUm1O7aCrhTibjpzeDFgNqbg==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/fakerjs" } ], + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0", - "npm": ">=6.14.13" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "node_modules/@types/node": { @@ -368,9 +369,10 @@ "license": "Apache-2.0" }, "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "license": "MIT", "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", @@ -1389,9 +1391,10 @@ } }, "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", "engines": { "node": "*" } diff --git a/ui-tests/package.json b/ui-tests/package.json index 68e9f9764b7..5084cea17d6 100644 --- a/ui-tests/package.json +++ b/ui-tests/package.json @@ -9,7 +9,7 @@ }, "license": "ISC", "dependencies": { - "@faker-js/faker": "^8.2.0", + "@faker-js/faker": "^9.7.0", "base-64": "^1.0.0", "chai": "^5.1.1", "cypress-file-upload": "^5.0.8",