Repository: needim/noty Branch: master Commit: 82f11352c38d Files: 147 Total size: 1.4 MB Directory structure: gitextract_8xne0dab/ ├── .babelrc ├── .codeclimate.yml ├── .editorconfig ├── .github/ │ ├── FUNDING.yml │ └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── LICENSE.txt ├── README.markdown ├── bower.json ├── browserstack-builds.json ├── browserstack-session.json ├── browserstack.json ├── composer.json ├── demo/ │ ├── animate.css │ ├── bouncejs/ │ │ └── bounce.js │ ├── demo.css │ ├── demo.js │ ├── font-awesome/ │ │ └── fonts/ │ │ └── FontAwesome.otf │ ├── fonts/ │ │ └── stylesheet.css │ ├── index.html │ ├── push.html │ └── sendpush.js ├── docs/ │ ├── .nojekyll │ ├── README.md │ ├── _assets/ │ │ ├── docs.js │ │ ├── docsify.js │ │ └── vue.css │ ├── _navbar.md │ ├── _sidebar.md │ ├── animations.md │ ├── api.md │ ├── bakers.md │ ├── browsers.md │ ├── confirm.md │ ├── index.html │ ├── installation.md │ ├── options.md │ ├── push.md │ ├── themes.md │ ├── types.md │ └── v2/ │ ├── animations.html │ ├── api.html │ ├── confirmations.html │ ├── index.html │ ├── layouts.html │ ├── options.html │ ├── releases.html │ ├── themes.html │ └── vendor/ │ ├── animate.css │ ├── custom.css │ ├── documentation.js │ ├── fastclick.js │ ├── google-code-prettify/ │ │ ├── prettify.css │ │ └── prettify.js │ ├── main.js │ ├── noty-2.4.1/ │ │ ├── .gitignore │ │ ├── Gruntfile.js │ │ ├── LICENSE.txt │ │ ├── README.markdown │ │ ├── bower.json │ │ ├── composer.json │ │ ├── demo/ │ │ │ ├── allLayouts.html │ │ │ ├── allTypes.html │ │ │ ├── animate.css │ │ │ ├── api.html │ │ │ ├── buttons.css │ │ │ ├── consumingAlert.html │ │ │ ├── customContainer.html │ │ │ ├── font-awesome/ │ │ │ │ └── fonts/ │ │ │ │ └── FontAwesome.otf │ │ │ ├── index.html │ │ │ ├── issue302.html │ │ │ ├── jquery-1.8.0.js │ │ │ ├── killer.html │ │ │ ├── noanim.html │ │ │ ├── notification_html.js │ │ │ ├── progressbar.html │ │ │ ├── themeBootstrap.html │ │ │ ├── themeCss.html │ │ │ ├── usingMaxVisible.html │ │ │ ├── usingWithAnimate.css.html │ │ │ ├── usingWithButtons.html │ │ │ ├── usingWithButtons2.html │ │ │ ├── usingWithModal.html │ │ │ └── usingWithOldOptions.html │ │ ├── js/ │ │ │ └── noty/ │ │ │ ├── jquery.noty.js │ │ │ ├── layouts/ │ │ │ │ ├── bottom.js │ │ │ │ ├── bottomCenter.js │ │ │ │ ├── bottomLeft.js │ │ │ │ ├── bottomRight.js │ │ │ │ ├── center.js │ │ │ │ ├── centerLeft.js │ │ │ │ ├── centerRight.js │ │ │ │ ├── inline.js │ │ │ │ ├── top.js │ │ │ │ ├── topCenter.js │ │ │ │ ├── topLeft.js │ │ │ │ └── topRight.js │ │ │ ├── packaged/ │ │ │ │ └── jquery.noty.packaged.js │ │ │ ├── promise.js │ │ │ └── themes/ │ │ │ ├── bootstrap.js │ │ │ ├── default.js │ │ │ ├── metroui.js │ │ │ ├── relax.js │ │ │ └── semanticUI.js │ │ ├── noty.jquery.json │ │ └── package.json │ ├── ps-icon-pack.css │ └── showdown/ │ └── showdown.js ├── index.d.ts ├── lib/ │ ├── noty.css │ ├── noty.js │ └── themes/ │ ├── bootstrap-v3.css │ ├── bootstrap-v4.css │ ├── light.css │ ├── metroui.css │ ├── mint.css │ ├── nest.css │ ├── relax.css │ ├── semanticui.css │ └── sunset.css ├── manifest.json.template ├── package.json ├── postcss.config.js ├── service-worker.js.template ├── src/ │ ├── api.js │ ├── button.js │ ├── index.js │ ├── noty.scss │ ├── push.js │ ├── themes/ │ │ ├── bootstrap-v3.scss │ │ ├── bootstrap-v4.scss │ │ ├── light.scss │ │ ├── metroui.scss │ │ ├── mint.scss │ │ ├── nest.scss │ │ ├── relax.scss │ │ ├── semanticui.scss │ │ └── sunset.scss │ └── utils.js ├── test/ │ ├── index.html │ ├── unit/ │ │ ├── init.test.js │ │ └── phantom.js │ └── vendor/ │ ├── qunit-theme-ninja.css │ └── qunit.js └── webpack.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": ["es2015"], "plugins": ["babel-plugin-add-module-exports"] } ================================================ FILE: .codeclimate.yml ================================================ engines: eslint: enabled: true fixme: enabled: true ratings: paths: - "src/**/*.js" exclude_paths: - test/**/* - demo/**/* - node_modules/**/* ================================================ FILE: .editorconfig ================================================ # editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false ================================================ FILE: .github/FUNDING.yml ================================================ github: [needim] patreon: needim ko_fi: needim ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ > **_Noty version_**: ..... > **_Browser_**: ..... > **_OS_**: ..... > **_jsFiddle link (if available)_**: ..... ---------- ================================================ FILE: .gitignore ================================================ child/ .DS_Store .idea/ node_modules/ _SpecRunner.html /.vscode/ yarn.lock .nyc_output coverage manifest.json service-worker.js ================================================ FILE: .travis.yml ================================================ language: node_js node_js: - "7" branches: only: - master ================================================ FILE: Gruntfile.js ================================================ module.exports = function (grunt) { 'use strict' grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), usebanner: { taskName: { options: { position: 'top', banner: '/* \n @package NOTY - Dependency-free notification library \n' + ' @version version: <%= pkg.version %> \n' + ' @contributors https://github.com/needim/noty/graphs/contributors \n' + ' @documentation Examples and Documentation - https://ned.im/noty \n' + ' @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php \n*/\n', linebreak: true }, files: { src: ['lib/noty.js', 'lib/noty.min.js'] } } }, qunit: { options: { inject: 'test/unit/phantom.js' }, files: 'test/index.html' }, connect: { server: { options: { port: 3000, base: '.' } } }, sass: { dist: { options: { style: 'expanded', sourcemap: 'file' }, files: [{ expand: true, cwd: 'src/themes', src: ['*.scss'], dest: 'lib/themes', ext: '.css' }] } }, curl: { builds: { src: { url: 'https://www.browserstack.com/automate/builds.json', auth: { user: process.env.BROWSERSTACK_USERNAME, pass: process.env.BROWSERSTACK_KEY } }, dest: 'browserstack-builds.json' }, session: { src: { url: 'https://www.browserstack.com/automate/builds/' + grunt.file.readJSON('browserstack-builds.json')[0]['automation_build']['hashed_id'] + '/sessions.json', auth: { user: process.env.BROWSERSTACK_USERNAME, pass: process.env.BROWSERSTACK_KEY } }, dest: 'browserstack-session.json' } } }) require('load-grunt-tasks')(grunt) grunt.registerTask('bs-create-md', function () { const session = grunt.file.readJSON('browserstack-session.json') const file = 'docs/browsers.md' let contents = '!> This data is provided by BrowserStack Automate \n\n\n' contents += `#### ${session[0].automation_session.build_name} \n\n` contents += '| OS | Browser | Result | Details | \n' contents += '| --- | --- | --- | --- | \n' session.forEach(function (s) { grunt.log.writeln(s.automation_session.hashed_id) contents += `| ${s.automation_session.os} ${s.automation_session.os_version} | ${s.automation_session.browser} ${s.automation_session.browser_version} | ${s.automation_session.status} | [view](${s.automation_session.public_url}) |` contents += '\n' }) grunt.file.write(file, contents) }) grunt.registerTask('browserstack-md', ['curl:builds', 'curl:session', 'bs-create-md']) grunt.registerTask('banner', 'usebanner') grunt.registerTask('test', 'qunit') grunt.registerTask('saucelabs', ['qunit', 'connect', 'saucelabs-qunit']) grunt.registerTask('default', ['test']) grunt.registerTask('themes', ['sass']) } ================================================ FILE: LICENSE.txt ================================================ Copyright (c) 2012 Nedim Arabacı 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. ================================================ FILE: README.markdown ================================================ # DEPRECATED

This repository is no longer supported, please consider using alternatives.

[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)

Dependency-free notification library.
Documentation »

GitHub release Bower version NPM version Packagist version CDNJS version
Dependencies Dev Dependencies
Travis NPM Downloads Contributors


## Hi **NOTY** is a notification library that makes it easy to create **alert** - **success** - **error** - **warning** - **information** - **confirmation** messages as an alternative the standard alert dialog. The notifications can be positioned at the; **top** - **topLeft** - **topCenter** - **topRight** - **center** - **centerLeft** - **centerRight** - **bottom** - **bottomLeft** - **bottomCenter** - **bottomRight** There are lots of other options in the API to customise the text, animation, buttons and much more. It also has various callbacks for the buttons, opening closing the notifications and queue control. --- ### Features - [x] Dependency-free - [x] Web Push Notifications with Service Worker support - [x] UMD - [x] Named queue system - [x] Has 11 layouts, 5 notification styles, 5+ themes - [x] Custom container (inline notifications) - [x] Confirm notifications - [x] TTL - [x] Progress bar indicator for timed notifications - [x] Supports css animations, [animate.css](https://github.com/daneden/animate.css), [mojs](https://github.com/legomushroom/mojs), [bounce.js](https://github.com/tictail/bounce.js), [velocity](https://github.com/julianshapiro/velocity) and other animation libraries - [x] 2 close options: click, button - [x] API & Callbacks - [x] Custom templating - [x] Document visibility control (blur, focus) ### Documentation Documentation and examples are here: --- ##### Basic Usage ```js import Noty from "noty"; new Noty({ text: "Notification text" }).show(); // or const Noty = require("noty"); new Noty({ text: "Notification text" }).show(); ``` ##### Development ```console $ npm run dev $ npm test $ npm run build $ npm run browserstack $ npm run serve-docs ``` ##### Development environment - [x] Standard - [x] Prettier - [x] ES6 & Babel & Webpack - [x] Sass - [x] Autoprefixer - [x] QUnit - [x] BrowserStack - [x] Pre-commit tests - [x] Travis CI [![JavaScript Style Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) ================================================ FILE: bower.json ================================================ { "name": "noty", "description": "Noty - Notification library", "license": "MIT", "homepage": "http://ned.im/noty", "main": "lib/noty.js", "keywords": [ "noty", "notification", "alert", "confirmation" ], "ignore": [ "node_modules", "tests" ], "authors": [ "Nedim Arabacı " ] } ================================================ FILE: browserstack-builds.json ================================================ [{"automation_build":{"name":"Local run 2017 07 27T17:31:03.314Z","duration":null,"status":"done","hashed_id":"7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0"}},{"automation_build":{"name":"Local run 2017 07 27T16:47:55.918Z","duration":null,"status":"done","hashed_id":"31f78fc1bfbe5c32506ca9c3acd06182f45314ed"}},{"automation_build":{"name":"Local run 2017 07 27T16:41:51.361Z","duration":null,"status":"done","hashed_id":"7bba6ab979ebd503c9cdccaf58d385f2b878fbce"}},{"automation_build":{"name":"Local run 2017 07 27T16:38:09.816Z","duration":null,"status":"done","hashed_id":"3a9b655e94c3a6a9e755036df49e9896c14b6f9c"}},{"automation_build":{"name":"Local run 2017 07 27T16:37:04.214Z","duration":null,"status":"done","hashed_id":"c66c5b2a11cc1ee6644d1fa2e9f6eff7a6a0cbec"}},{"automation_build":{"name":"Local run 2017 07 27T15:24:14.586Z","duration":null,"status":"done","hashed_id":"715319d73cd4103da0a40c2a06b7a66b1bfc6d6d"}}] ================================================ FILE: browserstack-session.json ================================================ [ { "automation_session": { "name": null, "duration": 48, "os": "Windows", "os_version": "10", "browser_version": "46.0", "browser": "opera", "device": null, "status": "done", "hashed_id": "c259644238854e4628696d8cfea9482b96a78a07", "reason": null, "build_name": "Local run 2017 07 27T17:31:03.314Z", "project_name": "noty", "logs": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/c259644238854e4628696d8cfea9482b96a78a07/logs", "browser_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/c259644238854e4628696d8cfea9482b96a78a07", "public_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/c259644238854e4628696d8cfea9482b96a78a07?auth_token=f87c9cb1ab62bb7b85af973cc2a1b03bd9d35fbc6a9e38b716fe38b01c4c3480", "video_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/c259644238854e4628696d8cfea9482b96a78a07/video-c259644238854e4628696d8cfea9482b96a78a07.mp4?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=L9qIjHCc4zQU%2BuRTWn3EFgmyHhQ%3D\u0026response-content-type=video%2Fmp4", "browser_console_logs_url": "https://www.browserstack.com/s3-upload/bs-selenium-logs-euw/s3-eu-west-1/c259644238854e4628696d8cfea9482b96a78a07/c259644238854e4628696d8cfea9482b96a78a07-console-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=IkOSopxHZ4nSX6QGOtkxYa%2FSp5Y%3D\u0026response-content-type=text%2Fplain", "har_logs_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/c259644238854e4628696d8cfea9482b96a78a07/c259644238854e4628696d8cfea9482b96a78a07-har-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=AW4U9XEaaZxPLERvua8%2FLQlnvY0%3D" } }, { "automation_session": { "name": null, "duration": 54, "os": "Windows", "os_version": "10", "browser_version": "59.0", "browser": "chrome", "device": null, "status": "done", "hashed_id": "dc87007925cb5729ac8aa2a6136aab1fb6808cc1", "reason": null, "build_name": "Local run 2017 07 27T17:31:03.314Z", "project_name": "noty", "logs": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/dc87007925cb5729ac8aa2a6136aab1fb6808cc1/logs", "browser_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/dc87007925cb5729ac8aa2a6136aab1fb6808cc1", "public_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/dc87007925cb5729ac8aa2a6136aab1fb6808cc1?auth_token=04d2d0b39bcdbb76153ee28e3acf67099ecbd9a093c6176df9ad892c083663c6", "video_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/dc87007925cb5729ac8aa2a6136aab1fb6808cc1/video-dc87007925cb5729ac8aa2a6136aab1fb6808cc1.mp4?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=A6DNc457B5vqFNxOvP6B%2F0tCYZk%3D\u0026response-content-type=video%2Fmp4", "browser_console_logs_url": "https://www.browserstack.com/s3-upload/bs-selenium-logs-euw/s3-eu-west-1/dc87007925cb5729ac8aa2a6136aab1fb6808cc1/dc87007925cb5729ac8aa2a6136aab1fb6808cc1-console-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=yz1BugMpwOrl2h9i84A6BQtr7Cs%3D\u0026response-content-type=text%2Fplain", "har_logs_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/dc87007925cb5729ac8aa2a6136aab1fb6808cc1/dc87007925cb5729ac8aa2a6136aab1fb6808cc1-har-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=kaUFdYGXBcjY5ZxokYZ7cYjhGpk%3D" } }, { "automation_session": { "name": null, "duration": 45, "os": "OS X", "os_version": "El Capitan", "browser_version": "9.1", "browser": "safari", "device": null, "status": "done", "hashed_id": "0c60211cab5840456ac824443e3be99b195597b5", "reason": null, "build_name": "Local run 2017 07 27T17:31:03.314Z", "project_name": "noty", "logs": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/0c60211cab5840456ac824443e3be99b195597b5/logs", "browser_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/0c60211cab5840456ac824443e3be99b195597b5", "public_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/0c60211cab5840456ac824443e3be99b195597b5?auth_token=9daf8b81531fe858108d9d76317b171c7dca69dee3ac3a25e065810fd353b837", "video_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/0c60211cab5840456ac824443e3be99b195597b5/video-0c60211cab5840456ac824443e3be99b195597b5.mp4?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=p32SrCXGkJ15m79Gvxq86P1tzXU%3D\u0026response-content-type=video%2Fmp4", "browser_console_logs_url": "https://www.browserstack.com/s3-upload/bs-selenium-logs-euw/s3-eu-west-1/0c60211cab5840456ac824443e3be99b195597b5/0c60211cab5840456ac824443e3be99b195597b5-console-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=E6AhIFzy%2FHX5QD6%2BUd1T8WPWhXY%3D\u0026response-content-type=text%2Fplain", "har_logs_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/0c60211cab5840456ac824443e3be99b195597b5/0c60211cab5840456ac824443e3be99b195597b5-har-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=CIaBXl9nhoeip5EEktV5Rqrg7vI%3D" } }, { "automation_session": { "name": null, "duration": 50, "os": "Windows", "os_version": "10", "browser_version": "54.0", "browser": "firefox", "device": null, "status": "done", "hashed_id": "336cf3a8db5363d7683f01392d4d328fce18838a", "reason": null, "build_name": "Local run 2017 07 27T17:31:03.314Z", "project_name": "noty", "logs": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/336cf3a8db5363d7683f01392d4d328fce18838a/logs", "browser_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/336cf3a8db5363d7683f01392d4d328fce18838a", "public_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/336cf3a8db5363d7683f01392d4d328fce18838a?auth_token=e93ad65f77003c53f0e7392f2bbd38d56811d1d6ce4e1f9f098494caa240ef21", "video_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/336cf3a8db5363d7683f01392d4d328fce18838a/video-336cf3a8db5363d7683f01392d4d328fce18838a.mp4?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=rJTPrYODLubpcgwCqZsW2mXo0JY%3D\u0026response-content-type=video%2Fmp4", "browser_console_logs_url": "https://www.browserstack.com/s3-upload/bs-selenium-logs-euw/s3-eu-west-1/336cf3a8db5363d7683f01392d4d328fce18838a/336cf3a8db5363d7683f01392d4d328fce18838a-console-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=FQCd3lZU3tixlx9j0EiqqjAUnYY%3D\u0026response-content-type=text%2Fplain", "har_logs_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/336cf3a8db5363d7683f01392d4d328fce18838a/336cf3a8db5363d7683f01392d4d328fce18838a-har-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=44zYIcazKHQzvD2F%2BEmhUFjwmHg%3D" } }, { "automation_session": { "name": null, "duration": 47, "os": "Windows", "os_version": "10", "browser_version": "15.0", "browser": "edge", "device": null, "status": "done", "hashed_id": "a2bb1f252f478c5b5cd4fdc06158830305120ea2", "reason": null, "build_name": "Local run 2017 07 27T17:31:03.314Z", "project_name": "noty", "logs": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/a2bb1f252f478c5b5cd4fdc06158830305120ea2/logs", "browser_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/a2bb1f252f478c5b5cd4fdc06158830305120ea2", "public_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/a2bb1f252f478c5b5cd4fdc06158830305120ea2?auth_token=c75ad2904602c489145eaf2ce18b8f5723a843cb6c8dcc62a60982dc6109ef27", "video_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/a2bb1f252f478c5b5cd4fdc06158830305120ea2/video-a2bb1f252f478c5b5cd4fdc06158830305120ea2.mp4?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=7Jf1rpd9%2FUvHyI3wSIwdYBsD1JE%3D\u0026response-content-type=video%2Fmp4", "browser_console_logs_url": "https://www.browserstack.com/s3-upload/bs-selenium-logs-euw/s3-eu-west-1/a2bb1f252f478c5b5cd4fdc06158830305120ea2/a2bb1f252f478c5b5cd4fdc06158830305120ea2-console-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=4soYSJ2wA1By7Oohu8047VYYE30%3D\u0026response-content-type=text%2Fplain", "har_logs_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/a2bb1f252f478c5b5cd4fdc06158830305120ea2/a2bb1f252f478c5b5cd4fdc06158830305120ea2-har-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=a%2BVdRuZNZPDx%2BqOg90n3WzIP8lU%3D" } }, { "automation_session": { "name": null, "duration": 30, "os": "Windows", "os_version": "8", "browser_version": "10.0", "browser": "ie", "device": null, "status": "done", "hashed_id": "d85b895f81c51f9cd5c72c225c9f155b331902c6", "reason": null, "build_name": "Local run 2017 07 27T17:31:03.314Z", "project_name": "noty", "logs": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/d85b895f81c51f9cd5c72c225c9f155b331902c6/logs", "browser_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/d85b895f81c51f9cd5c72c225c9f155b331902c6", "public_url": "https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/d85b895f81c51f9cd5c72c225c9f155b331902c6?auth_token=bd85550ce628686d6485062a32cc869abf2dcb7a2b9862b3884ebc7d4283d344", "video_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/d85b895f81c51f9cd5c72c225c9f155b331902c6/video-d85b895f81c51f9cd5c72c225c9f155b331902c6.mp4?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=TZYrsY8GWzdcXP0IrAvQ2LisTQQ%3D\u0026response-content-type=video%2Fmp4", "browser_console_logs_url": "https://www.browserstack.com/s3-upload/bs-selenium-logs-euw/s3-eu-west-1/d85b895f81c51f9cd5c72c225c9f155b331902c6/d85b895f81c51f9cd5c72c225c9f155b331902c6-console-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=yQkCo8qp1BkJU5tXN%2FgEZaGjTzU%3D\u0026response-content-type=text%2Fplain", "har_logs_url": "https://www.browserstack.com/s3-upload/bs-video-logs-euw/s3-eu-west-1/d85b895f81c51f9cd5c72c225c9f155b331902c6/d85b895f81c51f9cd5c72c225c9f155b331902c6-har-logs.txt?AWSAccessKeyId=AKIAIN2TCEEW2SVRV5JA\u0026Expires=1509231864\u0026Signature=LIp46ukF%2FZunjjONYzweREZP73s%3D" } } ] ================================================ FILE: browserstack.json ================================================ { "test_framework": "qunit", "test_path": "test/index.html", "browsers": [ { "browser": "ie", "browser_version": "10", "os": "Windows", "os_version": "8" }, { "browser": "edge", "browser_version": "latest", "os": "Windows", "os_version": "10" }, { "browser": "firefox", "browser_version": "latest", "os": "Windows", "os_version": "10" }, { "browser": "chrome", "browser_version": "latest", "os": "Windows", "os_version": "10" }, { "browser": "opera", "browser_version": "latest", "os": "Windows", "os_version": "10" }, { "browser": "safari", "browser_version": "latest", "os": "OS X", "os_version": "El Capitan" } ] } ================================================ FILE: composer.json ================================================ { "name": "needim/noty", "description": "Noty is a library that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog.", "type": "library", "license": "MIT", "homepage": "http://ned.im/noty", "keywords": [ "noty", "notification" ], "authors": [ { "name": "Nedim Arabaci", "homepage": "http://ned.im", "role": "Developer" } ], "minimum-stability": "dev" } ================================================ FILE: demo/animate.css ================================================ @charset "UTF-8"; /*! * animate.css -http://daneden.me/animate * Version - 3.5.1 * Licensed under the MIT license - http://opensource.org/licenses/MIT * * Copyright (c) 2016 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; } .animated.flipOutX, .animated.flipOutY, .animated.bounceIn, .animated.bounceOut { -webkit-animation-duration: .75s; animation-duration: .75s; } @-webkit-keyframes bounce { from, 20%, 53%, 80%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } 40%, 43% { -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); -webkit-transform: translate3d(0, -30px, 0); transform: translate3d(0, -30px, 0); } 70% { -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.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 { from, 20%, 53%, 80%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } 40%, 43% { -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); -webkit-transform: translate3d(0, -30px, 0); transform: translate3d(0, -30px, 0); } 70% { -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); -webkit-transform: translate3d(0, -15px, 0); transform: translate3d(0, -15px, 0); } 90% { -webkit-transform: translate3d(0,-4px,0); transform: translate3d(0,-4px,0); } } .bounce { -webkit-animation-name: bounce; animation-name: bounce; -webkit-transform-origin: center bottom; transform-origin: center bottom; } @-webkit-keyframes flash { from, 50%, to { opacity: 1; } 25%, 75% { opacity: 0; } } @keyframes flash { from, 50%, to { opacity: 1; } 25%, 75% { opacity: 0; } } .flash { -webkit-animation-name: flash; animation-name: flash; } /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ @-webkit-keyframes pulse { from { -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); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes pulse { from { -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); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } .pulse { -webkit-animation-name: pulse; animation-name: pulse; } @-webkit-keyframes rubberBand { from { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } 30% { -webkit-transform: scale3d(1.25, 0.75, 1); transform: scale3d(1.25, 0.75, 1); } 40% { -webkit-transform: scale3d(0.75, 1.25, 1); transform: scale3d(0.75, 1.25, 1); } 50% { -webkit-transform: scale3d(1.15, 0.85, 1); transform: scale3d(1.15, 0.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); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes rubberBand { from { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } 30% { -webkit-transform: scale3d(1.25, 0.75, 1); transform: scale3d(1.25, 0.75, 1); } 40% { -webkit-transform: scale3d(0.75, 1.25, 1); transform: scale3d(0.75, 1.25, 1); } 50% { -webkit-transform: scale3d(1.15, 0.85, 1); transform: scale3d(1.15, 0.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); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } .rubberBand { -webkit-animation-name: rubberBand; animation-name: rubberBand; } @-webkit-keyframes shake { from, to { -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 { from, to { -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); } } .shake { -webkit-animation-name: shake; animation-name: shake; } @-webkit-keyframes headShake { 0% { -webkit-transform: translateX(0); transform: translateX(0); } 6.5% { -webkit-transform: translateX(-6px) rotateY(-9deg); transform: translateX(-6px) rotateY(-9deg); } 18.5% { -webkit-transform: translateX(5px) rotateY(7deg); transform: translateX(5px) rotateY(7deg); } 31.5% { -webkit-transform: translateX(-3px) rotateY(-5deg); transform: translateX(-3px) rotateY(-5deg); } 43.5% { -webkit-transform: translateX(2px) rotateY(3deg); transform: translateX(2px) rotateY(3deg); } 50% { -webkit-transform: translateX(0); transform: translateX(0); } } @keyframes headShake { 0% { -webkit-transform: translateX(0); transform: translateX(0); } 6.5% { -webkit-transform: translateX(-6px) rotateY(-9deg); transform: translateX(-6px) rotateY(-9deg); } 18.5% { -webkit-transform: translateX(5px) rotateY(7deg); transform: translateX(5px) rotateY(7deg); } 31.5% { -webkit-transform: translateX(-3px) rotateY(-5deg); transform: translateX(-3px) rotateY(-5deg); } 43.5% { -webkit-transform: translateX(2px) rotateY(3deg); transform: translateX(2px) rotateY(3deg); } 50% { -webkit-transform: translateX(0); transform: translateX(0); } } .headShake { -webkit-animation-timing-function: ease-in-out; animation-timing-function: ease-in-out; -webkit-animation-name: headShake; animation-name: headShake; } @-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); } to { -webkit-transform: rotate3d(0, 0, 1, 0deg); transform: rotate3d(0, 0, 1, 0deg); } } @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); } to { -webkit-transform: rotate3d(0, 0, 1, 0deg); transform: rotate3d(0, 0, 1, 0deg); } } .swing { -webkit-transform-origin: top center; transform-origin: top center; -webkit-animation-name: swing; animation-name: swing; } @-webkit-keyframes tada { from { -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); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes tada { from { -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); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } .tada { -webkit-animation-name: tada; animation-name: tada; } /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ @-webkit-keyframes wobble { from { -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); } to { -webkit-transform: none; transform: none; } } @keyframes wobble { from { -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); } to { -webkit-transform: none; transform: none; } } .wobble { -webkit-animation-name: wobble; animation-name: wobble; } @-webkit-keyframes jello { from, 11.1%, to { -webkit-transform: none; transform: none; } 22.2% { -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); transform: skewX(-12.5deg) skewY(-12.5deg); } 33.3% { -webkit-transform: skewX(6.25deg) skewY(6.25deg); transform: skewX(6.25deg) skewY(6.25deg); } 44.4% { -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); transform: skewX(-3.125deg) skewY(-3.125deg); } 55.5% { -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); transform: skewX(1.5625deg) skewY(1.5625deg); } 66.6% { -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); transform: skewX(-0.78125deg) skewY(-0.78125deg); } 77.7% { -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); transform: skewX(0.390625deg) skewY(0.390625deg); } 88.8% { -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); transform: skewX(-0.1953125deg) skewY(-0.1953125deg); } } @keyframes jello { from, 11.1%, to { -webkit-transform: none; transform: none; } 22.2% { -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); transform: skewX(-12.5deg) skewY(-12.5deg); } 33.3% { -webkit-transform: skewX(6.25deg) skewY(6.25deg); transform: skewX(6.25deg) skewY(6.25deg); } 44.4% { -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); transform: skewX(-3.125deg) skewY(-3.125deg); } 55.5% { -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); transform: skewX(1.5625deg) skewY(1.5625deg); } 66.6% { -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); transform: skewX(-0.78125deg) skewY(-0.78125deg); } 77.7% { -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); transform: skewX(0.390625deg) skewY(0.390625deg); } 88.8% { -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); transform: skewX(-0.1953125deg) skewY(-0.1953125deg); } } .jello { -webkit-animation-name: jello; animation-name: jello; -webkit-transform-origin: center; transform-origin: center; } @-webkit-keyframes bounceIn { from, 20%, 40%, 60%, 80%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 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); } to { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes bounceIn { from, 20%, 40%, 60%, 80%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 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); } to { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } .bounceIn { -webkit-animation-name: bounceIn; animation-name: bounceIn; } @-webkit-keyframes bounceInDown { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 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); } to { -webkit-transform: none; transform: none; } } @keyframes bounceInDown { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 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); } to { -webkit-transform: none; transform: none; } } .bounceInDown { -webkit-animation-name: bounceInDown; animation-name: bounceInDown; } @-webkit-keyframes bounceInLeft { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 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); } to { -webkit-transform: none; transform: none; } } @keyframes bounceInLeft { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 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); } to { -webkit-transform: none; transform: none; } } .bounceInLeft { -webkit-animation-name: bounceInLeft; animation-name: bounceInLeft; } @-webkit-keyframes bounceInRight { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } from { 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); } to { -webkit-transform: none; transform: none; } } @keyframes bounceInRight { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } from { 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); } to { -webkit-transform: none; transform: none; } } .bounceInRight { -webkit-animation-name: bounceInRight; animation-name: bounceInRight; } @-webkit-keyframes bounceInUp { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } from { 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); } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes bounceInUp { from, 60%, 75%, 90%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } from { 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); } to { -webkit-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); } to { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } } @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); } to { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } } .bounceOut { -webkit-animation-name: bounceOut; animation-name: bounceOut; } @-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); } to { opacity: 0; -webkit-transform: translate3d(0, 2000px, 0); transform: translate3d(0, 2000px, 0); } } @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); } to { opacity: 0; -webkit-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); } to { opacity: 0; -webkit-transform: translate3d(-2000px, 0, 0); transform: translate3d(-2000px, 0, 0); } } @keyframes bounceOutLeft { 20% { opacity: 1; -webkit-transform: translate3d(20px, 0, 0); transform: translate3d(20px, 0, 0); } to { opacity: 0; -webkit-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); } to { opacity: 0; -webkit-transform: translate3d(2000px, 0, 0); transform: translate3d(2000px, 0, 0); } } @keyframes bounceOutRight { 20% { opacity: 1; -webkit-transform: translate3d(-20px, 0, 0); transform: translate3d(-20px, 0, 0); } to { opacity: 0; -webkit-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); } to { opacity: 0; -webkit-transform: translate3d(0, -2000px, 0); transform: translate3d(0, -2000px, 0); } } @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); } to { opacity: 0; -webkit-transform: translate3d(0, -2000px, 0); transform: translate3d(0, -2000px, 0); } } .bounceOutUp { -webkit-animation-name: bounceOutUp; animation-name: bounceOutUp; } @-webkit-keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .fadeIn { -webkit-animation-name: fadeIn; animation-name: fadeIn; } @-webkit-keyframes fadeInDown { from { opacity: 0; -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInDown { from { opacity: 0; -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInDown { -webkit-animation-name: fadeInDown; animation-name: fadeInDown; } @-webkit-keyframes fadeInDownBig { from { opacity: 0; -webkit-transform: translate3d(0, -2000px, 0); transform: translate3d(0, -2000px, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInDownBig { from { opacity: 0; -webkit-transform: translate3d(0, -2000px, 0); transform: translate3d(0, -2000px, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInDownBig { -webkit-animation-name: fadeInDownBig; animation-name: fadeInDownBig; } @-webkit-keyframes fadeInLeft { from { opacity: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInLeft { from { opacity: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInLeft { -webkit-animation-name: fadeInLeft; animation-name: fadeInLeft; } @-webkit-keyframes fadeInLeftBig { from { opacity: 0; -webkit-transform: translate3d(-2000px, 0, 0); transform: translate3d(-2000px, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInLeftBig { from { opacity: 0; -webkit-transform: translate3d(-2000px, 0, 0); transform: translate3d(-2000px, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInLeftBig { -webkit-animation-name: fadeInLeftBig; animation-name: fadeInLeftBig; } @-webkit-keyframes fadeInRight { from { opacity: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInRight { from { opacity: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInRight { -webkit-animation-name: fadeInRight; animation-name: fadeInRight; } @-webkit-keyframes fadeInRightBig { from { opacity: 0; -webkit-transform: translate3d(2000px, 0, 0); transform: translate3d(2000px, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInRightBig { from { opacity: 0; -webkit-transform: translate3d(2000px, 0, 0); transform: translate3d(2000px, 0, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInRightBig { -webkit-animation-name: fadeInRightBig; animation-name: fadeInRightBig; } @-webkit-keyframes fadeInUp { from { opacity: 0; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInUp { from { opacity: 0; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInUp { -webkit-animation-name: fadeInUp; animation-name: fadeInUp; } @-webkit-keyframes fadeInUpBig { from { opacity: 0; -webkit-transform: translate3d(0, 2000px, 0); transform: translate3d(0, 2000px, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes fadeInUpBig { from { opacity: 0; -webkit-transform: translate3d(0, 2000px, 0); transform: translate3d(0, 2000px, 0); } to { opacity: 1; -webkit-transform: none; transform: none; } } .fadeInUpBig { -webkit-animation-name: fadeInUpBig; animation-name: fadeInUpBig; } @-webkit-keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } .fadeOut { -webkit-animation-name: fadeOut; animation-name: fadeOut; } @-webkit-keyframes fadeOutDown { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } } @keyframes fadeOutDown { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } } .fadeOutDown { -webkit-animation-name: fadeOutDown; animation-name: fadeOutDown; } @-webkit-keyframes fadeOutDownBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, 2000px, 0); transform: translate3d(0, 2000px, 0); } } @keyframes fadeOutDownBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, 2000px, 0); transform: translate3d(0, 2000px, 0); } } .fadeOutDownBig { -webkit-animation-name: fadeOutDownBig; animation-name: fadeOutDownBig; } @-webkit-keyframes fadeOutLeft { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } } @keyframes fadeOutLeft { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } } .fadeOutLeft { -webkit-animation-name: fadeOutLeft; animation-name: fadeOutLeft; } @-webkit-keyframes fadeOutLeftBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(-2000px, 0, 0); transform: translate3d(-2000px, 0, 0); } } @keyframes fadeOutLeftBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(-2000px, 0, 0); transform: translate3d(-2000px, 0, 0); } } .fadeOutLeftBig { -webkit-animation-name: fadeOutLeftBig; animation-name: fadeOutLeftBig; } @-webkit-keyframes fadeOutRight { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } } @keyframes fadeOutRight { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } } .fadeOutRight { -webkit-animation-name: fadeOutRight; animation-name: fadeOutRight; } @-webkit-keyframes fadeOutRightBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(2000px, 0, 0); transform: translate3d(2000px, 0, 0); } } @keyframes fadeOutRightBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(2000px, 0, 0); transform: translate3d(2000px, 0, 0); } } .fadeOutRightBig { -webkit-animation-name: fadeOutRightBig; animation-name: fadeOutRightBig; } @-webkit-keyframes fadeOutUp { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } } @keyframes fadeOutUp { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } } .fadeOutUp { -webkit-animation-name: fadeOutUp; animation-name: fadeOutUp; } @-webkit-keyframes fadeOutUpBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, -2000px, 0); transform: translate3d(0, -2000px, 0); } } @keyframes fadeOutUpBig { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, -2000px, 0); transform: translate3d(0, -2000px, 0); } } .fadeOutUpBig { -webkit-animation-name: fadeOutUpBig; animation-name: fadeOutUpBig; } @-webkit-keyframes flip { from { -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; } to { -webkit-transform: perspective(400px); transform: perspective(400px); -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } } @keyframes flip { from { -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; } to { -webkit-transform: perspective(400px); transform: perspective(400px); -webkit-animation-timing-function: ease-in; animation-timing-function: ease-in; } } .animated.flip { -webkit-backface-visibility: visible; backface-visibility: visible; -webkit-animation-name: flip; animation-name: flip; } @-webkit-keyframes flipInX { from { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); transform: perspective(400px) rotate3d(1, 0, 0, 90deg); -webkit-animation-timing-function: ease-in; animation-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-animation-timing-function: ease-in; animation-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); } to { -webkit-transform: perspective(400px); transform: perspective(400px); } } @keyframes flipInX { from { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); transform: perspective(400px) rotate3d(1, 0, 0, 90deg); -webkit-animation-timing-function: ease-in; animation-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-animation-timing-function: ease-in; animation-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); } to { -webkit-transform: perspective(400px); transform: perspective(400px); } } .flipInX { -webkit-backface-visibility: visible !important; backface-visibility: visible !important; -webkit-animation-name: flipInX; animation-name: flipInX; } @-webkit-keyframes flipInY { from { -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); transform: perspective(400px) rotate3d(0, 1, 0, 90deg); -webkit-animation-timing-function: ease-in; animation-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-animation-timing-function: ease-in; animation-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); } to { -webkit-transform: perspective(400px); transform: perspective(400px); } } @keyframes flipInY { from { -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); transform: perspective(400px) rotate3d(0, 1, 0, 90deg); -webkit-animation-timing-function: ease-in; animation-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-animation-timing-function: ease-in; animation-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); } to { -webkit-transform: perspective(400px); transform: perspective(400px); } } .flipInY { -webkit-backface-visibility: visible !important; backface-visibility: visible !important; -webkit-animation-name: flipInY; animation-name: flipInY; } @-webkit-keyframes flipOutX { from { -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; } to { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); transform: perspective(400px) rotate3d(1, 0, 0, 90deg); opacity: 0; } } @keyframes flipOutX { from { -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; } to { -webkit-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-backface-visibility: visible !important; backface-visibility: visible !important; } @-webkit-keyframes flipOutY { from { -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; } to { -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); transform: perspective(400px) rotate3d(0, 1, 0, 90deg); opacity: 0; } } @keyframes flipOutY { from { -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; } to { -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); transform: perspective(400px) rotate3d(0, 1, 0, 90deg); opacity: 0; } } .flipOutY { -webkit-backface-visibility: visible !important; backface-visibility: visible !important; -webkit-animation-name: flipOutY; animation-name: flipOutY; } @-webkit-keyframes lightSpeedIn { from { -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; } to { -webkit-transform: none; transform: none; opacity: 1; } } @keyframes lightSpeedIn { from { -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; } to { -webkit-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 { from { opacity: 1; } to { -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); transform: translate3d(100%, 0, 0) skewX(30deg); opacity: 0; } } @keyframes lightSpeedOut { from { opacity: 1; } to { -webkit-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 { from { -webkit-transform-origin: center; transform-origin: center; -webkit-transform: rotate3d(0, 0, 1, -200deg); transform: rotate3d(0, 0, 1, -200deg); opacity: 0; } to { -webkit-transform-origin: center; transform-origin: center; -webkit-transform: none; transform: none; opacity: 1; } } @keyframes rotateIn { from { -webkit-transform-origin: center; transform-origin: center; -webkit-transform: rotate3d(0, 0, 1, -200deg); transform: rotate3d(0, 0, 1, -200deg); opacity: 0; } to { -webkit-transform-origin: center; transform-origin: center; -webkit-transform: none; transform: none; opacity: 1; } } .rotateIn { -webkit-animation-name: rotateIn; animation-name: rotateIn; } @-webkit-keyframes rotateInDownLeft { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: rotate3d(0, 0, 1, -45deg); transform: rotate3d(0, 0, 1, -45deg); opacity: 0; } to { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: none; transform: none; opacity: 1; } } @keyframes rotateInDownLeft { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: rotate3d(0, 0, 1, -45deg); transform: rotate3d(0, 0, 1, -45deg); opacity: 0; } to { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: none; transform: none; opacity: 1; } } .rotateInDownLeft { -webkit-animation-name: rotateInDownLeft; animation-name: rotateInDownLeft; } @-webkit-keyframes rotateInDownRight { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: rotate3d(0, 0, 1, 45deg); transform: rotate3d(0, 0, 1, 45deg); opacity: 0; } to { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: none; transform: none; opacity: 1; } } @keyframes rotateInDownRight { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: rotate3d(0, 0, 1, 45deg); transform: rotate3d(0, 0, 1, 45deg); opacity: 0; } to { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: none; transform: none; opacity: 1; } } .rotateInDownRight { -webkit-animation-name: rotateInDownRight; animation-name: rotateInDownRight; } @-webkit-keyframes rotateInUpLeft { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: rotate3d(0, 0, 1, 45deg); transform: rotate3d(0, 0, 1, 45deg); opacity: 0; } to { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: none; transform: none; opacity: 1; } } @keyframes rotateInUpLeft { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: rotate3d(0, 0, 1, 45deg); transform: rotate3d(0, 0, 1, 45deg); opacity: 0; } to { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-transform: none; transform: none; opacity: 1; } } .rotateInUpLeft { -webkit-animation-name: rotateInUpLeft; animation-name: rotateInUpLeft; } @-webkit-keyframes rotateInUpRight { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: rotate3d(0, 0, 1, -90deg); transform: rotate3d(0, 0, 1, -90deg); opacity: 0; } to { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: none; transform: none; opacity: 1; } } @keyframes rotateInUpRight { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: rotate3d(0, 0, 1, -90deg); transform: rotate3d(0, 0, 1, -90deg); opacity: 0; } to { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-transform: none; transform: none; opacity: 1; } } .rotateInUpRight { -webkit-animation-name: rotateInUpRight; animation-name: rotateInUpRight; } @-webkit-keyframes rotateOut { from { -webkit-transform-origin: center; transform-origin: center; opacity: 1; } to { -webkit-transform-origin: center; transform-origin: center; -webkit-transform: rotate3d(0, 0, 1, 200deg); transform: rotate3d(0, 0, 1, 200deg); opacity: 0; } } @keyframes rotateOut { from { -webkit-transform-origin: center; transform-origin: center; opacity: 1; } to { -webkit-transform-origin: center; transform-origin: center; -webkit-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 { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; opacity: 1; } to { -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 { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; opacity: 1; } to { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-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 { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; opacity: 1; } to { -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 { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; opacity: 1; } to { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-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 { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; opacity: 1; } to { -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 { from { -webkit-transform-origin: left bottom; transform-origin: left bottom; opacity: 1; } to { -webkit-transform-origin: left bottom; transform-origin: left bottom; -webkit-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 { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; opacity: 1; } to { -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 { from { -webkit-transform-origin: right bottom; transform-origin: right bottom; opacity: 1; } to { -webkit-transform-origin: right bottom; transform-origin: right bottom; -webkit-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; } to { -webkit-transform: translate3d(0, 700px, 0); transform: translate3d(0, 700px, 0); opacity: 0; } } @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; } to { -webkit-transform: translate3d(0, 700px, 0); transform: translate3d(0, 700px, 0); opacity: 0; } } .hinge { -webkit-animation-name: hinge; animation-name: hinge; } /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ @-webkit-keyframes rollIn { from { opacity: 0; -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); } to { opacity: 1; -webkit-transform: none; transform: none; } } @keyframes rollIn { from { opacity: 0; -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); } to { opacity: 1; -webkit-transform: none; transform: none; } } .rollIn { -webkit-animation-name: rollIn; animation-name: rollIn; } /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ @-webkit-keyframes rollOut { from { opacity: 1; } to { 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 { from { opacity: 1; } to { opacity: 0; -webkit-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 { from { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 50% { opacity: 1; } } @keyframes zoomIn { from { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 50% { opacity: 1; } } .zoomIn { -webkit-animation-name: zoomIn; animation-name: zoomIn; } @-webkit-keyframes zoomInDown { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } @keyframes zoomInDown { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } .zoomInDown { -webkit-animation-name: zoomInDown; animation-name: zoomInDown; } @-webkit-keyframes zoomInLeft { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } @keyframes zoomInLeft { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } .zoomInLeft { -webkit-animation-name: zoomInLeft; animation-name: zoomInLeft; } @-webkit-keyframes zoomInRight { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } @keyframes zoomInRight { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } .zoomInRight { -webkit-animation-name: zoomInRight; animation-name: zoomInRight; } @-webkit-keyframes zoomInUp { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } @keyframes zoomInUp { from { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } .zoomInUp { -webkit-animation-name: zoomInUp; animation-name: zoomInUp; } @-webkit-keyframes zoomOut { from { opacity: 1; } 50% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } to { opacity: 0; } } @keyframes zoomOut { from { opacity: 1; } 50% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } to { 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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } to { 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } @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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } to { 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 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); } to { 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); transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); } to { 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; } } .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); } to { 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); transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); } to { 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; } } .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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } to { 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } @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.550, 0.055, 0.675, 0.190); animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); } to { 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, 0.885, 0.320, 1); animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); } } .zoomOutUp { -webkit-animation-name: zoomOutUp; animation-name: zoomOutUp; } @-webkit-keyframes slideInDown { from { -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideInDown { from { -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .slideInDown { -webkit-animation-name: slideInDown; animation-name: slideInDown; } @-webkit-keyframes slideInLeft { from { -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideInLeft { from { -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .slideInLeft { -webkit-animation-name: slideInLeft; animation-name: slideInLeft; } @-webkit-keyframes slideInRight { from { -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideInRight { from { -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .slideInRight { -webkit-animation-name: slideInRight; animation-name: slideInRight; } @-webkit-keyframes slideInUp { from { -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideInUp { from { -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); visibility: visible; } to { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .slideInUp { -webkit-animation-name: slideInUp; animation-name: slideInUp; } @-webkit-keyframes slideOutDown { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } } @keyframes slideOutDown { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } } .slideOutDown { -webkit-animation-name: slideOutDown; animation-name: slideOutDown; } @-webkit-keyframes slideOutLeft { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } } @keyframes slideOutLeft { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } } .slideOutLeft { -webkit-animation-name: slideOutLeft; animation-name: slideOutLeft; } @-webkit-keyframes slideOutRight { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } } @keyframes slideOutRight { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } } .slideOutRight { -webkit-animation-name: slideOutRight; animation-name: slideOutRight; } @-webkit-keyframes slideOutUp { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } } @keyframes slideOutUp { from { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } to { visibility: hidden; -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } } .slideOutUp { -webkit-animation-name: slideOutUp; animation-name: slideOutUp; } ================================================ FILE: demo/bouncejs/bounce.js ================================================ /** * Bounce.js 0.8.2 * MIT license */ !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Bounce=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 1) { return 1; } t = ratio * this.limit; return 1 - this.exponent(t) * this.oscillation(t); }; BounceEasing.prototype.calculateOmega = function(bounces, limit) { return (this.bounces + 0.5) * Math.PI / this.limit; }; BounceEasing.prototype.exponent = function(t) { return Math.pow(Math.E, -this.alpha * t); }; BounceEasing.prototype.oscillation = function(t) { return Math.cos(this.omega * t); }; BounceEasing.prototype.serialize = function() { return { stiffness: this.stiffness, bounces: this.bounces }; }; return BounceEasing; })(Easing); module.exports = BounceEasing; },{"./index":9}],7:[function(_dereq_,module,exports){ var BounceEasing, HardBounceEasing, __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; }; BounceEasing = _dereq_("./bounce"); HardBounceEasing = (function(_super) { __extends(HardBounceEasing, _super); function HardBounceEasing() { return HardBounceEasing.__super__.constructor.apply(this, arguments); } HardBounceEasing.prototype.oscillation = function(t) { return Math.abs(Math.cos(this.omega * t)); }; return HardBounceEasing; })(BounceEasing); module.exports = HardBounceEasing; },{"./bounce":6}],8:[function(_dereq_,module,exports){ var HardSwayEasing, SwayEasing, __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; }; SwayEasing = _dereq_("./sway"); HardSwayEasing = (function(_super) { __extends(HardSwayEasing, _super); function HardSwayEasing() { return HardSwayEasing.__super__.constructor.apply(this, arguments); } HardSwayEasing.prototype.oscillation = function(t) { return Math.abs(Math.sin(this.omega * t)); }; return HardSwayEasing; })(SwayEasing); module.exports = HardSwayEasing; },{"./sway":10}],9:[function(_dereq_,module,exports){ var Easing, MathHelpers; MathHelpers = _dereq_("../math/helpers"); Easing = (function() { function Easing() {} Easing.prototype.calculate = function(ratio) { return ratio; }; Easing.prototype.serialize = function() { return {}; }; Easing.prototype.findOptimalKeyPoints = function(threshold, resolution) { var area, halfway, i, keyPoint, keyPoints, loops, result, values; if (threshold == null) { threshold = 1.0; } if (resolution == null) { resolution = 1000; } keyPoints = [0]; values = (function() { var _i, _results; _results = []; for (i = _i = 0; 0 <= resolution ? _i < resolution : _i > resolution; i = 0 <= resolution ? ++_i : --_i) { _results.push(this.calculate(i / resolution)); } return _results; }).call(this); keyPoints = keyPoints.concat(MathHelpers.findTurningPoints(values)); keyPoints.push(resolution - 1); i = 0; loops = 1000; while (loops--) { if (i === keyPoints.length - 1) { break; } area = MathHelpers.areaBetweenLineAndCurve(values, keyPoints[i], keyPoints[i + 1]); if (area <= threshold) { i++; } else { halfway = Math.round(keyPoints[i] + (keyPoints[i + 1] - keyPoints[i]) / 2); keyPoints.splice(i + 1, 0, halfway); } } if (loops === 0) { return []; } return result = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = keyPoints.length; _i < _len; _i++) { keyPoint = keyPoints[_i]; _results.push(keyPoint / (resolution - 1)); } return _results; })(); }; return Easing; })(); module.exports = Easing; },{"../math/helpers":12}],10:[function(_dereq_,module,exports){ var BounceEasing, SwayEasing, __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; }; BounceEasing = _dereq_("./bounce"); SwayEasing = (function(_super) { __extends(SwayEasing, _super); function SwayEasing() { return SwayEasing.__super__.constructor.apply(this, arguments); } SwayEasing.prototype.calculate = function(ratio) { var t; if (ratio >= 1) { return 0; } t = ratio * this.limit; return this.exponent(t) * this.oscillation(t); }; SwayEasing.prototype.calculateOmega = function(bounces, limit) { return this.bounces * Math.PI / this.limit; }; SwayEasing.prototype.oscillation = function(t) { return Math.sin(this.omega * t); }; return SwayEasing; })(BounceEasing); module.exports = SwayEasing; },{"./bounce":6}],11:[function(_dereq_,module,exports){ var Bounce, ComponentClasses, Matrix4D; Matrix4D = _dereq_("./math/matrix4d"); ComponentClasses = { scale: _dereq_("./components/scale"), rotate: _dereq_("./components/rotate"), translate: _dereq_("./components/translate"), skew: _dereq_("./components/skew") }; Bounce = (function() { Bounce.FPS = 30; Bounce.counter = 1; Bounce.prototype.components = null; Bounce.prototype.duration = 0; function Bounce() { this.components = []; } Bounce.prototype.scale = function(options) { return this.addComponent(new ComponentClasses["scale"](options)); }; Bounce.prototype.rotate = function(options) { return this.addComponent(new ComponentClasses["rotate"](options)); }; Bounce.prototype.translate = function(options) { return this.addComponent(new ComponentClasses["translate"](options)); }; Bounce.prototype.skew = function(options) { return this.addComponent(new ComponentClasses["skew"](options)); }; Bounce.prototype.addComponent = function(component) { this.components.push(component); this.updateDuration(); return this; }; Bounce.prototype.serialize = function() { var component, serialized, _i, _len, _ref; serialized = []; _ref = this.components; for (_i = 0, _len = _ref.length; _i < _len; _i++) { component = _ref[_i]; serialized.push(component.serialize()); } return serialized; }; Bounce.prototype.deserialize = function(serialized) { var options, _i, _len; for (_i = 0, _len = serialized.length; _i < _len; _i++) { options = serialized[_i]; this.addComponent(new ComponentClasses[options.type](options)); } return this; }; Bounce.prototype.updateDuration = function() { return this.duration = this.components.map(function(component) { return component.duration + component.delay; }).reduce(function(a, b) { return Math.max(a, b); }); }; Bounce.prototype.define = function(name) { this.name = name || Bounce.generateName(); this.styleElement = document.createElement("style"); this.styleElement.innerHTML = this.getKeyframeCSS({ name: this.name, prefix: true }); document.body.appendChild(this.styleElement); return this; }; Bounce.prototype.applyTo = function(elements, options) { var css, deferred, element, prefix, prefixes, _i, _j, _len, _len1, _ref; if (options == null) { options = {}; } this.define(); if (!elements.length) { elements = [elements]; } prefixes = this.getPrefixes(); deferred = null; if (window.jQuery && window.jQuery.Deferred) { deferred = new window.jQuery.Deferred(); } for (_i = 0, _len = elements.length; _i < _len; _i++) { element = elements[_i]; _ref = prefixes.animation; for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { prefix = _ref[_j]; css = [this.name, "" + this.duration + "ms", "linear", "both"]; if (options.loop) { css.push("infinite"); } element.style["" + prefix + "animation"] = css.join(" "); } } if (!options.loop) { setTimeout(((function(_this) { return function() { if (options.remove) { _this.remove(); } if (typeof options.onComplete === "function") { options.onComplete(); } if (deferred) { return deferred.resolve(); } }; })(this)), this.duration); } return deferred; }; Bounce.prototype.remove = function() { var _ref; if (!this.styleElement) { return; } if (this.styleElement.remove) { return this.styleElement.remove(); } else { return (_ref = this.styleElement.parentNode) != null ? _ref.removeChild(this.styleElement) : void 0; } }; Bounce.prototype.getPrefixes = function(force) { var prefixes, style; prefixes = { transform: [""], animation: [""] }; style = document.createElement("dummy").style; if (force || (!("transform" in style) && "webkitTransform" in style)) { prefixes.transform = ["-webkit-", ""]; } if (force || (!("animation" in style) && "webkitAnimation" in style)) { prefixes.animation = ["-webkit-", ""]; } return prefixes; }; Bounce.prototype.getKeyframeCSS = function(options) { var animations, key, keyframeList, keyframes, matrix, prefix, prefixes, transformString, transforms, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; if (options == null) { options = {}; } this.name = options.name || Bounce.generateName(); prefixes = { transform: [""], animation: [""] }; if (options.prefix || options.forcePrefix) { prefixes = this.getPrefixes(options.forcePrefix); } keyframeList = []; keyframes = this.getKeyframes(options); _ref = this.keys; for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; matrix = keyframes[key]; transformString = "matrix3d" + matrix; transforms = []; _ref1 = prefixes.transform; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { prefix = _ref1[_j]; transforms.push("" + prefix + "transform: " + transformString + ";"); } keyframeList.push("" + (Math.round(key * 100 * 100) / 100) + "% { " + (transforms.join(" ")) + " }"); } animations = []; _ref2 = prefixes.animation; for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { prefix = _ref2[_k]; animations.push("@" + prefix + "keyframes " + this.name + " { \n " + (keyframeList.join("\n ")) + " \n}"); } return animations.join("\n\n"); }; Bounce.prototype.getKeyframes = function(options) { var component, componentKeys, currentTime, frames, i, key, keyframes, keys, matrix, ratio, _i, _j, _k, _l, _len, _len1, _len2, _ref, _ref1; if (options == null) { options = {}; } keys = [0, 1]; if (options.optimized) { _ref = this.components; for (_i = 0, _len = _ref.length; _i < _len; _i++) { component = _ref[_i]; componentKeys = component.easingObject.findOptimalKeyPoints().map((function(_this) { return function(key) { return (key * component.duration / _this.duration) + (component.delay / _this.duration); }; })(this)); if (component.delay) { componentKeys.push((component.delay / this.duration) - 0.001); } keys = keys.concat(componentKeys); } } else { frames = Math.round((this.duration / 1000) * Bounce.FPS); for (i = _j = 0; 0 <= frames ? _j <= frames : _j >= frames; i = 0 <= frames ? ++_j : --_j) { keys.push(i / frames); } } keys = keys.sort(function(a, b) { return a - b; }); this.keys = []; keyframes = {}; for (_k = 0, _len1 = keys.length; _k < _len1; _k++) { key = keys[_k]; if (keyframes[key]) { continue; } matrix = new Matrix4D().identity(); _ref1 = this.components; for (_l = 0, _len2 = _ref1.length; _l < _len2; _l++) { component = _ref1[_l]; currentTime = key * this.duration; if ((component.delay - currentTime) > 1e-8) { continue; } ratio = (key - component.delay / this.duration) / (component.duration / this.duration); matrix.multiply(component.getEasedMatrix(ratio)); } this.keys.push(key); keyframes[key] = matrix.transpose().toFixed(3); } return keyframes; }; Bounce.generateName = function() { return "animation-" + (Bounce.counter++); }; Bounce.isSupported = function() { var property, propertyIsSupported, propertyList, propertyLists, style, _i, _j, _len, _len1; style = document.createElement("dummy").style; propertyLists = [["transform", "webkitTransform"], ["animation", "webkitAnimation"]]; for (_i = 0, _len = propertyLists.length; _i < _len; _i++) { propertyList = propertyLists[_i]; propertyIsSupported = false; for (_j = 0, _len1 = propertyList.length; _j < _len1; _j++) { property = propertyList[_j]; propertyIsSupported || (propertyIsSupported = property in style); } if (!propertyIsSupported) { return false; } } return true; }; return Bounce; })(); module.exports = Bounce; },{"./components/rotate":2,"./components/scale":3,"./components/skew":4,"./components/translate":5,"./math/matrix4d":13}],12:[function(_dereq_,module,exports){ var MathHelpers; MathHelpers = (function() { function MathHelpers() {} MathHelpers.prototype.sign = function(value) { if (value < 0) { return -1; } return 1; }; MathHelpers.prototype.findTurningPoints = function(values) { var i, signA, signB, turningPoints, _i, _ref; turningPoints = []; for (i = _i = 1, _ref = values.length - 1; 1 <= _ref ? _i < _ref : _i > _ref; i = 1 <= _ref ? ++_i : --_i) { signA = this.sign(values[i] - values[i - 1]); signB = this.sign(values[i + 1] - values[i]); if (signA !== signB) { turningPoints.push(i); } } return turningPoints; }; MathHelpers.prototype.areaBetweenLineAndCurve = function(values, start, end) { var area, curveValue, i, length, lineValue, yEnd, yStart, _i; length = end - start; yStart = values[start]; yEnd = values[end]; area = 0; for (i = _i = 0; 0 <= length ? _i <= length : _i >= length; i = 0 <= length ? ++_i : --_i) { curveValue = values[start + i]; lineValue = yStart + (i / length) * (yEnd - yStart); area += Math.abs(lineValue - curveValue); } return area; }; return MathHelpers; })(); module.exports = new MathHelpers; },{}],13:[function(_dereq_,module,exports){ var Matrix4D; Matrix4D = (function() { Matrix4D.prototype._array = null; function Matrix4D(array) { this._array = (array != null ? array.slice(0) : void 0) || [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; } Matrix4D.prototype.equals = function(matrix) { return this.toString() === matrix.toString(); }; Matrix4D.prototype.identity = function() { this.setArray([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); return this; }; Matrix4D.prototype.multiply = function(matrix) { var i, j, k, res, value, _i, _j, _k; res = new Matrix4D; for (i = _i = 0; _i < 4; i = ++_i) { for (j = _j = 0; _j < 4; j = ++_j) { for (k = _k = 0; _k < 4; k = ++_k) { value = res.get(i, j) + this.get(i, k) * matrix.get(k, j); res.set(i, j, value); } } } return this.copy(res); }; Matrix4D.prototype.transpose = function() { var a; a = this.getArray(); this.setArray([a[0], a[4], a[8], a[12], a[1], a[5], a[9], a[13], a[2], a[6], a[10], a[14], a[3], a[7], a[11], a[15]]); return this; }; Matrix4D.prototype.get = function(row, column) { return this.getArray()[row * 4 + column]; }; Matrix4D.prototype.set = function(row, column, value) { return this._array[row * 4 + column] = value; }; Matrix4D.prototype.copy = function(matrix) { this._array = matrix.getArray(); return this; }; Matrix4D.prototype.clone = function() { return new Matrix4D(this.getArray()); }; Matrix4D.prototype.getArray = function() { return this._array.slice(0); }; Matrix4D.prototype.setArray = function(array) { this._array = array; return this; }; Matrix4D.prototype.toString = function() { return "(" + (this.getArray().join(", ")) + ")"; }; Matrix4D.prototype.toFixed = function(n) { var value; this._array = (function() { var _i, _len, _ref, _results; _ref = this._array; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { value = _ref[_i]; _results.push(parseFloat(value.toFixed(n))); } return _results; }).call(this); return this; }; return Matrix4D; })(); module.exports = Matrix4D; },{}],14:[function(_dereq_,module,exports){ var Vector2D; Vector2D = (function() { Vector2D.prototype.x = 0; Vector2D.prototype.y = 0; function Vector2D(x, y) { this.x = x != null ? x : 0; this.y = y != null ? y : 0; } Vector2D.prototype.add = function(vector) { if (!Vector2D.isVector2D(vector)) { return this._addScalar(vector); } this.x += vector.x; this.y += vector.y; return this; }; Vector2D.prototype._addScalar = function(n) { this.x += n; this.y += n; return this; }; Vector2D.prototype.subtract = function(vector) { if (!Vector2D.isVector2D(vector)) { return this._subtractScalar(vector); } this.x -= vector.x; this.y -= vector.y; return this; }; Vector2D.prototype._subtractScalar = function(n) { return this._addScalar(-n); }; Vector2D.prototype.multiply = function(vector) { if (!Vector2D.isVector2D(vector)) { return this._multiplyScalar(vector); } this.x *= vector.x; this.y *= vector.y; return this; }; Vector2D.prototype._multiplyScalar = function(n) { this.x *= n; this.y *= n; return this; }; Vector2D.prototype.divide = function(vector) { if (!Vector2D.isVector2D(vector)) { return this._divideScalar(vector); } this.x /= vector.x; this.y /= vector.y; return this; }; Vector2D.prototype._divideScalar = function(n) { return this._multiplyScalar(1 / n); }; Vector2D.prototype.clone = function() { return new Vector2D(this.x, this.y); }; Vector2D.prototype.copy = function(vector) { this.x = vector.x; this.y = vector.y; return this; }; Vector2D.prototype.equals = function(vector) { return vector.x === this.x && vector.y === this.y; }; Vector2D.prototype.toString = function() { return "(" + this.x + ", " + this.y + ")"; }; Vector2D.prototype.toFixed = function(n) { this.x = parseFloat(this.x.toFixed(n)); this.y = parseFloat(this.y.toFixed(n)); return this; }; Vector2D.prototype.toArray = function() { return [this.x, this.y]; }; Vector2D.isVector2D = function(item) { return item instanceof Vector2D; }; return Vector2D; })(); module.exports = Vector2D; },{}]},{},[11]) (11) }); ================================================ FILE: demo/demo.css ================================================ body { font-family: 'GothamRoundedLight', sans-serif; font-weight: 300; background-color: rgb(255, 253, 250); background-image: url('bg-dot.png'); background-size: 41px 40px; background-position: 0 0; background-repeat: repeat; } a, strong { color: inherit; font-family: 'GothamRoundedMedium', sans-serif; } a:hover { text-decoration: none; } .activity-item i { float: left; margin-top: 3px; font-size: 16px; } div.activity { margin-left: 28px; line-height: 1.4em; } div.activity-item { padding: 7px 12px; } div.activity > span { display: block; font-size: .8em; } #custom_container { border: 2px solid #ccc; width: 500px; max-width: 100%; margin: 40px auto; min-height: 100px; border-radius: 5px; background: rgba(255, 255, 255, .5); overflow: hidden; } .logo { text-align: center; background: rgb(255, 253, 250); padding: 0 20px; width: 200px; margin: 0 auto; } select:focus { outline: none; } select { /* General styling */ height: 30px; width: 137px; padding-left: 10px; color: #222; border-radius: 3px; border: 0 solid #222; margin: 0 3px; /* Removes the default

CREATE

Custom Container

================================================ FILE: demo/push.html ================================================ NOTY v3 Push Demo


================================================ FILE: demo/sendpush.js ================================================ const webpush = require('web-push') const vapidKeys = webpush.generateVAPIDKeys() // Create a project on the Firebase Developer Console for the key // https://console.firebase.google.com/ webpush.setGCMAPIKey(process.env.NOTY_PUSH_API_KEY) webpush.setVapidDetails( 'mailto:nedimarabaci@gmail.com', vapidKeys.publicKey, vapidKeys.privateKey ) const pushSubscription = { endpoint: '<-https://android.googleapis.com/gcm/send/dF3pK2rWhOQ..........->', keys: { auth: '<-insert-auth-key-here->', p256dh: '<-insert-p256dh-key-here->' } } webpush.sendNotification(pushSubscription, JSON.stringify({ title: 'Noty title', body: 'Noty body', icon: 'https://avatars1.githubusercontent.com/u/3040386?v=3&s=200', image: 'https://cdn.dribbble.com/users/252805/screenshots/2760603/dribbble-notification.png', url: 'http://ned.im/noty/?ref=webPushTest', actions: [ {action: 'actionYes', 'title': 'Yes', 'icon': 'https://cdn2.iconfinder.com/data/icons/navigation-set-arrows-part-two/32/Check-128.png'}, {action: 'actionNo', 'title': 'No', 'icon': 'https://cdn0.iconfinder.com/data/icons/navigation-set-arrows-part-one/32/Close-128.png'} ] })) ================================================ FILE: docs/.nojekyll ================================================ ================================================ FILE: docs/README.md ================================================ # ![logo](_media/noty-v3-logo.png) > A Dependency-free notification library

Star Fork Watch Follow @needim

GitHub release Bower version NPM version Packagist version
NPM Downloads Contributors

##  Sponsored By ##  Became a Patron If you enjoy my work and want to support me creating stuff, I'm on Patreon!
Patreon logo Become a Patron! !> v2 Documentation is here ## Features - Dependency-free - UMD - Web Push Notifications with Service Worker support - Named queue system - Has 11 layouts, 5 notification styles, 5+ themes - Custom container (inline notifications) - Confirm notifications - TTL with timeout option - Progress bar indicator for timed notifications - Supports css animations, **animate.css**, **mojs**, **bounce.js**, **velocity** and others - 2 close options: click, button - API & Callbacks - Custom templating - Document visibility control (blur, focus) ================================================ FILE: docs/_assets/docs.js ================================================ var velocityShow = function (promise) { var n = this $.Velocity(n.barDom, { left: 450, scaleY: 2 }, { duration: 0 }) $.Velocity(n.barDom, { left: 0, scaleY: 1 }, { easing: [8, 8], complete: function () { promise(function (resolve) { resolve() }) } }) } var velocityClose = function (promise) { var n = this $.Velocity(n.barDom, { left: '+=-50' }, { easing: [8, 8, 2], duration: 350 }) $.Velocity(n.barDom, { left: 450, scaleY: .2, height: 0, margin: 0 }, { easing: [8, 8], complete: function () { promise(function (resolve) { resolve() }) } }) } var mojsShow = function (promise) { var n = this var Timeline = new mojs.Timeline() var body = new mojs.Html({ el: n.barDom, x: { 500: 0, delay: 0, duration: 500, easing: 'elastic.out' }, isForce3d: true, onComplete: function () { promise(function (resolve) { resolve() }) } }) var parent = new mojs.Shape({ parent: n.barDom, width: 200, height: n.barDom.getBoundingClientRect().height, radius: 0, x: { [150]: -150 }, duration: 1.2 * 500, isShowStart: true }) n.barDom.style['overflow'] = 'visible' parent.el.style['overflow'] = 'hidden' var burst = new mojs.Burst({ parent: parent.el, count: 10, top: n.barDom.getBoundingClientRect().height + 75, degree: 90, radius: 75, angle: { [-90]: 40 }, children: { fill: '#EBD761', delay: 'stagger(500, -50)', radius: 'rand(8, 25)', direction: -1, isSwirl: true } }) var fadeBurst = new mojs.Burst({ parent: parent.el, count: 2, degree: 0, angle: 75, radius: { 0: 100 }, top: '90%', children: { fill: '#EBD761', pathScale: [.65, 1], radius: 'rand(12, 15)', direction: [-1, 1], delay: .8 * 500, isSwirl: true } }) Timeline.add(body, burst, fadeBurst, parent) Timeline.play() } var mojsClose = function (promise) { var n = this new mojs.Html({ el: n.barDom, x: { 0: 500, delay: 10, duration: 500, easing: 'cubic.out' }, isForce3d: true, onComplete: function () { promise(function (resolve) { resolve() }) } }).play() } var bouncejsShow = function (promise) { var n = this new Bounce() .translate({ from: { x: 450, y: 0 }, to: { x: 0, y: 0 }, easing: 'bounce', duration: 1000, bounces: 4, stiffness: 3 }) .scale({ from: { x: 1.2, y: 1 }, to: { x: 1, y: 1 }, easing: 'bounce', duration: 1000, delay: 100, bounces: 4, stiffness: 1 }) .scale({ from: { x: 1, y: 1.2 }, to: { x: 1, y: 1 }, easing: 'bounce', duration: 1000, delay: 100, bounces: 6, stiffness: 1 }) .applyTo(n.barDom, { onComplete: function () { promise(function (resolve) { resolve() }) } }) } var bouncejsClose = function (promise) { var n = this new Bounce() .translate({ from: { x: 0, y: 0 }, to: { x: 450, y: 0 }, easing: 'bounce', duration: 500, bounces: 4, stiffness: 1 }) .applyTo(n.barDom, { onComplete: function () { promise(function (resolve) { resolve() }) } }) } $('body').on('click', '#example-runner', function (e) { new Noty({ text: '
I\'m an example notification. Hi!
', type: 'warning', theme: 'mint', layout: 'topRight', timeout: 4000, animation: { open: mojsShow, close: mojsClose } }).show() }) $('body').on('click', '#example-animatecss', function (e) { new Noty({ type: 'warning', text: 'NOTY - a Dependency-free notification library!', animation: { open: 'animated bounceInRight', // Animate.css class names close: 'animated bounceOutRight' // Animate.css class names } }).show(); }) $('body').on('click', '#example-bouncejs', function (e) { new Noty({ type: 'warning', text: 'NOTY - a Dependency-free notification library!', animation: { open: bouncejsShow, close: bouncejsClose } }).show(); }) $('body').on('click', '#example-mojs', function (e) { new Noty({ type: 'warning', text: 'NOTY - a Dependency-free notification library!', animation: { open: mojsShow, close: mojsClose } }).show(); }) $('body').on('click', '#example-velocity', function (e) { new Noty({ type: 'warning', text: 'NOTY - a Dependency-free notification library!', animation: { open: velocityShow, close: velocityClose } }).show(); }) setTimeout(function () { new Noty({ text: '
Wubba lubba dub dub! v3.1.3 released!
', type: 'information', theme: 'mint', layout: 'topRight', timeout: 4000, animation: { open: mojsShow, close: mojsClose } }).show() }, 2000) function RenderPreviews () { console.log("run") Noty.setMaxVisible(999999999); $themePreview = $(".theme-previews") $themePreviews = ["mint", "sunset", "relax", "nest", "metroui", "semanticui", "light", "bootstrap-v3", "bootstrap-v4"] if ($themePreview.length != 0) { $.each($themePreviews, function (i, theme) { $(".theme-preview-" + theme).append($("

" + theme + "

")) console.log(theme) generatePreview(theme, 'alert') generatePreview(theme, 'success') generatePreview(theme, 'warning') generatePreview(theme, 'error') generatePreview(theme, 'information') generatePreview(theme, 'confirm') }); function generatePreview (theme, type) { var notes = []; notes['alert'] = 'Best check yo self, you\'re not looking too good.'; notes['error'] = 'Change a few things up and try submitting again.'; notes['success'] = 'You successfully read this important alert message.'; notes['information'] = 'This alert needs your attention, but it\'s not super important.'; notes['warning'] = 'Warning!
Best check yo self, you\'re not looking too good.'; notes['confirm'] = 'Do you want to continue?'; new Noty({ text: notes[type], container: ".theme-preview-" + theme, type: type, theme: theme, dismissQueue: true, force: false, closeWith: [], buttons: (type != 'confirm') ? false : [ Noty.button('YES', 'btn btn-success', function () { console.log('button 1 clicked'); }), Noty.button('NO', 'btn btn-error', function () { console.log('button 2 clicked'); }) ] }).show() } } else { console.log("shit") } } ================================================ FILE: docs/_assets/docsify.js ================================================ (function () { 'use strict'; /** * Create a cached version of a pure function. */ function cached (fn) { var cache = Object.create(null); return function cachedFn (str) { var hit = cache[str]; return hit || (cache[str] = fn(str)) } } /** * Hyphenate a camelCase string. */ var hyphenate = cached(function (str) { return str.replace(/([A-Z])/g, function (m) { return '-' + m.toLowerCase(); }) }); /** * Simple Object.assign polyfill */ var merge = Object.assign || function (to) { var arguments$1 = arguments; var hasOwn = Object.prototype.hasOwnProperty; for (var i = 1; i < arguments.length; i++) { var from = Object(arguments$1[i]); for (var key in from) { if (hasOwn.call(from, key)) { to[key] = from[key]; } } } return to }; /** * Check if value is primitive */ function isPrimitive (value) { return typeof value === 'string' || typeof value === 'number' } /** * Perform no operation. */ function noop () {} /** * Check if value is function */ function isFn (obj) { return typeof obj === 'function' } var config = merge({ el: '#app', repo: '', maxLevel: 6, subMaxLevel: 0, loadSidebar: null, loadNavbar: null, homepage: 'README.md', coverpage: '', basePath: '', auto2top: false, name: '', themeColor: '', nameLink: window.location.pathname, autoHeader: false, executeScript: null, noEmoji: false, ga: '', mergeNavbar: false, formatUpdated: '', externalLinkTarget: '_blank', routerModel: 'hash', noCompileLinks: [] }, window.$docsify); var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')) .filter(function (n) { return /docsify\./.test(n.src); })[0]; if (script) { for (var prop in config) { var val = script.getAttribute('data-' + hyphenate(prop)); if (isPrimitive(val)) { config[prop] = val === '' ? true : val; } } if (config.loadSidebar === true) { config.loadSidebar = '_sidebar.md'; } if (config.loadNavbar === true) { config.loadNavbar = '_navbar.md'; } if (config.coverpage === true) { config.coverpage = '_coverpage.md'; } if (config.repo === true) { config.repo = ''; } if (config.name === true) { config.name = ''; } } window.$docsify = config; function initLifecycle (vm) { var hooks = [ 'init', 'mounted', 'beforeEach', 'afterEach', 'doneEach', 'ready' ]; vm._hooks = {}; vm._lifecycle = {}; hooks.forEach(function (hook) { var arr = vm._hooks[hook] = []; vm._lifecycle[hook] = function (fn) { return arr.push(fn); }; }); } function callHook (vm, hook, data, next) { if ( next === void 0 ) next = noop; var queue = vm._hooks[hook]; var step = function (index) { var hook = queue[index]; if (index >= queue.length) { next(data); } else { if (typeof hook === 'function') { if (hook.length === 2) { hook(data, function (result) { data = result; step(index + 1); }); } else { var result = hook(data); data = result !== undefined ? result : data; step(index + 1); } } else { step(index + 1); } } }; step(0); } var cacheNode = {}; /** * Get Node * @param {String|Element} el * @param {Boolean} noCache * @return {Element} */ function getNode (el, noCache) { if ( noCache === void 0 ) noCache = false; if (typeof el === 'string') { if (typeof window.Vue !== 'undefined') { return find(el) } el = noCache ? find(el) : (cacheNode[el] || (cacheNode[el] = find(el))); } return el } var $ = document; var body = $.body; var head = $.head; /** * Find element * @example * find('nav') => document.querySelector('nav') * find(nav, 'a') => nav.querySelector('a') */ function find (el, node) { return node ? el.querySelector(node) : $.querySelector(el) } /** * Find all elements * @example * findAll('a') => [].slice.call(document.querySelectorAll('a')) * findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a')) */ function findAll (el, node) { return [].slice.call(node ? el.querySelectorAll(node) : $.querySelectorAll(el)) } function create (node, tpl) { node = $.createElement(node); if (tpl) { node.innerHTML = tpl; } return node } function appendTo (target, el) { return target.appendChild(el) } function before (target, el) { return target.insertBefore(el, target.children[0]) } function on (el, type, handler) { isFn(type) ? window.addEventListener(el, type) : el.addEventListener(type, handler); } function off (el, type, handler) { isFn(type) ? window.removeEventListener(el, type) : el.removeEventListener(type, handler); } /** * Toggle class * * @example * toggleClass(el, 'active') => el.classList.toggle('active') * toggleClass(el, 'add', 'active') => el.classList.add('active') */ function toggleClass (el, type, val) { el && el.classList[val ? type : 'toggle'](val || type); } var dom = Object.freeze({ getNode: getNode, $: $, body: body, head: head, find: find, findAll: findAll, create: create, appendTo: appendTo, before: before, on: on, off: off, toggleClass: toggleClass }); var inBrowser = typeof window !== 'undefined'; var isMobile = inBrowser && document.body.clientWidth <= 600; /** * @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js */ var supportsPushState = inBrowser && (function () { // Borrowed wholesale from https://github.com/defunkt/jquery-pjax return window.history && window.history.pushState && window.history.replaceState && // pushState isn’t reliable on iOS until 5. !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/) })(); /** * Render github corner * @param {Object} data * @return {String} */ function corner (data) { if (!data) { return '' } if (!/\/\//.test(data)) { data = 'https://github.com/' + data; } data = data.replace(/^git\+/, ''); return ( "" + '' + '') } /** * Render main content */ function main (config) { var aside = ( '' + ''); return (isMobile ? (aside + "
") : ("
" + aside)) + '
' + '
' + '
' + '
' } /** * Cover Page */ function cover () { var SL = ', 100%, 85%'; var bgc = 'linear-gradient(to left bottom, ' + "hsl(" + (Math.floor(Math.random() * 255) + SL) + ") 0%," + "hsl(" + (Math.floor(Math.random() * 255) + SL) + ") 100%)"; return "
" + '
' + '
' + '
' } /** * Render tree * @param {Array} tree * @param {String} tpl * @return {String} */ function tree (toc, tpl) { if ( tpl === void 0 ) tpl = ''; if (!toc || !toc.length) { return '' } toc.forEach(function (node) { tpl += "
  • " + (node.title) + "
  • "; if (node.children) { tpl += "
    • " + (tree(node.children)) + "
    "; } }); return tpl } function helper (className, content) { return ("

    " + (content.slice(5).trim()) + "

    ") } function theme (color) { return ("") } var barEl; var timeId; /** * Init progress component */ function init () { var div = create('div'); div.classList.add('progress'); appendTo(body, div); barEl = div; } /** * Render progress bar */ var progressbar = function (ref) { var loaded = ref.loaded; var total = ref.total; var step = ref.step; var num; !barEl && init(); if (step) { num = parseInt(barEl.style.width || 0, 10) + step; num = num > 80 ? 80 : num; } else { num = Math.floor(loaded / total * 100); } barEl.style.opacity = 1; barEl.style.width = num >= 95 ? '100%' : num + '%'; if (num >= 95) { clearTimeout(timeId); timeId = setTimeout(function (_) { barEl.style.opacity = 0; barEl.style.width = '0%'; }, 200); } }; var cache = {}; /** * Simple ajax get * @param {string} url * @param {boolean} [hasBar=false] has progress bar * @return { then(resolve, reject), abort } */ function get (url, hasBar) { if ( hasBar === void 0 ) hasBar = false; var xhr = new XMLHttpRequest(); var on = function () { xhr.addEventListener.apply(xhr, arguments); }; var cached$$1 = cache[url]; if (cached$$1) { return { then: function (cb) { return cb(cached$$1.content, cached$$1.opt); }, abort: noop } } xhr.open('GET', url); xhr.send(); return { then: function (success, error) { if ( error === void 0 ) error = noop; if (hasBar) { var id = setInterval(function (_) { return progressbar({ step: Math.floor(Math.random() * 5 + 1) }); }, 500); on('progress', progressbar); on('loadend', function (evt) { progressbar(evt); clearInterval(id); }); } on('error', error); on('load', function (ref) { var target = ref.target; if (target.status >= 400) { error(target); } else { var result = cache[url] = { content: target.response, opt: { updatedAt: xhr.getResponseHeader('last-modified') } }; success(result.content, result.opt); } }); }, abort: function (_) { return xhr.readyState !== 4 && xhr.abort(); } } } function replaceVar (block, color) { block.innerHTML = block.innerHTML .replace(/var\(\s*--theme-color.*?\)/g, color); } var cssVars = function (color) { // Variable support if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) { return } var styleBlocks = findAll('style:not(.inserted),link');[].forEach.call(styleBlocks, function (block) { if (block.nodeName === 'STYLE') { replaceVar(block, color); } else if (block.nodeName === 'LINK') { var href = block.getAttribute('href'); if (!/\.css$/.test(href)) { return } get(href).then(function (res) { var style = create('style', res); head.appendChild(style); replaceVar(style, color); }); } }); }; var RGX = /([^{]*?)\w(?=\})/g; var dict = { YYYY: 'getFullYear', YY: 'getYear', MM: function (d) { return d.getMonth() + 1; }, DD: 'getDate', HH: 'getHours', mm: 'getMinutes', ss: 'getSeconds' }; var tinydate = function (str) { var parts=[], offset=0; str.replace(RGX, function (key, _, idx) { // save preceding string parts.push(str.substring(offset, idx - 1)); offset = idx += key.length + 1; // save function parts.push(function(d){ return ('00' + (typeof dict[key]==='string' ? d[dict[key]]() : dict[key](d))).slice(-key.length); }); }); if (offset !== str.length) { parts.push(str.substring(offset)); } return function (arg) { var out='', i=0, d=arg||new Date(); for (; i[^\n]+(\n(?!def)[^\n]+)*\n*)+/, list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/, def: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, table: noop, paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, text: /^[^\n]+/ }; block.bullet = /(?:[*+-]|\d+\.)/; block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; block.item = replace(block.item, 'gm') (/bull/g, block.bullet) (); block.list = replace(block.list) (/bull/g, block.bullet) ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))') ('def', '\\n+(?=' + block.def.source + ')') (); block.blockquote = replace(block.blockquote) ('def', block.def) (); block._tag = '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b'; block.html = replace(block.html) ('comment', //) ('closed', /<(tag)[\s\S]+?<\/\1>/) ('closing', /])*?>/) (/tag/g, block._tag) (); block.paragraph = replace(block.paragraph) ('hr', block.hr) ('heading', block.heading) ('lheading', block.lheading) ('blockquote', block.blockquote) ('tag', '<' + block._tag) ('def', block.def) (); /** * Normal Block Grammar */ block.normal = merge({}, block); /** * GFM Block Grammar */ block.gfm = merge({}, block.normal, { fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/, paragraph: /^/, heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/ }); block.gfm.paragraph = replace(block.paragraph) ('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|' + block.list.source.replace('\\1', '\\3') + '|') (); /** * GFM + Tables Block Grammar */ block.tables = merge({}, block.gfm, { nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ }); /** * Block Lexer */ function Lexer(options) { this.tokens = []; this.tokens.links = {}; this.options = options || marked.defaults; this.rules = block.normal; if (this.options.gfm) { if (this.options.tables) { this.rules = block.tables; } else { this.rules = block.gfm; } } } /** * Expose Block Rules */ Lexer.rules = block; /** * Static Lex Method */ Lexer.lex = function(src, options) { var lexer = new Lexer(options); return lexer.lex(src); }; /** * Preprocessing */ Lexer.prototype.lex = function(src) { src = src .replace(/\r\n|\r/g, '\n') .replace(/\t/g, ' ') .replace(/\u00a0/g, ' ') .replace(/\u2424/g, '\n'); return this.token(src, true); }; /** * Lexing */ Lexer.prototype.token = function(src, top, bq) { var this$1 = this; var src = src.replace(/^ +$/gm, '') , next , loose , cap , bull , b , item , space , i , l; while (src) { // newline if (cap = this$1.rules.newline.exec(src)) { src = src.substring(cap[0].length); if (cap[0].length > 1) { this$1.tokens.push({ type: 'space' }); } } // code if (cap = this$1.rules.code.exec(src)) { src = src.substring(cap[0].length); cap = cap[0].replace(/^ {4}/gm, ''); this$1.tokens.push({ type: 'code', text: !this$1.options.pedantic ? cap.replace(/\n+$/, '') : cap }); continue; } // fences (gfm) if (cap = this$1.rules.fences.exec(src)) { src = src.substring(cap[0].length); this$1.tokens.push({ type: 'code', lang: cap[2], text: cap[3] || '' }); continue; } // heading if (cap = this$1.rules.heading.exec(src)) { src = src.substring(cap[0].length); this$1.tokens.push({ type: 'heading', depth: cap[1].length, text: cap[2] }); continue; } // table no leading pipe (gfm) if (top && (cap = this$1.rules.nptable.exec(src))) { src = src.substring(cap[0].length); item = { type: 'table', header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), cells: cap[3].replace(/\n$/, '').split('\n') }; for (i = 0; i < item.align.length; i++) { if (/^ *-+: *$/.test(item.align[i])) { item.align[i] = 'right'; } else if (/^ *:-+: *$/.test(item.align[i])) { item.align[i] = 'center'; } else if (/^ *:-+ *$/.test(item.align[i])) { item.align[i] = 'left'; } else { item.align[i] = null; } } for (i = 0; i < item.cells.length; i++) { item.cells[i] = item.cells[i].split(/ *\| */); } this$1.tokens.push(item); continue; } // lheading if (cap = this$1.rules.lheading.exec(src)) { src = src.substring(cap[0].length); this$1.tokens.push({ type: 'heading', depth: cap[2] === '=' ? 1 : 2, text: cap[1] }); continue; } // hr if (cap = this$1.rules.hr.exec(src)) { src = src.substring(cap[0].length); this$1.tokens.push({ type: 'hr' }); continue; } // blockquote if (cap = this$1.rules.blockquote.exec(src)) { src = src.substring(cap[0].length); this$1.tokens.push({ type: 'blockquote_start' }); cap = cap[0].replace(/^ *> ?/gm, ''); // Pass `top` to keep the current // "toplevel" state. This is exactly // how markdown.pl works. this$1.token(cap, top, true); this$1.tokens.push({ type: 'blockquote_end' }); continue; } // list if (cap = this$1.rules.list.exec(src)) { src = src.substring(cap[0].length); bull = cap[2]; this$1.tokens.push({ type: 'list_start', ordered: bull.length > 1 }); // Get each top-level item. cap = cap[0].match(this$1.rules.item); next = false; l = cap.length; i = 0; for (; i < l; i++) { item = cap[i]; // Remove the list item's bullet // so it is seen as the next token. space = item.length; item = item.replace(/^ *([*+-]|\d+\.) +/, ''); // Outdent whatever the // list item contains. Hacky. if (~item.indexOf('\n ')) { space -= item.length; item = !this$1.options.pedantic ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') : item.replace(/^ {1,4}/gm, ''); } // Determine whether the next list item belongs here. // Backpedal if it does not belong in this list. if (this$1.options.smartLists && i !== l - 1) { b = block.bullet.exec(cap[i + 1])[0]; if (bull !== b && !(bull.length > 1 && b.length > 1)) { src = cap.slice(i + 1).join('\n') + src; i = l - 1; } } // Determine whether item is loose or not. // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ // for discount behavior. loose = next || /\n\n(?!\s*$)/.test(item); if (i !== l - 1) { next = item.charAt(item.length - 1) === '\n'; if (!loose) { loose = next; } } this$1.tokens.push({ type: loose ? 'loose_item_start' : 'list_item_start' }); // Recurse. this$1.token(item, false, bq); this$1.tokens.push({ type: 'list_item_end' }); } this$1.tokens.push({ type: 'list_end' }); continue; } // html if (cap = this$1.rules.html.exec(src)) { src = src.substring(cap[0].length); this$1.tokens.push({ type: this$1.options.sanitize ? 'paragraph' : 'html', pre: !this$1.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), text: cap[0] }); continue; } // def if ((!bq && top) && (cap = this$1.rules.def.exec(src))) { src = src.substring(cap[0].length); this$1.tokens.links[cap[1].toLowerCase()] = { href: cap[2], title: cap[3] }; continue; } // table (gfm) if (top && (cap = this$1.rules.table.exec(src))) { src = src.substring(cap[0].length); item = { type: 'table', header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') }; for (i = 0; i < item.align.length; i++) { if (/^ *-+: *$/.test(item.align[i])) { item.align[i] = 'right'; } else if (/^ *:-+: *$/.test(item.align[i])) { item.align[i] = 'center'; } else if (/^ *:-+ *$/.test(item.align[i])) { item.align[i] = 'left'; } else { item.align[i] = null; } } for (i = 0; i < item.cells.length; i++) { item.cells[i] = item.cells[i] .replace(/^ *\| *| *\| *$/g, '') .split(/ *\| */); } this$1.tokens.push(item); continue; } // top-level paragraph if (top && (cap = this$1.rules.paragraph.exec(src))) { src = src.substring(cap[0].length); this$1.tokens.push({ type: 'paragraph', text: cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1] }); continue; } // text if (cap = this$1.rules.text.exec(src)) { // Top-level should never reach here. src = src.substring(cap[0].length); this$1.tokens.push({ type: 'text', text: cap[0] }); continue; } if (src) { throw new Error('Infinite loop on byte: ' + src.charCodeAt(0)); } } return this.tokens; }; /** * Inline-Level Grammar */ var inline = { escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, url: noop, tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, link: /^!?\[(inside)\]\(href\)/, reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, br: /^ {2,}\n(?!\s*$)/, del: noop, text: /^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/; inline.link = replace(inline.link) ('inside', inline._inside) ('href', inline._href) (); inline.reflink = replace(inline.reflink) ('inside', inline._inside) (); /** * Normal Inline Grammar */ inline.normal = merge({}, inline); /** * Pedantic Inline Grammar */ inline.pedantic = merge({}, inline.normal, { strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ }); /** * GFM Inline Grammar */ inline.gfm = merge({}, inline.normal, { escape: replace(inline.escape)('])', '~|])')(), url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, del: /^~~(?=\S)([\s\S]*?\S)~~/, text: replace(inline.text) (']|', '~]|') ('|', '|https?://|') () }); /** * GFM + Line Breaks Inline Grammar */ inline.breaks = merge({}, inline.gfm, { br: replace(inline.br)('{2,}', '*')(), text: replace(inline.gfm.text)('{2,}', '*')() }); /** * Inline Lexer & Compiler */ function InlineLexer(links, options) { this.options = options || marked.defaults; this.links = links; this.rules = inline.normal; this.renderer = this.options.renderer || new Renderer; this.renderer.options = this.options; if (!this.links) { throw new Error('Tokens array requires a `links` property.'); } if (this.options.gfm) { if (this.options.breaks) { this.rules = inline.breaks; } else { this.rules = inline.gfm; } } else if (this.options.pedantic) { this.rules = inline.pedantic; } } /** * Expose Inline Rules */ InlineLexer.rules = inline; /** * Static Lexing/Compiling Method */ InlineLexer.output = function(src, links, options) { var inline = new InlineLexer(links, options); return inline.output(src); }; /** * Lexing/Compiling */ InlineLexer.prototype.output = function(src) { var this$1 = this; var out = '' , link , text , href , cap; while (src) { // escape if (cap = this$1.rules.escape.exec(src)) { src = src.substring(cap[0].length); out += cap[1]; continue; } // autolink if (cap = this$1.rules.autolink.exec(src)) { src = src.substring(cap[0].length); if (cap[2] === '@') { text = cap[1].charAt(6) === ':' ? this$1.mangle(cap[1].substring(7)) : this$1.mangle(cap[1]); href = this$1.mangle('mailto:') + text; } else { text = escape(cap[1]); href = text; } out += this$1.renderer.link(href, null, text); continue; } // url (gfm) if (!this$1.inLink && (cap = this$1.rules.url.exec(src))) { src = src.substring(cap[0].length); text = escape(cap[1]); href = text; out += this$1.renderer.link(href, null, text); continue; } // tag if (cap = this$1.rules.tag.exec(src)) { if (!this$1.inLink && /^/i.test(cap[0])) { this$1.inLink = false; } src = src.substring(cap[0].length); out += this$1.options.sanitize ? this$1.options.sanitizer ? this$1.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]; continue; } // link if (cap = this$1.rules.link.exec(src)) { src = src.substring(cap[0].length); this$1.inLink = true; out += this$1.outputLink(cap, { href: cap[2], title: cap[3] }); this$1.inLink = false; continue; } // reflink, nolink if ((cap = this$1.rules.reflink.exec(src)) || (cap = this$1.rules.nolink.exec(src))) { src = src.substring(cap[0].length); link = (cap[2] || cap[1]).replace(/\s+/g, ' '); link = this$1.links[link.toLowerCase()]; if (!link || !link.href) { out += cap[0].charAt(0); src = cap[0].substring(1) + src; continue; } this$1.inLink = true; out += this$1.outputLink(cap, link); this$1.inLink = false; continue; } // strong if (cap = this$1.rules.strong.exec(src)) { src = src.substring(cap[0].length); out += this$1.renderer.strong(this$1.output(cap[2] || cap[1])); continue; } // em if (cap = this$1.rules.em.exec(src)) { src = src.substring(cap[0].length); out += this$1.renderer.em(this$1.output(cap[2] || cap[1])); continue; } // code if (cap = this$1.rules.code.exec(src)) { src = src.substring(cap[0].length); out += this$1.renderer.codespan(escape(cap[2], true)); continue; } // br if (cap = this$1.rules.br.exec(src)) { src = src.substring(cap[0].length); out += this$1.renderer.br(); continue; } // del (gfm) if (cap = this$1.rules.del.exec(src)) { src = src.substring(cap[0].length); out += this$1.renderer.del(this$1.output(cap[1])); continue; } // text if (cap = this$1.rules.text.exec(src)) { src = src.substring(cap[0].length); out += this$1.renderer.text(escape(this$1.smartypants(cap[0]))); continue; } if (src) { throw new Error('Infinite loop on byte: ' + src.charCodeAt(0)); } } return out; }; /** * Compile Link */ InlineLexer.prototype.outputLink = function(cap, link) { var href = escape(link.href) , title = link.title ? escape(link.title) : null; return cap[0].charAt(0) !== '!' ? this.renderer.link(href, title, this.output(cap[1])) : this.renderer.image(href, title, escape(cap[1])); }; /** * Smartypants Transformations */ InlineLexer.prototype.smartypants = function(text) { if (!this.options.smartypants) { return text; } return text // em-dashes .replace(/---/g, '\u2014') // en-dashes .replace(/--/g, '\u2013') // opening singles .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') // closing singles & apostrophes .replace(/'/g, '\u2019') // opening doubles .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c') // closing doubles .replace(/"/g, '\u201d') // ellipses .replace(/\.{3}/g, '\u2026'); }; /** * Mangle Links */ InlineLexer.prototype.mangle = function(text) { if (!this.options.mangle) { return text; } var out = '' , l = text.length , i = 0 , ch; for (; i < l; i++) { ch = text.charCodeAt(i); if (Math.random() > 0.5) { ch = 'x' + ch.toString(16); } out += '&#' + ch + ';'; } return out; }; /** * Renderer */ function Renderer(options) { this.options = options || {}; } Renderer.prototype.code = function(code, lang, escaped) { if (this.options.highlight) { var out = this.options.highlight(code, lang); if (out != null && out !== code) { escaped = true; code = out; } } if (!lang) { return '
    '
          + (escaped ? code : escape(code, true))
          + '\n
    '; } return '
    '
        + (escaped ? code : escape(code, true))
        + '\n
    \n'; }; Renderer.prototype.blockquote = function(quote) { return '
    \n' + quote + '
    \n'; }; Renderer.prototype.html = function(html) { return html; }; Renderer.prototype.heading = function(text, level, raw) { return '' + text + '\n'; }; Renderer.prototype.hr = function() { return this.options.xhtml ? '
    \n' : '
    \n'; }; Renderer.prototype.list = function(body, ordered) { var type = ordered ? 'ol' : 'ul'; return '<' + type + '>\n' + body + '\n'; }; Renderer.prototype.listitem = function(text) { return '
  • ' + text + '
  • \n'; }; Renderer.prototype.paragraph = function(text) { return '

    ' + text + '

    \n'; }; Renderer.prototype.table = function(header, body) { return '\n' + '\n' + header + '\n' + '\n' + body + '\n' + '
    \n'; }; Renderer.prototype.tablerow = function(content) { return '\n' + content + '\n'; }; Renderer.prototype.tablecell = function(content, flags) { var type = flags.header ? 'th' : 'td'; var tag = flags.align ? '<' + type + ' style="text-align:' + flags.align + '">' : '<' + type + '>'; return tag + content + '\n'; }; // span level renderer Renderer.prototype.strong = function(text) { return '' + text + ''; }; Renderer.prototype.em = function(text) { return '' + text + ''; }; Renderer.prototype.codespan = function(text) { return '' + text + ''; }; Renderer.prototype.br = function() { return this.options.xhtml ? '
    ' : '
    '; }; Renderer.prototype.del = function(text) { return '' + text + ''; }; Renderer.prototype.link = function(href, title, text) { if (this.options.sanitize) { try { var prot = decodeURIComponent(unescape(href)) .replace(/[^\w:]/g, '') .toLowerCase(); } catch (e) { return ''; } if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) { return ''; } } var out = '
    '; return out; }; Renderer.prototype.image = function(href, title, text) { var out = '' + text + '' : '>'; return out; }; Renderer.prototype.text = function(text) { return text; }; /** * Parsing & Compiling */ function Parser(options) { this.tokens = []; this.token = null; this.options = options || marked.defaults; this.options.renderer = this.options.renderer || new Renderer; this.renderer = this.options.renderer; this.renderer.options = this.options; } /** * Static Parse Method */ Parser.parse = function(src, options, renderer) { var parser = new Parser(options, renderer); return parser.parse(src); }; /** * Parse Loop */ Parser.prototype.parse = function(src) { var this$1 = this; this.inline = new InlineLexer(src.links, this.options, this.renderer); this.tokens = src.reverse(); var out = ''; while (this.next()) { out += this$1.tok(); } return out; }; /** * Next Token */ Parser.prototype.next = function() { return this.token = this.tokens.pop(); }; /** * Preview Next Token */ Parser.prototype.peek = function() { return this.tokens[this.tokens.length - 1] || 0; }; /** * Parse Text Tokens */ Parser.prototype.parseText = function() { var this$1 = this; var body = this.token.text; while (this.peek().type === 'text') { body += '\n' + this$1.next().text; } return this.inline.output(body); }; /** * Parse Current Token */ Parser.prototype.tok = function() { var this$1 = this; switch (this.token.type) { case 'space': { return ''; } case 'hr': { return this.renderer.hr(); } case 'heading': { return this.renderer.heading( this.inline.output(this.token.text), this.token.depth, this.token.text); } case 'code': { return this.renderer.code(this.token.text, this.token.lang, this.token.escaped); } case 'table': { var header = '' , body = '' , i , row , cell , flags , j; // header cell = ''; for (i = 0; i < this.token.header.length; i++) { flags = { header: true, align: this$1.token.align[i] }; cell += this$1.renderer.tablecell( this$1.inline.output(this$1.token.header[i]), { header: true, align: this$1.token.align[i] } ); } header += this.renderer.tablerow(cell); for (i = 0; i < this.token.cells.length; i++) { row = this$1.token.cells[i]; cell = ''; for (j = 0; j < row.length; j++) { cell += this$1.renderer.tablecell( this$1.inline.output(row[j]), { header: false, align: this$1.token.align[j] } ); } body += this$1.renderer.tablerow(cell); } return this.renderer.table(header, body); } case 'blockquote_start': { var body = ''; while (this.next().type !== 'blockquote_end') { body += this$1.tok(); } return this.renderer.blockquote(body); } case 'list_start': { var body = '' , ordered = this.token.ordered; while (this.next().type !== 'list_end') { body += this$1.tok(); } return this.renderer.list(body, ordered); } case 'list_item_start': { var body = ''; while (this.next().type !== 'list_item_end') { body += this$1.token.type === 'text' ? this$1.parseText() : this$1.tok(); } return this.renderer.listitem(body); } case 'loose_item_start': { var body = ''; while (this.next().type !== 'list_item_end') { body += this$1.tok(); } return this.renderer.listitem(body); } case 'html': { var html = !this.token.pre && !this.options.pedantic ? this.inline.output(this.token.text) : this.token.text; return this.renderer.html(html); } case 'paragraph': { return this.renderer.paragraph(this.inline.output(this.token.text)); } case 'text': { return this.renderer.paragraph(this.parseText()); } } }; /** * Helpers */ function escape(html, encode) { return html .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function unescape(html) { // explicitly match decimal, hex, and named HTML entities return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) { n = n.toLowerCase(); if (n === 'colon') { return ':'; } if (n.charAt(0) === '#') { return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1)); } return ''; }); } function replace(regex, opt) { regex = regex.source; opt = opt || ''; return function self(name, val) { if (!name) { return new RegExp(regex, opt); } val = val.source || val; val = val.replace(/(^|[^\[])\^/g, '$1'); regex = regex.replace(name, val); return self; }; } function noop() {} noop.exec = noop; function merge(obj) { var arguments$1 = arguments; var i = 1 , target , key; for (; i < arguments.length; i++) { target = arguments$1[i]; for (key in target) { if (Object.prototype.hasOwnProperty.call(target, key)) { obj[key] = target[key]; } } } return obj; } /** * Marked */ function marked(src, opt, callback) { if (callback || typeof opt === 'function') { if (!callback) { callback = opt; opt = null; } opt = merge({}, marked.defaults, opt || {}); var highlight = opt.highlight , tokens , pending , i = 0; try { tokens = Lexer.lex(src, opt); } catch (e) { return callback(e); } pending = tokens.length; var done = function(err) { if (err) { opt.highlight = highlight; return callback(err); } var out; try { out = Parser.parse(tokens, opt); } catch (e) { err = e; } opt.highlight = highlight; return err ? callback(err) : callback(null, out); }; if (!highlight || highlight.length < 3) { return done(); } delete opt.highlight; if (!pending) { return done(); } for (; i < tokens.length; i++) { (function(token) { if (token.type !== 'code') { return --pending || done(); } return highlight(token.text, token.lang, function(err, code) { if (err) { return done(err); } if (code == null || code === token.text) { return --pending || done(); } token.text = code; token.escaped = true; --pending || done(); }); })(tokens[i]); } return; } try { if (opt) { opt = merge({}, marked.defaults, opt); } return Parser.parse(Lexer.lex(src, opt), opt); } catch (e) { e.message += '\nPlease report this to https://github.com/chjj/marked.'; if ((opt || marked.defaults).silent) { return '

    An error occured:

    '
            + escape(e.message + '', true)
            + '
    '; } throw e; } } /** * Options */ marked.options = marked.setOptions = function(opt) { merge(marked.defaults, opt); return marked; }; marked.defaults = { gfm: true, tables: true, breaks: false, pedantic: false, sanitize: false, sanitizer: null, mangle: true, smartLists: false, silent: false, highlight: null, langPrefix: 'lang-', smartypants: false, headerPrefix: '', renderer: new Renderer, xhtml: false }; /** * Expose */ marked.Parser = Parser; marked.parser = Parser.parse; marked.Renderer = Renderer; marked.Lexer = Lexer; marked.lexer = Lexer.lex; marked.InlineLexer = InlineLexer; marked.inlineLexer = InlineLexer.output; marked.parse = marked; { module.exports = marked; } }).call(function() { return this || (typeof window !== 'undefined' ? window : commonjsGlobal); }()); }); var prism = createCommonjsModule(function (module) { /* ********************************************** Begin prism-core.js ********************************************** */ var _self = (typeof window !== 'undefined') ? window // if in browser : ( (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) ? self // if in worker : {} // if in node js ); /** * Prism: Lightweight, robust, elegant syntax highlighting * MIT license http://www.opensource.org/licenses/mit-license.php/ * @author Lea Verou http://lea.verou.me */ var Prism = (function(){ // Private helper vars var lang = /\blang(?:uage)?-(\w+)\b/i; var uniqueId = 0; var _ = _self.Prism = { util: { encode: function (tokens) { if (tokens instanceof Token) { return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); } else if (_.util.type(tokens) === 'Array') { return tokens.map(_.util.encode); } else { return tokens.replace(/&/g, '&').replace(/ text.length) { // Something went terribly wrong, ABORT, ABORT! break tokenloop; } if (str instanceof Token) { continue; } pattern.lastIndex = 0; var match = pattern.exec(str), delNum = 1; // Greedy patterns can override/remove up to two previously matched tokens if (!match && greedy && i != strarr.length - 1) { pattern.lastIndex = pos; match = pattern.exec(text); if (!match) { break; } var from = match.index + (lookbehind ? match[1].length : 0), to = match.index + match[0].length, k = i, p = pos; for (var len = strarr.length; k < len && p < to; ++k) { p += strarr[k].length; // Move the index i to the element in strarr that is closest to from if (from >= p) { ++i; pos = p; } } /* * If strarr[i] is a Token, then the match starts inside another Token, which is invalid * If strarr[k - 1] is greedy we are in conflict with another greedy pattern */ if (strarr[i] instanceof Token || strarr[k - 1].greedy) { continue; } // Number of tokens to delete and replace with the new match delNum = k - i; str = text.slice(pos, p); match.index -= pos; } if (!match) { continue; } if(lookbehind) { lookbehindLength = match[1].length; } var from = match.index + lookbehindLength, match = match[0].slice(lookbehindLength), to = from + match.length, before = str.slice(0, from), after = str.slice(to); var args = [i, delNum]; if (before) { args.push(before); } var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); args.push(wrapped); if (after) { args.push(after); } Array.prototype.splice.apply(strarr, args); } } } return strarr; }, hooks: { all: {}, add: function (name, callback) { var hooks = _.hooks.all; hooks[name] = hooks[name] || []; hooks[name].push(callback); }, run: function (name, env) { var callbacks = _.hooks.all[name]; if (!callbacks || !callbacks.length) { return; } for (var i=0, callback; callback = callbacks[i++];) { callback(env); } } } }; var Token = _.Token = function(type, content, alias, matchedStr, greedy) { this.type = type; this.content = content; this.alias = alias; // Copy of the full string this token was created from this.length = (matchedStr || "").length|0; this.greedy = !!greedy; }; Token.stringify = function(o, language, parent) { if (typeof o == 'string') { return o; } if (_.util.type(o) === 'Array') { return o.map(function(element) { return Token.stringify(element, language, o); }).join(''); } var env = { type: o.type, content: Token.stringify(o.content, language, parent), tag: 'span', classes: ['token', o.type], attributes: {}, language: language, parent: parent }; if (env.type == 'comment') { env.attributes['spellcheck'] = 'true'; } if (o.alias) { var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; Array.prototype.push.apply(env.classes, aliases); } _.hooks.run('wrap', env); var attributes = Object.keys(env.attributes).map(function(name) { return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; }).join(' '); return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; }; if (!_self.document) { if (!_self.addEventListener) { // in Node.js return _self.Prism; } // In worker _self.addEventListener('message', function(evt) { var message = JSON.parse(evt.data), lang = message.language, code = message.code, immediateClose = message.immediateClose; _self.postMessage(_.highlight(code, _.languages[lang], lang)); if (immediateClose) { _self.close(); } }, false); return _self.Prism; } //Get current script and highlight var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); if (script) { _.filename = script.src; if (document.addEventListener && !script.hasAttribute('data-manual')) { if(document.readyState !== "loading") { if (window.requestAnimationFrame) { window.requestAnimationFrame(_.highlightAll); } else { window.setTimeout(_.highlightAll, 16); } } else { document.addEventListener('DOMContentLoaded', _.highlightAll); } } } return _self.Prism; })(); if ('object' !== 'undefined' && module.exports) { module.exports = Prism; } // hack for components to work correctly in node.js if (typeof commonjsGlobal !== 'undefined') { commonjsGlobal.Prism = Prism; } /* ********************************************** Begin prism-markup.js ********************************************** */ Prism.languages.markup = { 'comment': //, 'prolog': /<\?[\w\W]+?\?>/, 'doctype': //i, 'cdata': //i, 'tag': { pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, inside: { 'tag': { pattern: /^<\/?[^\s>\/]+/i, inside: { 'punctuation': /^<\/?/, 'namespace': /^[^\s>\/:]+:/ } }, 'attr-value': { pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, inside: { 'punctuation': /[=>"']/ } }, 'punctuation': /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { 'namespace': /^[^\s>\/:]+:/ } } } }, 'entity': /&#?[\da-z]{1,8};/i }; // Plugin to make entity title show the real entity, idea by Roman Komarov Prism.hooks.add('wrap', function(env) { if (env.type === 'entity') { env.attributes['title'] = env.content.replace(/&/, '&'); } }); Prism.languages.xml = Prism.languages.markup; Prism.languages.html = Prism.languages.markup; Prism.languages.mathml = Prism.languages.markup; Prism.languages.svg = Prism.languages.markup; /* ********************************************** Begin prism-css.js ********************************************** */ Prism.languages.css = { 'comment': /\/\*[\w\W]*?\*\//, 'atrule': { pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, inside: { 'rule': /@[\w-]+/ // See rest below } }, 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/, 'string': { pattern: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/, greedy: true }, 'property': /(\b|\B)[\w-]+(?=\s*:)/i, 'important': /\B!important\b/i, 'function': /[-a-z0-9]+(?=\()/i, 'punctuation': /[(){};:]/ }; Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css); if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'style': { pattern: /()[\w\W]*?(?=<\/style>)/i, lookbehind: true, inside: Prism.languages.css, alias: 'language-css' } }); Prism.languages.insertBefore('inside', 'attr-value', { 'style-attr': { pattern: /\s*style=("|').*?\1/i, inside: { 'attr-name': { pattern: /^\s*style/i, inside: Prism.languages.markup.tag.inside }, 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 'attr-value': { pattern: /.+/i, inside: Prism.languages.css } }, alias: 'language-css' } }, Prism.languages.markup.tag); } /* ********************************************** Begin prism-clike.js ********************************************** */ Prism.languages.clike = { 'comment': [ { pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, lookbehind: true }, { pattern: /(^|[^\\:])\/\/.*/, lookbehind: true } ], 'string': { pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, greedy: true }, 'class-name': { pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, lookbehind: true, inside: { punctuation: /(\.|\\)/ } }, 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, 'boolean': /\b(true|false)\b/, 'function': /[a-z0-9_]+(?=\()/i, 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, 'punctuation': /[{}[\];(),.:]/ }; /* ********************************************** Begin prism-javascript.js ********************************************** */ Prism.languages.javascript = Prism.languages.extend('clike', { 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i, 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/ }); Prism.languages.insertBefore('javascript', 'keyword', { 'regex': { pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, lookbehind: true, greedy: true } }); Prism.languages.insertBefore('javascript', 'string', { 'template-string': { pattern: /`(?:\\\\|\\?[^\\])*?`/, greedy: true, inside: { 'interpolation': { pattern: /\$\{[^}]+\}/, inside: { 'interpolation-punctuation': { pattern: /^\$\{|\}$/, alias: 'punctuation' }, rest: Prism.languages.javascript } }, 'string': /[\s\S]+/ } } }); if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'script': { pattern: /()[\w\W]*?(?=<\/script>)/i, lookbehind: true, inside: Prism.languages.javascript, alias: 'language-javascript' } }); } Prism.languages.js = Prism.languages.javascript; /* ********************************************** Begin prism-file-highlight.js ********************************************** */ (function () { if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) { return; } self.Prism.fileHighlight = function() { var Extensions = { 'js': 'javascript', 'py': 'python', 'rb': 'ruby', 'ps1': 'powershell', 'psm1': 'powershell', 'sh': 'bash', 'bat': 'batch', 'h': 'c', 'tex': 'latex' }; if(Array.prototype.forEach) { // Check to prevent error in IE8 Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) { var src = pre.getAttribute('data-src'); var language, parent = pre; var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; while (parent && !lang.test(parent.className)) { parent = parent.parentNode; } if (parent) { language = (pre.className.match(lang) || [, ''])[1]; } if (!language) { var extension = (src.match(/\.(\w+)$/) || [, ''])[1]; language = Extensions[extension] || extension; } var code = document.createElement('code'); code.className = 'language-' + language; pre.textContent = ''; code.textContent = 'Loading…'; pre.appendChild(code); var xhr = new XMLHttpRequest(); xhr.open('GET', src, true); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status < 400 && xhr.responseText) { code.textContent = xhr.responseText; Prism.highlightElement(code); } else if (xhr.status >= 400) { code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText; } else { code.textContent = '✖ Error: File does not exist or is empty'; } } }; xhr.send(null); }); } }; document.addEventListener('DOMContentLoaded', self.Prism.fileHighlight); })(); }); /** * gen toc tree * @link https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81 * @param {Array} toc * @param {Number} maxLevel * @return {Array} */ function genTree (toc, maxLevel) { var headlines = []; var last = {}; toc.forEach(function (headline) { var level = headline.level || 1; var len = level - 1; if (level > maxLevel) { return } if (last[len]) { last[len].children = (last[len].children || []).concat(headline); } else { headlines.push(headline); } last[level] = headline; }); return headlines } var cache$1 = {}; var re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,.\/:;<=>?@\[\]^`{|}~]/g; function slugify (str) { if (typeof str !== 'string') { return '' } var slug = str.toLowerCase().trim() .replace(/<[^>\d]+>/g, '') .replace(re, '') .replace(/\s/g, '-') .replace(/-+/g, '-') .replace(/^(\d)/, '_$1'); var count = cache$1[slug]; count = cache$1.hasOwnProperty(slug) ? (count + 1) : 0; cache$1[slug] = count; if (count) { slug = slug + '-' + count; } return slug } slugify.clear = function () { cache$1 = {}; }; function replace (m, $1) { return '' + $1 + '' } function emojify (text) { return text .replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, function (m) { return m.replace(/:/g, '__colon__'); }) .replace(/:(\w+?):/ig, (inBrowser && window.emojify) || replace) .replace(/__colon__/g, ':') } var decode = decodeURIComponent; var encode = encodeURIComponent; function parseQuery (query) { var res = {}; query = query.trim().replace(/^(\?|#|&)/, ''); if (!query) { return res } // Simple parse query.split('&').forEach(function (param) { var parts = param.replace(/\+/g, ' ').split('='); res[parts[0]] = parts[1] && decode(parts[1]); }); return res } function stringifyQuery (obj) { var qs = []; for (var key in obj) { qs.push(obj[key] ? ((encode(key)) + "=" + (encode(obj[key]))).toLowerCase() : encode(key)); } return qs.length ? ("?" + (qs.join('&'))) : '' } function getPath () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return cleanPath(args.join('/')) } var isAbsolutePath = cached(function (path) { return /(:|(\/{2}))/g.test(path) }); var getParentPath = cached(function (path) { return /\/$/g.test(path) ? path : (path = path.match(/(\S*\/)[^\/]+$/)) ? path[1] : '' }); var cleanPath = cached(function (path) { return path .replace(/^\/+/, '/') .replace(/([^:])\/{2,}/g, '$1/') }); var cachedLinks = {}; var Compiler = function Compiler (config, router) { this.config = config; this.router = router; this.cacheTree = {}; this.toc = []; this.linkTarget = config.externalLinkTarget || '_blank'; this.contentBase = router.getBasePath(); var renderer = this._initRenderer(); var compile; var mdConf = config.markdown || {}; if (isFn(mdConf)) { compile = mdConf(marked, renderer); } else { marked.setOptions(merge(mdConf, { renderer: merge(renderer, mdConf.renderer) })); compile = marked; } this.compile = cached(function (text) { var html = ''; if (!text) { return text } html = compile(text); html = config.noEmoji ? html : emojify(html); slugify.clear(); return html }); }; Compiler.prototype.matchNotCompileLink = function matchNotCompileLink (link) { var links = this.config.noCompileLinks; for (var i = 0; i < links.length; i++) { var n = links[i]; var re = cachedLinks[n] || (cachedLinks[n] = new RegExp(("^" + n + "$"))); if (re.test(link)) { return link } } }; Compiler.prototype._initRenderer = function _initRenderer () { var renderer = new marked.Renderer(); var ref = this; var linkTarget = ref.linkTarget; var router = ref.router; var contentBase = ref.contentBase; var _self = this; /** * render anchor tag * @link https://github.com/chjj/marked#overriding-renderer-methods */ renderer.heading = function (text, level) { var nextToc = { level: level, title: text }; if (/{docsify-ignore}/g.test(text)) { text = text.replace('{docsify-ignore}', ''); nextToc.title = text; nextToc.ignoreSubHeading = true; } if (/{docsify-ignore-all}/g.test(text)) { text = text.replace('{docsify-ignore-all}', ''); nextToc.title = text; nextToc.ignoreAllSubs = true; } var slug = slugify(text); var url = router.toURL(router.getCurrentPath(), { id: slug }); nextToc.slug = url; _self.toc.push(nextToc); return ("
    " + text + "") }; // highlight code renderer.code = function (code, lang) { if ( lang === void 0 ) lang = ''; var hl = prism.highlight(code, prism.languages[lang] || prism.languages.markup); return ("
    " + hl + "
    ") }; renderer.link = function (href, title, text) { var blank = ''; if (!/:|(\/{2})/.test(href) && !_self.matchNotCompileLink(href) && !/(\s?:ignore)(\s\S+)?$/.test(title)) { href = router.toURL(href, null, router.getCurrentPath()); } else { blank = " target=\"" + linkTarget + "\""; title = title && title.replace(/:ignore/g, '').trim(); } if (title) { title = " title=\"" + title + "\""; } return ("" + text + "") }; renderer.paragraph = function (text) { if (/^!>/.test(text)) { return helper('tip', text) } else if (/^\?>/.test(text)) { return helper('warn', text) } return ("

    " + text + "

    ") }; renderer.image = function (href, title, text) { var url = href; var titleHTML = title ? (" title=\"" + title + "\"") : ''; if (!isAbsolutePath(href)) { url = getPath(contentBase, href); } return ("\""") }; return renderer }; /** * Compile sidebar */ Compiler.prototype.sidebar = function sidebar (text, level) { var currentPath = this.router.getCurrentPath(); var html = ''; if (text) { html = this.compile(text); // html = html && html.match(/]*>([\s\S]+)<\/ul>/g)[0]; } else { var tree$$1 = this.cacheTree[currentPath] || genTree(this.toc, level); html = tree(tree$$1, '
      '); this.cacheTree[currentPath] = tree$$1; } return html }; /** * Compile sub sidebar */ Compiler.prototype.subSidebar = function subSidebar (level) { if (!level) { this.toc = []; return } var currentPath = this.router.getCurrentPath(); var ref = this; var cacheTree = ref.cacheTree; var toc = ref.toc; toc[0] && toc[0].ignoreAllSubs && (this.toc = []); toc[0] && toc[0].level === 1 && toc.shift(); toc.forEach(function (node, i) { node.ignoreSubHeading && toc.splice(i, 1); }); var tree$$1 = cacheTree[currentPath] || genTree(toc, level); cacheTree[currentPath] = tree$$1; this.toc = []; return tree(tree$$1, '
        ') }; Compiler.prototype.article = function article (text) { return this.compile(text) }; /** * Compile cover page */ Compiler.prototype.cover = function cover$$1 (text) { var cacheToc = this.toc.slice(); var html = this.compile(text); this.toc = cacheToc.slice(); return html }; var title = $.title; /** * Toggle button */ function btn (el, router) { var toggle = function (_) { return body.classList.toggle('close'); }; el = getNode(el); on(el, 'click', function (e) { e.stopPropagation(); toggle(); }); var sidebar = getNode('.sidebar'); isMobile && on(body, 'click', function (_) { return body.classList.contains('close') && toggle(); } ); on(sidebar, 'click', function (_) { return setTimeout((function (_) { return getAndActive(router, sidebar, true, true); }, 0)); } ); } function sticky () { var cover = getNode('section.cover'); if (!cover) { return } var coverHeight = cover.getBoundingClientRect().height; if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) { toggleClass(body, 'add', 'sticky'); } else { toggleClass(body, 'remove', 'sticky'); } } /** * Get and active link * @param {object} router * @param {string|element} el * @param {Boolean} isParent acitve parent * @param {Boolean} autoTitle auto set title * @return {element} */ function getAndActive (router, el, isParent, autoTitle) { el = getNode(el); var links = findAll(el, 'a'); var hash = router.toURL(router.getCurrentPath()); var target; links .sort(function (a, b) { return b.href.length - a.href.length; }) .forEach(function (a) { var href = a.getAttribute('href'); var node = isParent ? a.parentNode : a; if (hash.indexOf(href) === 0 && !target) { target = a; toggleClass(node, 'add', 'active'); } else { toggleClass(node, 'remove', 'active'); } }); if (autoTitle) { $.title = target ? ((target.innerText) + " - " + title) : title; } return target } var nav = {}; var hoverOver = false; function highlight () { var sidebar = getNode('.sidebar'); var anchors = findAll('.anchor'); var wrap = find(sidebar, '.sidebar-nav'); var active = find(sidebar, 'li.active'); var top = body.scrollTop; var last; for (var i = 0, len = anchors.length; i < len; i += 1) { var node = anchors[i]; if (node.offsetTop > top) { if (!last) { last = node; } break } else { last = node; } } if (!last) { return } var li = nav[last.getAttribute('data-id')]; if (!li || li === active) { return } active && active.classList.remove('active'); li.classList.add('active'); active = li; // scroll into view // https://github.com/vuejs/vuejs.org/blob/master/themes/vue/source/js/common.js#L282-L297 if (!hoverOver && body.classList.contains('sticky')) { var height = sidebar.clientHeight; var curOffset = 0; var cur = active.offsetTop + active.clientHeight + 40; var isInView = ( active.offsetTop >= wrap.scrollTop && cur <= wrap.scrollTop + height ); var notThan = cur - curOffset < height; var top$1 = isInView ? wrap.scrollTop : notThan ? curOffset : cur - height; sidebar.scrollTop = top$1; } } function scrollActiveSidebar (router) { if (isMobile) { return } var sidebar = getNode('.sidebar'); var lis = findAll(sidebar, 'li'); for (var i = 0, len = lis.length; i < len; i += 1) { var li = lis[i]; var a = li.querySelector('a'); if (!a) { continue } var href = a.getAttribute('href'); if (href !== '/') { href = router.parse(href).query.id; } nav[decodeURIComponent(href)] = li; } off('scroll', highlight); on('scroll', highlight); on(sidebar, 'mouseover', function () { hoverOver = true; }); on(sidebar, 'mouseleave', function () { hoverOver = false; }); } function scrollIntoView (id) { var section = find('#' + id); section && section.scrollIntoView(); } var scrollEl = $.scrollingElement || $.documentElement; function scroll2Top (offset) { if ( offset === void 0 ) offset = 0; scrollEl.scrollTop = offset === true ? 0 : Number(offset); } function executeScript () { var script = findAll('.markdown-section>script') .filter(function (s) { return !/template/.test(s.type); })[0]; if (!script) { return false } var code = script.innerText.trim(); if (!code) { return false } setTimeout(function (_) { window.__EXECUTE_RESULT__ = new Function(code)(); }, 0); } function formatUpdated (html, updated, fn) { updated = typeof fn === 'function' ? fn(updated) : typeof fn === 'string' ? tinydate(fn)(new Date(updated)) : updated; return html.replace(/{docsify-updated}/g, updated) } function renderMain (html) { if (!html) { // TODO: Custom 404 page html = 'not found'; } this._renderTo('.markdown-section', html); // Render sidebar with the TOC !this.config.loadSidebar && this._renderSidebar(); // execute script if (this.config.executeScript !== false && typeof window.Vue !== 'undefined' && !executeScript()) { setTimeout(function (_) { var vueVM = window.__EXECUTE_RESULT__; vueVM && vueVM.$destroy && vueVM.$destroy(); window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main'); }, 0); } else { this.config.executeScript && executeScript(); } } function renderNameLink (vm) { var el = getNode('.app-name-link'); var nameLink = vm.config.nameLink; var path = vm.route.path; if (!el) { return } if (isPrimitive(vm.config.nameLink)) { el.setAttribute('href', nameLink); } else if (typeof nameLink === 'object') { var match = Object.keys(nameLink).filter(function (key) { return path.indexOf(key) > -1; })[0]; el.setAttribute('href', nameLink[match]); } } function renderMixin (proto) { proto._renderTo = function (el, content, replace) { var node = getNode(el); if (node) { node[replace ? 'outerHTML' : 'innerHTML'] = content; } }; proto._renderSidebar = function (text) { var ref = this.config; var maxLevel = ref.maxLevel; var subMaxLevel = ref.subMaxLevel; var loadSidebar = ref.loadSidebar; this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel)); var activeEl = getAndActive(this.router, '.sidebar-nav', true, true); if (loadSidebar && activeEl) { activeEl.parentNode.innerHTML += (this.compiler.subSidebar(subMaxLevel) || ''); } else { // reset toc this.compiler.subSidebar(); } // bind event this._bindEventOnRendered(activeEl); }; proto._bindEventOnRendered = function (activeEl) { var ref = this.config; var autoHeader = ref.autoHeader; var auto2top = ref.auto2top; scrollActiveSidebar(this.router); if (autoHeader && activeEl) { var main$$1 = getNode('#main'); var firstNode = main$$1.children[0]; if (firstNode && firstNode.tagName !== 'H1') { var h1 = create('h1'); h1.innerText = activeEl.innerText; before(main$$1, h1); } } auto2top && scroll2Top(auto2top); }; proto._renderNav = function (text) { text && this._renderTo('nav', this.compiler.compile(text)); getAndActive(this.router, 'nav'); }; proto._renderMain = function (text, opt) { var this$1 = this; if ( opt === void 0 ) opt = {}; if (!text) { return renderMain.call(this, text) } callHook(this, 'beforeEach', text, function (result) { var html = this$1.isHTML ? result : this$1.compiler.compile(result); if (opt.updatedAt) { html = formatUpdated(html, opt.updatedAt, this$1.config.formatUpdated); } callHook(this$1, 'afterEach', html, function (text) { return renderMain.call(this$1, text); }); }); }; proto._renderCover = function (text) { var el = getNode('.cover'); if (!text) { toggleClass(el, 'remove', 'show'); return } toggleClass(el, 'add', 'show'); var html = this.coverIsHTML ? text : this.compiler.cover(text); var m = html.trim().match('

        ([^<]*?)

        $'); if (m) { if (m[2] === 'color') { el.style.background = m[1] + (m[3] || ''); } else { var path = m[1]; toggleClass(el, 'add', 'has-mask'); if (!isAbsolutePath(m[1])) { path = getPath(this.router.getBasePath(), m[1]); } el.style.backgroundImage = "url(" + path + ")"; el.style.backgroundSize = 'cover'; el.style.backgroundPosition = 'center center'; } html = html.replace(m[0], ''); } this._renderTo('.cover-main', html); sticky(); }; proto._updateRender = function () { // render name link renderNameLink(this); }; } function initRender (vm) { var config = vm.config; // Init markdown compiler vm.compiler = new Compiler(config, vm.router); var id = config.el || '#app'; var navEl = find('nav') || create('nav'); var el = find(id); var html = ''; var navAppendToTarget = body; if (el) { if (config.repo) { html += corner(config.repo); } if (config.coverpage) { html += cover(); } html += main(config); // Render main app vm._renderTo(el, html, true); } else { vm.rendered = true; } if (config.mergeNavbar && isMobile) { navAppendToTarget = find('.sidebar'); } else { navEl.classList.add('app-nav'); if (!config.repo) { navEl.classList.add('no-badge'); } } // Add nav before(navAppendToTarget, navEl); if (config.themeColor) { $.head.appendChild( create('div', theme(config.themeColor)).firstElementChild ); // Polyfll cssVars(config.themeColor); } vm._updateRender(); toggleClass(body, 'ready'); } var cached$1 = {}; function getAlias (path, alias, last) { var match = Object.keys(alias).filter(function (key) { var re = cached$1[key] || (cached$1[key] = new RegExp(("^" + key + "$"))); return re.test(path) && path !== last })[0]; return match ? getAlias(path.replace(cached$1[match], alias[match]), alias, path) : path } function getFileName (path) { return /\.(md|html)$/g.test(path) ? path : /\/$/g.test(path) ? (path + "README.md") : (path + ".md") } var History = function History (config) { this.config = config; }; History.prototype.getBasePath = function getBasePath () { return this.config.basePath }; History.prototype.getFile = function getFile (path, isRelative) { path = path || this.getCurrentPath(); var ref = this; var config = ref.config; var base = this.getBasePath(); path = config.alias ? getAlias(path, config.alias) : path; path = getFileName(path); path = path === '/README.md' ? (config.homepage || path) : path; path = isAbsolutePath(path) ? path : getPath(base, path); if (isRelative) { path = path.replace(new RegExp(("^" + base)), ''); } return path }; History.prototype.onchange = function onchange (cb) { if ( cb === void 0 ) cb = noop; cb(); }; History.prototype.getCurrentPath = function getCurrentPath () {}; History.prototype.normalize = function normalize () {}; History.prototype.parse = function parse () {}; History.prototype.toURL = function toURL () {}; function replaceHash (path) { var i = location.href.indexOf('#'); location.replace( location.href.slice(0, i >= 0 ? i : 0) + '#' + path ); } var replaceSlug = cached(function (path) { return path.replace('#', '?id=') }); var HashHistory = (function (History$$1) { function HashHistory (config) { History$$1.call(this, config); this.mode = 'hash'; } if ( History$$1 ) HashHistory.__proto__ = History$$1; HashHistory.prototype = Object.create( History$$1 && History$$1.prototype ); HashHistory.prototype.constructor = HashHistory; HashHistory.prototype.getBasePath = function getBasePath () { var path = window.location.pathname || ''; var base = this.config.basePath; return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base) }; HashHistory.prototype.getCurrentPath = function getCurrentPath () { // We can't use location.hash here because it's not // consistent across browsers - Firefox will pre-decode it! var href = location.href; var index = href.indexOf('#'); return index === -1 ? '' : href.slice(index + 1) }; HashHistory.prototype.onchange = function onchange (cb) { if ( cb === void 0 ) cb = noop; on('hashchange', cb); }; HashHistory.prototype.normalize = function normalize () { var path = this.getCurrentPath(); path = replaceSlug(path); if (path.charAt(0) === '/') { return replaceHash(path) } replaceHash('/' + path); }; /** * Parse the url * @param {string} [path=location.herf] * @return {object} { path, query } */ HashHistory.prototype.parse = function parse (path) { if ( path === void 0 ) path = location.href; var query = ''; var hashIndex = path.indexOf('#'); if (hashIndex) { path = path.slice(hashIndex + 1); } var queryIndex = path.indexOf('?'); if (queryIndex >= 0) { query = path.slice(queryIndex + 1); path = path.slice(0, queryIndex); } return { path: path, file: this.getFile(path, true), query: parseQuery(query) } }; HashHistory.prototype.toURL = function toURL (path, params, currentRoute) { var local = currentRoute && path[0] === '#'; var route = this.parse(replaceSlug(path)); route.query = merge({}, route.query, params); path = route.path + stringifyQuery(route.query); path = path.replace(/\.md(\?)|\.md$/, '$1'); if (local) { path = currentRoute + path; } return cleanPath('#/' + path) }; return HashHistory; }(History)); var HTML5History = (function (History$$1) { function HTML5History (config) { History$$1.call(this, config); this.mode = 'history'; } if ( History$$1 ) HTML5History.__proto__ = History$$1; HTML5History.prototype = Object.create( History$$1 && History$$1.prototype ); HTML5History.prototype.constructor = HTML5History; HTML5History.prototype.getCurrentPath = function getCurrentPath () { var base = this.getBasePath(); var path = window.location.pathname; if (base && path.indexOf(base) === 0) { path = path.slice(base.length); } return (path || '/') + window.location.search + window.location.hash }; HTML5History.prototype.onchange = function onchange (cb) { if ( cb === void 0 ) cb = noop; on('click', function (e) { var el = e.target.tagName === 'A' ? e.target : e.target.parentNode; if (el.tagName === 'A' && !/_blank/.test(el.target)) { e.preventDefault(); var url = el.href; window.history.pushState({ key: url }, '', url); cb(); } }); on('popstate', cb); }; /** * Parse the url * @param {string} [path=location.href] * @return {object} { path, query } */ HTML5History.prototype.parse = function parse (path) { if ( path === void 0 ) path = location.href; var query = ''; var queryIndex = path.indexOf('?'); if (queryIndex >= 0) { query = path.slice(queryIndex + 1); path = path.slice(0, queryIndex); } var base = getPath(location.origin); var baseIndex = path.indexOf(base); if (baseIndex > -1) { path = path.slice(baseIndex + base.length); } return { path: path, file: this.getFile(path), query: parseQuery(query) } }; HTML5History.prototype.toURL = function toURL (path, params, currentRoute) { var local = currentRoute && path[0] === '#'; var route = this.parse(path); route.query = merge({}, route.query, params); path = route.path + stringifyQuery(route.query); path = path.replace(/\.md(\?)|\.md$/, '$1'); if (local) { path = currentRoute + path; } return cleanPath('/' + path) }; return HTML5History; }(History)); function routerMixin (proto) { proto.route = {}; } var lastRoute = {}; function updateRender (vm) { vm.router.normalize(); vm.route = vm.router.parse(); body.setAttribute('data-page', vm.route.file); } function initRouter (vm) { var config = vm.config; var mode = config.routerMode || 'hash'; var router; if (mode === 'history' && supportsPushState) { router = new HTML5History(config); } else { router = new HashHistory(config); } vm.router = router; updateRender(vm); lastRoute = vm.route; router.onchange(function (_) { updateRender(vm); vm._updateRender(); if (lastRoute.path === vm.route.path) { vm.$resetEvents(); return } vm.$fetch(); lastRoute = vm.route; }); } function eventMixin (proto) { proto.$resetEvents = function () { scrollIntoView(this.route.query.id); getAndActive(this.router, 'nav'); }; } function initEvent (vm) { // Bind toggle button btn('button.sidebar-toggle', vm.router); // Bind sticky effect if (vm.config.coverpage) { !isMobile && on('scroll', sticky); } else { body.classList.add('sticky'); } } function loadNested (path, file, next, vm, first) { path = first ? path : path.replace(/\/$/, ''); path = getParentPath(path); if (!path) { return } get(vm.router.getFile(path + file)) .then(next, function (_) { return loadNested(path, file, next, vm); }); } function fetchMixin (proto) { var last; proto._fetch = function (cb) { var this$1 = this; if ( cb === void 0 ) cb = noop; var ref = this.route; var path = ref.path; var ref$1 = this.config; var loadNavbar = ref$1.loadNavbar; var loadSidebar = ref$1.loadSidebar; // Abort last request last && last.abort && last.abort(); last = get(this.router.getFile(path), true); // Current page is html this.isHTML = /\.html$/g.test(path); var loadSideAndNav = function () { if (!loadSidebar) { return cb() } var fn = function (result) { this$1._renderSidebar(result); cb(); }; // Load sidebar loadNested(path, loadSidebar, fn, this$1, true); }; // Load main content last.then(function (text, opt) { this$1._renderMain(text, opt); loadSideAndNav(); }, function (_) { this$1._renderMain(null); loadSideAndNav(); }); // Load nav loadNavbar && loadNested(path, loadNavbar, function (text) { return this$1._renderNav(text); }, this, true); }; proto._fetchCover = function () { var this$1 = this; var ref = this.config; var coverpage = ref.coverpage; var root = getParentPath(this.route.path); var path = this.router.getFile(root + coverpage); if (this.route.path !== '/' || !coverpage) { this._renderCover(); return } this.coverIsHTML = /\.html$/g.test(path); get(path) .then(function (text) { return this$1._renderCover(text); }); }; proto.$fetch = function (cb) { var this$1 = this; if ( cb === void 0 ) cb = noop; this._fetchCover(); this._fetch(function (result) { this$1.$resetEvents(); callHook(this$1, 'doneEach'); cb(); }); }; } function initFetch (vm) { var ref = vm.config; var loadSidebar = ref.loadSidebar; // server-client renderer if (vm.rendered) { var activeEl = getAndActive(vm.router, '.sidebar-nav', true, true); if (loadSidebar && activeEl) { activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__; } vm._bindEventOnRendered(activeEl); vm._fetchCover(); vm.$resetEvents(); callHook(vm, 'doneEach'); callHook(vm, 'ready'); } else { vm.$fetch(function (_) { return callHook(vm, 'ready'); }); } } function initMixin (proto) { proto._init = function () { var vm = this; vm.config = config || {}; initLifecycle(vm); // Init hooks initPlugin(vm); // Install plugins callHook(vm, 'init'); initRouter(vm); // Add router initRender(vm); // Render base DOM initEvent(vm); // Bind events initFetch(vm); // Fetch data callHook(vm, 'mounted'); }; } function initPlugin (vm) { [].concat(vm.config.plugins).forEach(function (fn) { return isFn(fn) && fn(vm._lifecycle, vm); }); } var util = Object.freeze({ cached: cached, hyphenate: hyphenate, merge: merge, isPrimitive: isPrimitive, noop: noop, isFn: isFn, inBrowser: inBrowser, isMobile: isMobile, supportsPushState: supportsPushState, parseQuery: parseQuery, stringifyQuery: stringifyQuery, getPath: getPath, isAbsolutePath: isAbsolutePath, getParentPath: getParentPath, cleanPath: cleanPath }); var initGlobalAPI = function () { window.Docsify = { util: util, dom: dom, get: get, slugify: slugify }; window.DocsifyCompiler = Compiler; window.marked = marked; window.Prism = prism; }; function Docsify () { this._init(); } var proto = Docsify.prototype; initMixin(proto); routerMixin(proto); renderMixin(proto); fetchMixin(proto); eventMixin(proto); /** * Global API */ initGlobalAPI(); /** * Version */ Docsify.version = '4.2.4'; /** * Run Docsify */ setTimeout(function (_) { return new Docsify(); }, 0); }()); ================================================ FILE: docs/_assets/vue.css ================================================ * { -webkit-font-smoothing: antialiased; -webkit-overflow-scrolling: touch; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-text-size-adjust: none; -webkit-touch-callout: none; box-sizing: border-box } body:not(.ready) { overflow: hidden } body:not(.ready) .app-nav, body:not(.ready) > nav, body:not(.ready) [data-cloak] { display: none } div#app { font-size: 30px; font-weight: lighter; margin: 40vh auto; text-align: center } div#app:empty:before { content: "Loading..." } .emoji { height: 19.2px; height: 1.2rem; vertical-align: middle } .progress { background-color: #42b983; background-color: var(--theme-color, #42b983); height: 2px; left: 0; position: fixed; right: 0; top: 0; transition: width .2s, opacity .4s; width: 0; z-index: 5 } .search .search-keyword, .search a:hover { color: #42b983; color: var(--theme-color, #42b983) } .search .search-keyword { font-style: normal } body, html { height: 100% } body { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; color: #34495e; font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; font-size: 15px; letter-spacing: 0; margin: 0; overflow-x: hidden } img { max-width: 100% } kbd { border: 1px solid #ccc; border-radius: 3px; display: inline-block; font-size: 12px !important; line-height: 12px; margin-bottom: 3px; padding: 3px 5px; vertical-align: middle } .app-nav { left: 0; margin: 25px 60px 0 0; position: absolute; right: 0; text-align: right; z-index: 2 } .app-nav p { margin: 0 } .app-nav > a { margin: 0 16px; margin: 0 1rem; padding: 5px 0 } .app-nav li, .app-nav ul { display: inline-block; list-style: none; margin: 0 } .app-nav a { color: inherit; font-size: 16px; text-decoration: none; transition: color .3s } .app-nav a.active, .app-nav a:hover { color: #42b983; color: var(--theme-color, #42b983) } .app-nav a.active { border-bottom: 2px solid #42b983; border-bottom: 2px solid var(--theme-color, #42b983) } .app-nav li { display: inline-block; margin: 0 16px; margin: 0 1rem; padding: 5px 0; position: relative } .app-nav li ul { background-color: #fff; border: 1px solid #ddd; border-bottom-color: #ccc; border-radius: 4px; box-sizing: border-box; display: none; max-height: calc(100vh - 61px); overflow-y: scroll; padding: 10px 0; position: absolute; right: -15px; text-align: left; top: 100%; white-space: nowrap } .app-nav li ul li { display: block; font-size: 14px; line-height: 16px; line-height: 1rem; margin: 0; margin: 8px 14px; white-space: nowrap } .app-nav li ul a { display: block; font-size: inherit; margin: 0; padding: 0 } .app-nav li ul a.active { border-bottom: 0 } .app-nav li:hover ul { display: block } .app-nav.no-badge { margin-right: 25px } .github-corner { border-bottom: 0; position: fixed; right: 0; text-decoration: none; top: 0; z-index: 1 } .github-corner svg { color: #fff; fill: #42b983; fill: var(--theme-color, #42b983); height: 80px; width: 80px } .github-corner:hover .octo-arm { -webkit-animation: a .56s ease-in-out; animation: a .56s ease-in-out } main { display: block; position: relative; width: 100vw; height: 100% } .anchor { display: inline-block; text-decoration: none; transition: all .3s } .anchor span { color: #34495e } .anchor:hover { text-decoration: underline } .sidebar { border-right: 1px solid rgba(0, 0, 0, .07); overflow-y: auto; padding: 40px 0; top: 0; bottom: 0; left: 0; position: absolute; transition: -webkit-transform .25s ease-out; transition: transform .25s ease-out; transition: transform .25s ease-out, -webkit-transform .25s ease-out; width: 300px; z-index: 3 } .sidebar > h1 { margin: 0 auto 16px; margin: 0 auto 1rem; font-size: 24px; font-size: 1.5rem; font-weight: 300; text-align: center } .sidebar > h1 a { color: inherit; text-decoration: none } .sidebar > h1 .app-nav { display: block; position: static } .sidebar .sidebar-nav { line-height: 2em } .sidebar ul { margin: 0; padding: 0 } .sidebar li > p { font-weight: 700; margin: 0 } .sidebar ul, .sidebar ul li { list-style: none } .sidebar ul li a { border-bottom: none; display: block } .sidebar ul li ul { padding-left: 20px } .sidebar::-webkit-scrollbar { width: 4px } .sidebar::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px } .sidebar:hover::-webkit-scrollbar-thumb { background: hsla(0, 0%, 53%, .4) } .sidebar:hover::-webkit-scrollbar-track { background: hsla(0, 0%, 53%, .1) } .sidebar-toggle { background-color: transparent; background-color: hsla(0, 0%, 100%, .8); border: 0; outline: none; padding: 10px; bottom: 0; left: 0; position: absolute; text-align: center; transition: opacity .3s; width: 30px; width: 284px; z-index: 4 } .sidebar-toggle .sidebar-toggle-button:hover { opacity: .4 } .sidebar-toggle span { background-color: #42b983; background-color: var(--theme-color, #42b983); display: block; margin-bottom: 4px; width: 16px; height: 2px } body.sticky .sidebar, body.sticky .sidebar-toggle { position: fixed } .content { padding-top: 20px; top: 0; right: 0; bottom: 0; left: 300px; position: absolute; transition: left .25s ease } .markdown-section { margin: 0 auto; max-width: 800px; padding: 30px 15px 40px; position: relative } .markdown-section > * { box-sizing: border-box; font-size: inherit } .markdown-section > :first-child { margin-top: 0 !important } .markdown-section hr { border: none; border-bottom: 1px solid #eee; margin: 2em 0 } .markdown-section table { border-collapse: collapse; border-spacing: 0; display: block; margin-bottom: 16px; margin-bottom: 1rem; overflow: auto; width: 100% } .markdown-section th { font-weight: 700 } .markdown-section td, .markdown-section th { border: 1px solid #ddd; padding: 6px 13px } .markdown-section tr { border-top: 1px solid #ccc } .markdown-section p.tip, .markdown-section tr:nth-child(2n) { background-color: #f8f8f8 } .markdown-section p.tip { border-bottom-right-radius: 2px; border-left: 4px solid #f66; border-top-right-radius: 2px; margin: 2em 0; padding: 12px 24px 12px 30px; position: relative } .markdown-section p.tip code { background-color: #efefef } .markdown-section p.tip em { color: #34495e } .markdown-section p.tip:before { background-color: #f66; border-radius: 100%; color: #fff; content: "!"; font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; font-size: 14px; font-weight: 700; left: -12px; line-height: 20px; position: absolute; width: 20px; height: 20px; text-align: center; top: 14px } .markdown-section p.warn { background: rgba(66, 185, 131, .1); border-radius: 2px; padding: 16px; padding: 1rem } body.close .sidebar { -webkit-transform: translateX(-300px); transform: translateX(-300px) } body.close .sidebar-toggle { width: auto } body.close .content { left: 0 } @media print { .app-nav, .github-corner, .sidebar, .sidebar-toggle { display: none } } @media screen and (max-width: 768px) { .github-corner, .sidebar, .sidebar-toggle { position: fixed } .app-nav { margin-top: 16px } .app-nav li ul { top: 30px } main { height: auto; overflow-x: hidden } .sidebar { left: -300px; transition: -webkit-transform .25s ease-out; transition: transform .25s ease-out; transition: transform .25s ease-out, -webkit-transform .25s ease-out } .content { left: 0; max-width: 100vw; position: static; transition: -webkit-transform .25s ease; transition: transform .25s ease; transition: transform .25s ease, -webkit-transform .25s ease } .app-nav, .github-corner { transition: -webkit-transform .25s ease-out; transition: transform .25s ease-out; transition: transform .25s ease-out, -webkit-transform .25s ease-out } .sidebar-toggle { background-color: transparent; width: auto } body.close .sidebar { -webkit-transform: translateX(300px); transform: translateX(300px) } body.close .sidebar-toggle { background-color: hsla(0, 0%, 100%, .8); transition: background-color 1s; width: 284px } body.close .content { -webkit-transform: translateX(300px); transform: translateX(300px) } body.close .app-nav, body.close .github-corner { display: none } .github-corner .octo-arm { -webkit-animation: a .56s ease-in-out; animation: a .56s ease-in-out } .github-corner:hover .octo-arm { -webkit-animation: none; animation: none } } @-webkit-keyframes a { 0%, to { -webkit-transform: rotate(0); transform: rotate(0) } 20%, 60% { -webkit-transform: rotate(-25deg); transform: rotate(-25deg) } 40%, 80% { -webkit-transform: rotate(10deg); transform: rotate(10deg) } } @keyframes a { 0%, to { -webkit-transform: rotate(0); transform: rotate(0) } 20%, 60% { -webkit-transform: rotate(-25deg); transform: rotate(-25deg) } 40%, 80% { -webkit-transform: rotate(10deg); transform: rotate(10deg) } } section.cover { -webkit-box-align: center; -ms-flex-align: center; align-items: center; background-position: 50%; background-repeat: no-repeat; background-size: cover; height: 100vh; display: none } section.cover .cover-main { -webkit-box-flex: 1; -ms-flex: 1; flex: 1; margin: -20px 16px 0; text-align: center; z-index: 1 } section.cover a { color: inherit } section.cover a, section.cover a:hover { text-decoration: none } section.cover p { line-height: 24px; line-height: 1.5rem; margin: 1em 0 } section.cover h1 { color: inherit; font-size: 40px; font-size: 2.5rem; font-weight: 300; margin: 10px 0 40px; margin: .625rem 0 2.5rem; position: relative; text-align: center } section.cover h1 a { display: block } section.cover h1 small { bottom: -7px; bottom: -.4375rem; font-size: 16px; font-size: 1rem; position: absolute } section.cover blockquote { font-size: 24px; font-size: 1.5rem; text-align: center } section.cover ul { line-height: 1.8; list-style-type: none; margin: 1em auto; max-width: 500px; padding: 0 } section.cover .cover-main > p:last-child a { border-color: #42b983; border: 1px solid var(--theme-color, #42b983); border-radius: 2rem; box-sizing: border-box; color: #42b983; color: var(--theme-color, #42b983); display: inline-block; font-size: 16.8px; font-size: 1.05rem; letter-spacing: 1.6px; letter-spacing: .1rem; margin-right: 16px; margin-right: 1rem; padding: .75em 32px; padding: .75em 2rem; text-decoration: none; transition: all .15s ease } section.cover .cover-main > p:last-child a:last-child { background-color: #42b983; background-color: var(--theme-color, #42b983); color: #fff; margin-right: 0 } section.cover .cover-main > p:last-child a:last-child:hover { color: inherit; opacity: .8 } section.cover .cover-main > p:last-child a:hover { color: inherit } section.cover blockquote > p > a { border-bottom: 2px solid #42b983; border-bottom: 2px solid var(--theme-color, #42b983); transition: color .3s } section.cover blockquote > p > a:hover { color: #42b983; color: var(--theme-color, #42b983) } section.cover.show { display: -webkit-box; display: -ms-flexbox; display: flex } section.cover.has-mask .mask { background-color: #fff; opacity: .8; position: absolute; width: 100%; height: 100% } .sidebar, body { background-color: #fff } .sidebar { color: #364149 } .sidebar li { margin: 6px 0 6px 15px } .sidebar ul li a { color: #505d6b; font-size: 14px; font-weight: 400; overflow: hidden; text-decoration: none; text-overflow: ellipsis; white-space: nowrap } .sidebar ul li a:hover { text-decoration: underline } .sidebar ul li ul { padding: 0 } .sidebar ul li.active > a { border-right: 2px solid; color: #42b983; color: var(--theme-color, #42b983); font-weight: 600 } .app-sub-sidebar .section-link:before { content: "-"; padding-right: 4px } .markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section strong { color: #2c3e50; font-weight: 600 } .markdown-section a { color: #42b983; color: var(--theme-color, #42b983); font-weight: 600 } .markdown-section h1 { font-size: 32px; font-size: 2rem; margin: 0 0 16px; margin: 0 0 1rem } .markdown-section h2 { font-size: 28px; font-size: 1.75rem; margin: 45px 0 12.8px; margin: 45px 0 .8rem } .markdown-section h3 { font-size: 24px; font-size: 1.5rem; margin: 40px 0 9.6px; margin: 40px 0 .6rem } .markdown-section h4 { font-size: 20px; font-size: 1.25rem } .markdown-section h5, .markdown-section h6 { font-size: 16px; font-size: 1rem } .markdown-section h6 { color: #777 } .markdown-section figure, .markdown-section ol, .markdown-section p, .markdown-section ul { margin: 1.2em 0 } .markdown-section ol, .markdown-section p, .markdown-section ul { line-height: 25.6px; line-height: 1.6rem; word-spacing: .8px; word-spacing: .05rem } .markdown-section ol, .markdown-section ul { padding-left: 24px; padding-left: 1.5rem } .markdown-section blockquote { border-left: 4px solid #42b983; border-left: 4px solid var(--theme-color, #42b983); color: #858585; margin: 2em 0; padding-left: 20px } .markdown-section blockquote p { font-weight: 600; margin-left: 0 } .markdown-section iframe { margin: 1em 0 } .markdown-section em { color: #7f8c8d } .markdown-section code { border-radius: 2px; color: #e96900; font-size: 12.8px; font-size: .8rem; margin: 0 2px; padding: 3px 5px; white-space: nowrap } .markdown-section code, .markdown-section pre { background-color: #f8f8f8; font-family: Roboto Mono, Monaco, courier, monospace } .markdown-section pre { -moz-osx-font-smoothing: initial; -webkit-font-smoothing: initial; line-height: 24px; line-height: 1.5rem; margin: 1.2em 0; overflow: auto; padding: 0 22.4px; padding: 0 1.4rem; position: relative; word-wrap: normal } .token.cdata, .token.comment, .token.doctype, .token.prolog { color: #8e908c } .token.namespace { opacity: .7 } .token.boolean, .token.number { color: #c76b29 } .token.punctuation { color: #525252 } .token.property { color: #c08b30 } .token.tag { color: #2973b7 } .token.string { color: #42b983; color: var(--theme-color, #42b983) } .token.selector { color: #6679cc } .token.attr-name { color: #2973b7 } .language-css .token.string, .style .token.string, .token.entity, .token.url { color: #22a2c9 } .token.attr-value, .token.control, .token.directive, .token.unit { color: #42b983; color: var(--theme-color, #42b983) } .token.keyword { color: #e96900 } .token.atrule, .token.regex, .token.statement { color: #22a2c9 } .token.placeholder, .token.variable { color: #3d8fd1 } .token.deleted { text-decoration: line-through } .token.inserted { border-bottom: 1px dotted #202746; text-decoration: none } .token.italic { font-style: italic } .token.bold, .token.important { font-weight: 700 } .token.important { color: #c94922 } .token.entity { cursor: help } .markdown-section pre > code { -moz-osx-font-smoothing: initial; -webkit-font-smoothing: initial; background-color: #f8f8f8; border-radius: 2px; color: #525252; display: block; font-family: Roboto Mono, Monaco, courier, monospace; font-size: 12.8px; font-size: .8rem; line-height: inherit; margin: 0 2px; max-width: inherit; overflow: inherit; padding: 2.2em 5px; white-space: inherit } .markdown-section code:after, .markdown-section code:before { letter-spacing: .8px; letter-spacing: .05rem } code .token { -moz-osx-font-smoothing: initial; -webkit-font-smoothing: initial; min-height: 24px; min-height: 1.5rem } pre:after { color: #ccc; content: attr(data-lang); font-size: 9.6px; font-size: .6rem; font-weight: 600; height: 15px; line-height: 15px; padding: 5px 10px 0; position: absolute; right: 0; text-align: right; top: 0 } .flex-grid-thirds { margin-bottom: 100px; display: flex; justify-content: space-between; } .flex-grid-thirds .col { width: 32%; } ================================================ FILE: docs/_navbar.md ================================================ - Translations - [English](/) ================================================ FILE: docs/_sidebar.md ================================================

        Become a Sponsor

        - [
        Home](/) - [
        Installation](installation.md) - [
        Options & Defaults](options.md) - [
        Types & Layouts](types.md) - [
        Themes](themes.md) - [
        Show & Hide Animations](animations.md) - [
        Web Push Notifications](push.md) - [
        Confirm Dialogs](confirm.md) - [
        API & Callbacks](api.md) - [
        Browser Support](browsers.md) - [
        Bakers](bakers.md) ================================================ FILE: docs/animations.md ================================================ ### CSS Animations Using with class names. (like animate.css) ```javascript new Noty({ text: 'NOTY - a dependency-free notification library!', animation: { open: 'animated bounceInRight', // Animate.css class names close: 'animated bounceOutRight' // Animate.css class names } }).show(); ```

        Example css animation; ```css .noty_effects_open { opacity: 0; transform: translate(50%); animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); } .noty_effects_close { animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); } @keyframes noty_anim_in { 100% { transform: translate(0); opacity: 1; } } @keyframes noty_anim_out { 100% { transform: translate(50%); opacity: 0; } } ``` !> **JavaScript animations** are deprecated! But you can use 3rd party animation libraries. #### Other cool ways ### Animating with bounce.js > Get [bounce.js](http://bouncejs.com/?ref=notyjs), first. Then; ```javascript new Noty({ ... text: 'NOTY - animating with Bounce.js!', ... animation: { open: function (promise) { var n = this; new Bounce() .translate({ from : {x: 450, y: 0}, to: {x: 0, y: 0}, easing : "bounce", duration : 1000, bounces : 4, stiffness: 3 }) .scale({ from : {x: 1.2, y: 1}, to: {x: 1, y: 1}, easing : "bounce", duration : 1000, delay : 100, bounces : 4, stiffness: 1 }) .scale({ from : {x: 1, y: 1.2}, to: {x: 1, y: 1}, easing : "bounce", duration : 1000, delay : 100, bounces : 6, stiffness: 1 }) .applyTo(n.barDom, { onComplete: function () { promise(function(resolve) { resolve(); }) } }); }, close: function (promise) { var n = this; new Bounce() .translate({ from : {x: 0, y: 0}, to: {x: 450, y: 0}, easing : "bounce", duration : 500, bounces : 4, stiffness: 1 }) .applyTo(n.barDom, { onComplete: function () { promise(function(resolve) { resolve(); }) } }); } } }).show(); ```

        !> **Important**: You need to resolve promises for this type of usage. ### Animating with mo.js > Get [mo.js](https://mojs.github.io/), first. Then; ```javascript new Noty({ ... text: 'NOTY - animating with Mo.js!', ... animation: { open: function (promise) { var n = this; var Timeline = new mojs.Timeline(); var body = new mojs.Html({ el : n.barDom, x : {500: 0, delay: 0, duration: 500, easing: 'elastic.out'}, isForce3d : true, onComplete: function () { promise(function(resolve) { resolve(); }) } }); var parent = new mojs.Shape({ parent: n.barDom, width : 200, height : n.barDom.getBoundingClientRect().height, radius : 0, x : {[150]: -150}, duration : 1.2 * 500, isShowStart: true }); n.barDom.style['overflow'] = 'visible'; parent.el.style['overflow'] = 'hidden'; var burst = new mojs.Burst({ parent : parent.el, count : 10, top : n.barDom.getBoundingClientRect().height + 75, degree : 90, radius : 75, angle : {[-90]: 40}, children: { fill : '#EBD761', delay : 'stagger(500, -50)', radius : 'rand(8, 25)', direction: -1, isSwirl : true } }); var fadeBurst = new mojs.Burst({ parent : parent.el, count : 2, degree : 0, angle : 75, radius : {0: 100}, top : '90%', children: { fill : '#EBD761', pathScale: [.65, 1], radius : 'rand(12, 15)', direction: [-1, 1], delay : .8 * 500, isSwirl : true } }); Timeline.add(body, burst, fadeBurst, parent); Timeline.play(); }, close: function (promise) { var n = this; new mojs.Html({ el : n.barDom, x : {0: 500, delay: 10, duration: 500, easing: 'cubic.out'}, skewY : {0: 10, delay: 10, duration: 500, easing: 'cubic.out'}, isForce3d : true, onComplete: function () { promise(function(resolve) { resolve(); }) } }).play(); } } }).show(); ```

        !> **Important**: You need to resolve promises for this type of usage. ### Animating with velocity > Get [velocity](http://velocityjs.org/?ref=notyjs), first. Then; ```javascript new Noty({ ... text: 'NOTY - animating with velocity!', ... animation: { open: function (promise) { var n = this; Velocity(n.barDom, { left: 450, scaleY: 2 }, { duration: 0 }); Velocity(n.barDom, { left: 0, scaleY: 1 }, { easing: [ 8, 8 ], complete: function() { promise(function(resolve) { resolve(); }) } }); }, close: function (promise) { var n = this; Velocity(n.barDom, { left: '+=-50' }, { easing: [ 8, 8, 2], duration: 350 }); Velocity(n.barDom, { left: 450, scaleY: .2, height: 0, margin: 0 }, { easing: [ 8, 8 ], complete: function () { promise(function(resolve) { resolve(); }) } }); } } }).show(); ```

        !> **Important**: You need to resolve promises for this type of usage. ================================================ FILE: docs/api.md ================================================ ### API Methods ```javascript var n = new Noty({text: 'Hi!'}); console.log(n); // Returns a NOTY javascript object n.show(); // Show a NOTY n.close(); // Close a NOTY n.setText('Hi again!'); // Notification text updater. Important: .noty_body class is required for setText API method. n.setType('error'); // Notification type updater n.setTheme('newTheme'); // Notification theme updater n.setTimeout(4500); // false (clears timeout) or integer (clears timer, starts for given value) n.stop(); // Clears the timeout n.resume(); // Restarts the timeout ``` > **setText()**, **setType()** and **setTheme()** methods doesn't override NOTY's options.
        If you wanna override those values pass a second parameter as boolean **true**. ### API Static Methods ```javascript Noty.closeAll(); // Closes all notifications Noty.closeAll('myCustomQueueName'); // Closes all notifications with queue named 'myCustomQueueName' Noty.setMaxVisible(10); // Sets the maxVisible notification count for global queue; Noty.setMaxVisible(10, 'myCustomQueueName'); // Sets the maxVisible notification count for 'myCustomQueueName' queue; ``` > Default **maxVisible** value is **5** for all queues. ### Callbacks ```javascript new Noty({ ... callbacks: { beforeShow: function() {}, onShow: function() {}, afterShow: function() {}, onClose: function() {}, afterClose: function() {}, onHover: function() {}, onTemplate: function() { this.barDom.innerHTML = '
        ' + this.options.text + '
        '; // Important: .noty_body class is required for setText API method. } } ... }).show(); ``` ### Callbacks Alternative Usage ```javascript new Noty({ ... }).on('onShow', function() { ... }).on('afterShow', function() { ... }).show(); // Important: You need to call on() methods before the show() method. ``` ### Custom Templating !> Custom templating is possible with **onTemplate** callback. > **Suggestion**: You can also use a template library as an alternative. ================================================ FILE: docs/bakers.md ================================================ # Support my Projects Hi! Noty.js and [my other libraries](https://github.com/needim) are MIT licensed open source projects and they are completely free to use. However, the amount of effort needed to maintain and develop new features for these projects is not sustainable without proper financial backing. You can support my works by pledging on Patreon (recurring, with perks for different tiers). Patreon logo Become a Sponsor or Baker! ## Current Sponsors !> **$30 or more per month**
        I'll put your logo on all my project's websites & GitHub readme pages. (for the period of subscription) (**30k+ unique pageviews**) ## Current Bakers - Your name - Your name - ... !> **$1 or more per month**
        I'll put your name on all my project's websites bakers page & GitHub repo bakers.md. (for the period of subscription) ================================================ FILE: docs/browsers.md ================================================ !> This data is provided by BrowserStack Automate #### Local run 2017 07 27T17:31:03.314Z | OS | Browser | Result | Details | | --- | --- | --- | --- | | Windows 10 | opera 46.0 | done | [view](https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/c259644238854e4628696d8cfea9482b96a78a07?auth_token=f87c9cb1ab62bb7b85af973cc2a1b03bd9d35fbc6a9e38b716fe38b01c4c3480) | | Windows 10 | chrome 59.0 | done | [view](https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/dc87007925cb5729ac8aa2a6136aab1fb6808cc1?auth_token=04d2d0b39bcdbb76153ee28e3acf67099ecbd9a093c6176df9ad892c083663c6) | | OS X El Capitan | safari 9.1 | done | [view](https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/0c60211cab5840456ac824443e3be99b195597b5?auth_token=9daf8b81531fe858108d9d76317b171c7dca69dee3ac3a25e065810fd353b837) | | Windows 10 | firefox 54.0 | done | [view](https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/336cf3a8db5363d7683f01392d4d328fce18838a?auth_token=e93ad65f77003c53f0e7392f2bbd38d56811d1d6ce4e1f9f098494caa240ef21) | | Windows 10 | edge 15.0 | done | [view](https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/a2bb1f252f478c5b5cd4fdc06158830305120ea2?auth_token=c75ad2904602c489145eaf2ce18b8f5723a843cb6c8dcc62a60982dc6109ef27) | | Windows 8 | ie 10.0 | done | [view](https://www.browserstack.com/automate/builds/7d2483377687d162b9bc20fcaf3cb1bfb8f5bec0/sessions/d85b895f81c51f9cd5c72c225c9f155b331902c6?auth_token=bd85550ce628686d6485062a32cc869abf2dcb7a2b9862b3884ebc7d4283d344) | ================================================ FILE: docs/confirm.md ================================================ We can set button objects with an array like below; ```javascript var n = new Noty({ text: 'Do you want to continue? ', buttons: [ Noty.button('YES', 'btn btn-success', function () { console.log('button 1 clicked'); }, {id: 'button1', 'data-status': 'ok'}), Noty.button('NO', 'btn btn-error', function () { console.log('button 2 clicked'); n.close(); }) ] }); n.show(); ``` ?> **Noty.button**(**text**:string, **classNames**:string, **cb**:function, **attributes**:object); !> **About button styling**: Noty doesn't care about that. You need to pass class names with your styles. ================================================ FILE: docs/index.html ================================================ NOTY - a dependency-free notification library
        ================================================ FILE: docs/installation.md ================================================ Include **lib/noty.css** & **lib/noty.js** or use Bower, NPM, Yarn or Composer ```html ``` !> NOTY v3 **is NOT dependent to jQuery** anymore. ### Install via Bower ```bash $ bower install noty ``` ### Install via NPM ```bash $ npm install noty ``` ### Install via Yarn ```bash $ yarn add noty ``` ### Install via Composer ```bash $ composer require needim/noty ``` #### For the Laravel Add to `resources/assets/sass/app.scss` ```scss @import "~noty/src/noty.scss"; @import "~noty/src/themes/mint.scss"; ``` Add to `resources/assets/js/bootstrap.js` ```javascript window.Noty = require('noty'); ``` Then run `yarn dev` or `npm run dev` ### Usage: Creating a Notification ```javascript new Noty({ ... text: 'Some notification text', ... }).show(); ``` ### ES6 import & Require Usages ```javascript import Noty from 'noty'; new Noty({ ... text: 'Some notification text', ... }).show(); const Noty = require('noty'); new Noty({ ... text: 'Some notification text', ... }).show(); ``` ### RequireJS !> While defining path for Noty you should write "Noty" with capital letter of N. ```javascript requirejs.config({ paths: { "Noty": "libs/noty.min", ... }, ... ``` ================================================ FILE: docs/options.md ================================================ Creating a notification; ```javascript new Noty({ ... text: 'Some notification text', ... }).show(); ``` Available options listed below. | Option | Default | Info | | --- | --- | --- | | **type**: string | 'alert' | alert, success, error, warning, info - ClassName generator uses this value → `noty_type__${type}` | | **layout**: string | 'topRight' | top, topLeft, topCenter, topRight, center, centerLeft, centerRight, bottom, bottomLeft, bottomCenter, bottomRight - ClassName generator uses this value → `noty_layout__${layout}` | | **theme**: string | 'mint' | relax, mint, metroui - ClassName generator uses this value → `noty_theme__${theme}` | | **text**: string | '' | This string can contain HTML too. But be careful and don't pass user inputs to this parameter. | | **timeout**: boolean,int | false | false, 1000, 3000, 3500, etc. Delay for closing event in milliseconds (ms). Set 'false' for sticky notifications. | | **progressBar**: boolean | true | true, false - Displays a progress bar if timeout is not false. | | **closeWith**: [...string] | ['click'] | click, button | | **animation.open**: string,null,function | 'noty_effects_open' | If **string**, assumed to be CSS class name. If **null**, no animation at all. If **function**, runs the function. (v3.0.1+) You can use animate.css class names or your custom css animations as well. | | **animation.close**: string,null,function | 'noty_effects_close' | If **string**, assumed to be CSS class name. If **null**, no animation at all. If **function**, runs the function. (v3.0.1+) You can use animate.css class names or your custom css animations as well. | | **sounds.sources**: [...string] | [] | **v3.1.0-beta** Array of audio sources e.g 'some.wav' [Check browser support](http://caniuse.com/#search=audio) | | **sounds.volume**: int | 1 | **v3.1.0-beta** Integer value between 0-1 e.g 0.5 [Check browser support](http://caniuse.com/#search=audio) | | **sounds.conditions**: [...string] | [] | **v3.1.0-beta** There are two conditions for now: **'docVisible'** & **'docHidden'**. You can use one of them or both. [Check browser support](http://caniuse.com/#search=audio) | | **docTitle.conditions**: [...string] | [] | **v3.1.0-beta** There are two conditions for now: **'docVisible'** & **'docHidden'**. You can use one of them or both. | | **modal**: boolean | false | **v3.1.0-beta** Behaves like v2 but more stable | | **id**: string,boolean | false | You can use this id with querySelectors. Generated automatically if false. | | **force**: boolean | false | DOM insert method depends on this parameter. If false uses append, if true uses prepend. | | **queue**: string | 'global' | NEW Named queue system. Details are [here](api.md). | | **killer**: boolean,string | false | If true closes all **visible** notifications and shows itself. If string(queueName) closes all **visible** notification on this queue and shows itself. | | **container**: boolean,string | false | Custom container selector string. Like '.my-custom-container'. Layout parameter will be ignored. | | **buttons**: [...Noty.button] | [] | An array of Noty.button, for creating confirmation dialogs. Details are [here](confirm.md). | | **callbacks.beforeShow**: function | Default: () => {} | Details are [here](api.md). | | **callbacks.onShow**: function | Default: () => {} | Details are [here](api.md). | | **callbacks.afterShow**: function | Default: () => {} | Details are [here](api.md). | | **callbacks.onClose**: function | Default: () => {} | Details are [here](api.md). | | **callbacks.afterClose**: function | Default: () => {} | Details are [here](api.md). | | **callbacks.onHover**: function | Default: () => {} | Details are [here](api.md). | | **callbacks.onClick**: function | Default: () => {} | Only works if `closeWith` = `['click']`. Details are [here](api.md). | | **callbacks.onTemplate**: function | Default: () => {} | Mainly for DOM manipulations. Details are [here](api.md). | | **visibilityControl**: boolean | false | If **true** Noty uses PageVisibility API to handle timeout. To ensure that users do not miss their notifications. | [See a detailed example on Jsfiddle.](https://jsfiddle.net/znyh891t/) ### Overriding Options Of course, you can override default values; ```javascript Noty.overrideDefaults({ layout : 'topRight', theme : 'mint', closeWith: ['click', 'button'], animation: { open : 'animated fadeInRight', close: 'animated fadeOutRight' } }); ``` ================================================ FILE: docs/push.md ================================================ With v3.1.0-beta push notifications are supported with service worker implementation. ### Preparation Steps * 1) Create a project on the [Firebase Developer Console](https://console.firebase.google.com/). * 2) Go to **Project settings** (The cog near the top left corner), click the ' **Cloud Messaging**' tab. * 3) Note that **Server Key** and **Sender ID**. * 4) Create a copy of [manifest.json.template](https://github.com/needim/noty/blob/master/manifest.json.template) called **manifest.json** at root folder * 5) Replace in your new manifest.json with your own Sender ID from the Firebase Developer Console project. * 6) Create a copy of [service-worker.js.template](https://github.com/needim/noty/blob/master/service-worker.js.template) called **service-worker.js** at root folder * 7) Link your manifest ##### Now half of the job is done. ### Let's create a Noty.Push instance ```javascript const NotyPush = Noty.Push('/service-worker.js') .on('onPermissionGranted', function () { console.log('Perm: granted') }) .on('onPermissionDenied', function () { console.log('Perm: denied') }) .on('onSubscriptionSuccess', function (subData) { console.log('Subscription:', subData) // (YOU NEED TO STORE THIS VALUES FOR LATER USE) }) .on('onSubscriptionCancel', function (subData) { console.log('Subscription: canceled') }) .on('onWorkerSuccess', function () { console.log('Worker: installed') }) .on('onWorkerError', function (err) { console.log('Worker: failed', err) }) .on('onWorkerNotSupported', function (err) { console.log('Worker: not supported', err) }) ``` ### Let's Ask User's Permission ```javascript NotyPush.requestSubscription() ``` Now the browser will ask permission. And if the user allows it, the service worker will be registered. !> **You have to store subData onSubscriptionSuccess callback for later use.** ### Sending push notifications from backend (Node.js) Now that we have subscription information, we can send notifications with [**web-push**](https://github.com/web-push-libs/web-push) library. Let's install [**web-push**](https://github.com/web-push-libs/web-push) first. ``` $ npm install web-push ``` Create a JavaScript file called sendPushExample.js ```javascript const webpush = require('web-push') const vapidKeys = webpush.generateVAPIDKeys() webpush.setGCMAPIKey('YOUR-SERVER-KEY-FROM-FIREBASE-CONSOLE') webpush.setVapidDetails( 'mailto:your@email.com', vapidKeys.publicKey, vapidKeys.privateKey ) // Use your previously saved subscription information const pushSubscription = { endpoint: '', keys: { auth: '', p256dh: '' } } // image & actions are optional webpush.sendNotification(pushSubscription, JSON.stringify({ title: 'Noty title', body: 'Noty body', icon: 'https://your-icon0-url.png', image: 'https://your-image-url.png', url: 'http://ned.im/noty/?ref=webPushTest', actions: [ {action: 'actionYes', 'title': 'Yes', 'icon': 'https://your-icon1-url.png'}, {action: 'actionNo', 'title': 'No', 'icon': 'https://your-icon2-url.png'} ] })) ``` After that we can run ``` $ node sendPushExample.js ``` Notification should look like this for Chrome ![notification example for chrome](_media/notification-example-chrome.png) ### Checking user's current permission ```javascript NotyPush.getPermissionStatus() === 'granted' NotyPush.getPermissionStatus() === 'default' NotyPush.getPermissionStatus() === 'denied' // In some cases, you may need to check // whether your service worker is running. NotyPush.isSWRegistered() === true // You may ask again for permission, // If user's permission granted // but service worker unregistered or not working. ``` ================================================ FILE: docs/themes.md ================================================ **Available Themes**:
        `mint`, `sunset`, `relax`, `nest`, `metroui`, `semanticui`, `light`, `bootstrap-v3`, `bootstrap-v4` **Default Theme**: `mint` Usage; ```javascript new Noty({ theme: 'themeName', text: 'Some notification text' }).show(); ``` ## Theme Previews {docsify-ignore}
        ================================================ FILE: docs/types.md ================================================ **Types**:
        `alert`, `success`, `warning`, `error`, `info/information` **Layouts**:
        `top`, `topLeft`, `topCenter`, `topRight`, `center`, `centerLeft`, `centerRight`, `bottom`, `bottomLeft`, `bottomCenter`, `bottomRight` Creating a notification; ```javascript new Noty({ type: 'success', layout: 'topRight', text: 'Some notification text' }).show(); ``` ### Custom Containers Custom container usage example; ```javascript new Noty({ text : 'Some notification text', container: '.custom-container' }).show(); ``` ================================================ FILE: docs/v2/animations.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Show & Hide Animations

        1. Using with jQuery animate properties;

        var n = noty({
            text: 'NOTY - a jquery notification library!',
            animation: {
                open: {height: 'toggle'},
                close: {height: 'toggle'},
                easing: 'swing',
                speed: 500 // opening & closing animation speed
            }
        });
        
        About Easing
        The remaining parameter of .animate() is a string naming an easing function to use. An easing function specifies the speed at which the animation progresses at different points within the animation. The only easing implementations in the jQuery library are the default, called swing, and one that progresses at a constant pace, called linear. More easing functions are available with the use of plug-ins, most notably the jQuery UI suite.

        2. Using with class names. (like animate.css)

        var n = noty({
            text: 'NOTY - a jquery notification library!',
            animation: {
                open: 'animated bounceInLeft', // Animate.css class names
                close: 'animated bounceOutLeft', // Animate.css class names
                easing: 'swing', // unavailable - no need
                speed: 500 // unavailable - no need
            }
        });
        
        easing and speed has no effect when string class name is being used.
        ================================================ FILE: docs/v2/api.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        API & Callbacks

        NOTY have 5 callback option for now. onShow - afterShow - onClose - afterClose - afterCloseClick

        API Methods

        var n = noty({text: 'Hi!'});
        
        
        console.log($.noty.get(n.id)); // Returns a NOTY javascript object
        console.log(n); // Returns a NOTY javascript object
        
        
        $.noty.close(n.id); // Close a NOTY
        n.close(); // same as above
        
        
        $.noty.setText(n.id, 'Hi again!'); // Notification text updater
        n.setText('Hi again!'); // same as above
        
        
        $.noty.setType(n.id, 'error'); // Notification type updater
        n.setType('error'); // same as above
        
        
        $.noty.clearQueue(); // Clears the notification queue
        $.noty.closeAll(); // Close all notifications
        
        ================================================ FILE: docs/v2/confirmations.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Confirm Dialogs

        We can set button objects with an array like above;

        noty({
          text: 'Do you want to continue? <input id="example" type="text">',
          buttons: [
            {addClass: 'btn btn-primary', text: 'Ok', onClick: function($noty) {
                // this = button element
                // $noty = $noty element
        
                console.log($noty.$bar.find('input#example').val());
        
                $noty.close();
                noty({text: 'You clicked "Ok" button', type: 'success'});
              }
            },
            {addClass: 'btn btn-danger', text: 'Cancel', onClick: function($noty) {
                $noty.close();
                noty({text: 'You clicked "Cancel" button', type: 'error'});
              }
            }
          ]
        });
        
        ================================================ FILE: docs/v2/index.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Installation

        1. Include jQuery 1.6+

        2. Include noty/packaged/jquery.noty.packaged.min.js.

        That's It. Your code should then be similar to this:

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
        <script type="text/javascript" src="js/noty/packaged/jquery.noty.packaged.min.js"></script>
        
        NOTY is compatible with jQuery 1.6+ for now. But if you are using older version then 1.6 you can add promise.js to your header.
        (Thanks to Maksim Pecherskiy)

        Install via Bower

        $ bower install noty
        

        Install via NPM

        $ npm install noty
        
        ================================================ FILE: docs/v2/layouts.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Types & Layouts

        NOTY has 11 layouts; top, topLeft, topCenter, topRight, center, centerLeft, centerRight, bottom, bottomLeft, bottomCenter, bottomRight
        and 5 types alert, success, warning, error, information

        Let's create a notification with layout and type CREATE

        Custom container example for using inline layout;

        Custom container usage example;

        var n = $('.custom-container').noty({text: 'NOTY - a jquery notification library!'});
        ================================================ FILE: docs/v2/options.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Options & Defaults

        Available options listed below.

        $.noty.defaults = {
          layout: 'top',
          theme: 'defaultTheme', // or relax
          type: 'alert', // success, error, warning, information, notification
          text: '', // [string|html] can be HTML or STRING
        
          dismissQueue: true, // [boolean] If you want to use queue feature set this true
          force: false, // [boolean] adds notification to the beginning of queue when set to true
          maxVisible: 5, // [integer] you can set max visible notification count for dismissQueue true option,
        
          template: '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>',
        
          timeout: false, // [integer|boolean] delay for closing event in milliseconds. Set false for sticky notifications
          progressBar: false, // [boolean] - displays a progress bar
        
          animation: {
            open: {height: 'toggle'}, // or Animate.css class names like: 'animated bounceInLeft'
            close: {height: 'toggle'}, // or Animate.css class names like: 'animated bounceOutLeft'
            easing: 'swing',
            speed: 500 // opening & closing animation speed
          },
          closeWith: ['click'], // ['click', 'button', 'hover', 'backdrop'] // backdrop click will close all notifications
        
          modal: false, // [boolean] if true adds an overlay
          killer: false, // [boolean] if true closes all notifications and shows itself
        
          callback: {
            onShow: function() {},
            afterShow: function() {},
            onClose: function() {},
            afterClose: function() {},
            onCloseClick: function() {},
          },
        
          buttons: false // [boolean|array] an array of buttons, for creating confirmation dialogs.
        };
        
        Of course, you can override default values;
        $.noty.defaults.theme = 'relax';
        ================================================ FILE: docs/v2/releases.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Release History

        ================================================ FILE: docs/v2/themes.html ================================================ noty - a jQuery Notification Plugin
        NOTY is a jQuery plugin that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)


        Theme Library

        NOTY comes with 4 themes; defaultTheme, relax, bootstrapTheme (v2) and metroui

        If you want to submit your theme you can create a pull request on Github.

        • defaultTheme

        • relax

        • bootstrapTheme

        Author: famaridon

        • metroui

        ================================================ FILE: docs/v2/vendor/animate.css ================================================ /* Animate.css - http://daneden.me/animate LICENSED UNDER THE MIT LICENSE (MIT) Copyright (c) 2012 Dan Eden 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. */ @charset "UTF-8";.animated{-webkit-animation-duration:.2s;animation-duration:.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}@-webkit-keyframes bounce{0%,20%,50%,80%,100%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@keyframes bounce{0%,20%,50%,80%,100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);-ms-transform:translateY(-15px);transform:translateY(-15px)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce}@-webkit-keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.1);transform:scale(1.1)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes pulse{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}100%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);-ms-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);-ms-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);-ms-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);-ms-transform:rotate(-5deg);transform:rotate(-5deg)}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}}.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:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9)rotate(-3deg);transform:scale(.9)rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1)rotate(3deg);transform:scale(1.1)rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1)rotate(-3deg);transform:scale(1.1)rotate(-3deg)}100%{-webkit-transform:scale(1)rotate(0);transform:scale(1)rotate(0)}}@keyframes tada{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9)rotate(-3deg);-ms-transform:scale(.9)rotate(-3deg);transform:scale(.9)rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1)rotate(3deg);-ms-transform:scale(1.1)rotate(3deg);transform:scale(1.1)rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1)rotate(-3deg);-ms-transform:scale(1.1)rotate(-3deg);transform:scale(1.1)rotate(-3deg)}100%{-webkit-transform:scale(1)rotate(0);-ms-transform:scale(1)rotate(0);transform:scale(1)rotate(0)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateX(0%);transform:translateX(0%)}15%{-webkit-transform:translateX(-25%)rotate(-5deg);transform:translateX(-25%)rotate(-5deg)}30%{-webkit-transform:translateX(20%)rotate(3deg);transform:translateX(20%)rotate(3deg)}45%{-webkit-transform:translateX(-15%)rotate(-3deg);transform:translateX(-15%)rotate(-3deg)}60%{-webkit-transform:translateX(10%)rotate(2deg);transform:translateX(10%)rotate(2deg)}75%{-webkit-transform:translateX(-5%)rotate(-1deg);transform:translateX(-5%)rotate(-1deg)}100%{-webkit-transform:translateX(0%);transform:translateX(0%)}}@keyframes wobble{0%{-webkit-transform:translateX(0%);-ms-transform:translateX(0%);transform:translateX(0%)}15%{-webkit-transform:translateX(-25%)rotate(-5deg);-ms-transform:translateX(-25%)rotate(-5deg);transform:translateX(-25%)rotate(-5deg)}30%{-webkit-transform:translateX(20%)rotate(3deg);-ms-transform:translateX(20%)rotate(3deg);transform:translateX(20%)rotate(3deg)}45%{-webkit-transform:translateX(-15%)rotate(-3deg);-ms-transform:translateX(-15%)rotate(-3deg);transform:translateX(-15%)rotate(-3deg)}60%{-webkit-transform:translateX(10%)rotate(2deg);-ms-transform:translateX(10%)rotate(2deg);transform:translateX(10%)rotate(2deg)}75%{-webkit-transform:translateX(-5%)rotate(-1deg);-ms-transform:translateX(-5%)rotate(-1deg);transform:translateX(-5%)rotate(-1deg)}100%{-webkit-transform:translateX(0%);-ms-transform:translateX(0%);transform:translateX(0%)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05);transform:scale(1.05)}70%{-webkit-transform:scale(.9);transform:scale(.9)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);-ms-transform:scale(.3);transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}70%{-webkit-transform:scale(.9);-ms-transform:scale(.9);transform:scale(.9)}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}60%{opacity:1;-webkit-transform:translateY(30px);transform:translateY(30px)}80%{-webkit-transform:translateY(-10px);transform:translateY(-10px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes bounceInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}60%{opacity:1;-webkit-transform:translateY(30px);-ms-transform:translateY(30px);transform:translateY(30px)}80%{-webkit-transform:translateY(-10px);-ms-transform:translateY(-10px);transform:translateY(-10px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}60%{opacity:1;-webkit-transform:translateX(30px);transform:translateX(30px)}80%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes bounceInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}60%{opacity:1;-webkit-transform:translateX(30px);-ms-transform:translateX(30px);transform:translateX(30px)}80%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}60%{opacity:1;-webkit-transform:translateX(-30px);transform:translateX(-30px)}80%{-webkit-transform:translateX(10px);transform:translateX(10px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes bounceInRight{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}60%{opacity:1;-webkit-transform:translateX(-30px);-ms-transform:translateX(-30px);transform:translateX(-30px)}80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}60%{opacity:1;-webkit-transform:translateY(-30px);transform:translateY(-30px)}80%{-webkit-transform:translateY(10px);transform:translateY(10px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes bounceInUp{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}60%{opacity:1;-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);transform:translateY(-30px)}80%{-webkit-transform:translateY(10px);-ms-transform:translateY(10px);transform:translateY(10px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(.95);transform:scale(.95)}50%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}100%{opacity:0;-webkit-transform:scale(.3);transform:scale(.3)}}@keyframes bounceOut{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(.95);-ms-transform:scale(.95);transform:scale(.95)}50%{opacity:1;-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}100%{opacity:0;-webkit-transform:scale(.3);-ms-transform:scale(.3);transform:scale(.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes bounceOutDown{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(20px);transform:translateX(20px)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes bounceOutLeft{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes bounceOutRight{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(20px);transform:translateY(20px)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes bounceOutUp{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.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:translateY(-20px);transform:translateY(-20px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.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;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes fadeOutDownBig{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}}@keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes fadeOutLeftBig{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}}@keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes fadeOutRightBig{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes fadeOutUpBig{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px)translateZ(0)rotateY(0)scale(1);transform:perspective(400px)translateZ(0)rotateY(0)scale(1)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1)}50%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95)}80%,100%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1)}}@keyframes flip{0%{-webkit-transform:perspective(400px)translateZ(0)rotateY(0)scale(1);-ms-transform:perspective(400px)translateZ(0)rotateY(0)scale(1);transform:perspective(400px)translateZ(0)rotateY(0)scale(1)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1);-ms-transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1)}50%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);-ms-transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95);-ms-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95)}80%,100%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1);-ms-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1)}}.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)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateX(-10deg);transform:perspective(400px)rotateX(-10deg)}70%{-webkit-transform:perspective(400px)rotateX(10deg);transform:perspective(400px)rotateX(10deg)}100%{-webkit-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}}@keyframes flipInX{0%{-webkit-transform:perspective(400px)rotateX(90deg);-ms-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateX(-10deg);-ms-transform:perspective(400px)rotateX(-10deg);transform:perspective(400px)rotateX(-10deg)}70%{-webkit-transform:perspective(400px)rotateX(10deg);-ms-transform:perspective(400px)rotateX(10deg);transform:perspective(400px)rotateX(10deg)}100%{-webkit-transform:perspective(400px)rotateX(0);-ms-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}}.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)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateY(-10deg);transform:perspective(400px)rotateY(-10deg)}70%{-webkit-transform:perspective(400px)rotateY(10deg);transform:perspective(400px)rotateY(10deg)}100%{-webkit-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}}@keyframes flipInY{0%{-webkit-transform:perspective(400px)rotateY(90deg);-ms-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateY(-10deg);-ms-transform:perspective(400px)rotateY(-10deg);transform:perspective(400px)rotateY(-10deg)}70%{-webkit-transform:perspective(400px)rotateY(10deg);-ms-transform:perspective(400px)rotateY(10deg);transform:perspective(400px)rotateY(10deg)}100%{-webkit-transform:perspective(400px)rotateY(0);-ms-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}}.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)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px)rotateX(0);-ms-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateX(90deg);-ms-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px)rotateY(0);-ms-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateY(90deg);-ms-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(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-keyframes lightSpeedIn{0%{-webkit-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}60%{-webkit-transform:translateX(-20%)skewX(30deg);transform:translateX(-20%)skewX(30deg);opacity:1}80%{-webkit-transform:translateX(0%)skewX(-15deg);transform:translateX(0%)skewX(-15deg);opacity:1}100%{-webkit-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translateX(100%)skewX(-30deg);-ms-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}60%{-webkit-transform:translateX(-20%)skewX(30deg);-ms-transform:translateX(-20%)skewX(30deg);transform:translateX(-20%)skewX(30deg);opacity:1}80%{-webkit-transform:translateX(0%)skewX(-15deg);-ms-transform:translateX(0%)skewX(-15deg);transform:translateX(0%)skewX(-15deg);opacity:1}100%{-webkit-transform:translateX(0%)skewX(0);-ms-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);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%{-webkit-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}100%{-webkit-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}}@keyframes lightSpeedOut{0%{-webkit-transform:translateX(0%)skewX(0);-ms-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}100%{-webkit-transform:translateX(100%)skewX(-30deg);-ms-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)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:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,100%{-webkit-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);-ms-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,100%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(200deg);-ms-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes slideOutRight{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes slideOutUp{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}@-webkit-keyframes hinge{0%{-webkit-transform:rotate(0);transform:rotate(0)}0%,20%,60%{-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:rotate(80deg);transform:rotate(80deg)}40%{-webkit-transform:rotate(60deg);transform:rotate(60deg)}40%,80%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}80%{-webkit-transform:rotate(60deg)translateY(0);transform:rotate(60deg)translateY(0);opacity:1}100%{-webkit-transform:translateY(700px);transform:translateY(700px);opacity:0}}@keyframes hinge{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}0%,20%,60%{-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:rotate(80deg);-ms-transform:rotate(80deg);transform:rotate(80deg)}40%{-webkit-transform:rotate(60deg);-ms-transform:rotate(60deg);transform:rotate(60deg)}40%,80%{-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}80%{-webkit-transform:rotate(60deg)translateY(0);-ms-transform:rotate(60deg)translateY(0);transform:rotate(60deg)translateY(0);opacity:1}100%{-webkit-transform:translateY(700px);-ms-transform:translateY(700px);transform:translateY(700px);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%)rotate(-120deg);transform:translateX(-100%)rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%)rotate(-120deg);-ms-transform:translateX(-100%)rotate(-120deg);transform:translateX(-100%)rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0)rotate(0);-ms-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1;-webkit-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}100%{opacity:0;-webkit-transform:translateX(100%)rotate(120deg);transform:translateX(100%)rotate(120deg)}}@keyframes rollOut{0%{opacity:1;-webkit-transform:translateX(0)rotate(0);-ms-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}100%{opacity:0;-webkit-transform:translateX(100%)rotate(120deg);-ms-transform:translateX(100%)rotate(120deg);transform:translateX(100%)rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut} ================================================ FILE: docs/v2/vendor/custom.css ================================================ /* * What follows is the result of much research on cross-browser styling. * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, * Kroc Camen, and the H5BP dev community and team. */ /* ========================================================================== Base styles: opinionated defaults ========================================================================== */ html { color: #222; font-size: 1em; line-height: 1.4; } .small { line-height: 1.5rem; } /* * Remove text-shadow in selection highlight: * https://twitter.com/miketaylr/status/12228805301 * * These selection rule sets have to be separate. * Customize the background color to match your design. */ ::-moz-selection { background: #b3d4fc; text-shadow: none; } ::selection { background: #b3d4fc; text-shadow: none; } /* * A better looking default horizontal rule */ hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } /* * Remove the gap between audio, canvas, iframes, * images, videos and the bottom of their containers: * https://github.com/h5bp/html5-boilerplate/issues/440 */ audio, canvas, iframe, img, svg, video { vertical-align: middle; } /* * Remove default fieldset styles. */ fieldset { border: 0; margin: 0; padding: 0; } /* * Allow only vertical resizing of textareas. */ textarea { resize: vertical; } /* ========================================================================== Author's custom styles ========================================================================== */ @font-face { font-family: "Brandon Text Light"; src: url("../fonts/brandon-text-light.woff") format("woff"); font-weight: normal; font-style: normal; } @font-face { font-family: "Brandon Text Regular"; src: url("../fonts/brandon-text-regular.woff") format("woff"); font-weight: normal; font-style: normal; } @font-face { font-family: "Brandon Text Bold"; src: url("../fonts/brandon-text-bold.woff") format("woff"); font-weight: normal; font-style: normal; } html, body { font-family: 'Brandon Text Light', "Helvetica Neue", Helvetica, Arial, sans-serif; width: 100%; color: #8c8c8c; font-size: 16px; line-height: 30px; background-color: #2D3134; } h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 { color: #fff; font-family: 'Nunito', 'Brandon Text Regular', "Helvetica Neue", Helvetica, Arial, sans-serif; } a, i, input, textarea, .primary, button, .mask { transition: all .15s ease; } a { color: #dde4e8; text-decoration: underline; } a:hover { text-decoration: underline; color: #fff; } .bold { font-family: 'Brandon Text Regular', "Helvetica Neue", Helvetica, Arial, sans-serif; } strong { font-family: 'Brandon Text Regular', "Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: 300; } .profile-bio { width: 50%; margin: 5px auto 10px; color: #444; } a.top-link { margin: 0 20px; color: #444; transition: all .3s ease; width: 110px !important; display: inline-block; } a.top-link:hover { color: #e7543d; } .container-top { padding-top: 50px; position: fixed; width: 100%; z-index: 3; } .container-top:after { content: " "; border-bottom: 2px solid rgba(209, 209, 209, 0.26); -webkit-border-radius: 100%; -moz-border-radius: 100%; border-radius: 100%; width: 100%; height: 155px; position: absolute; z-index: -1; top: -20px; left: 0; -webkit-transition: all .4s ease; -moz-transition: all .4s ease; -ms-transition: all .4s ease; -o-transition: all .4s ease; transition: all .4s ease; } .container-top.shown:after, .container-top.shown:before { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .container-top:before { content: " "; background-color: #fff; -webkit-border-radius: 100%; -moz-border-radius: 100%; border-radius: 100%; width: 100%; height: 155px; position: absolute; z-index: -2; top: -20px; left: 0; } .container-bottom { padding-top: 170px; z-index: 1; } .top-link [class^="ps-icon-"]:before, .top-link [class*=" ps-icon-"]:before { position: relative; top: 7px; margin-right: 4px; font-size: 1.4em; } a.contact-link { margin: 0 4px; color: #ccc; display: inline-block; width: 25px; } .primary, a.contact-link:hover { color: #e7543d; } a.contact-link.wdt img { width: 18px; position: relative; top: -2px; } h3.name { letter-spacing: 1px; font-family: "Nunito", "Brandon Text Light", sans-serif; } h3.top-name { position: absolute; font-family: "Nunito", "Brandon Text Light", sans-serif; top: -60px; left: 0; width: 100%; opacity: 0; -webkit-transition: all .3s; -moz-transition: all .3s; -ms-transition: all .3s; -o-transition: all .3s; transition: all .3s; letter-spacing: 1px; } .mt10 { margin-top: 10px; } .mt20 { margin-top: 20px; } .mt30 { margin-top: 30px; } .mb10 { margin-bottom: 10px; } .mb20 { margin-bottom: 20px; } .mb30 { margin-bottom: 30px; } a.button { display: inline-block; position: relative; padding: .8em 1.3em; font-size: 11px; letter-spacing: 1px; font-weight: 800; text-transform: uppercase; line-height: 1.2; outline: 0; background: #AC8FFD; border: 2px solid #948CE2; color: #fff; text-shadow: none; border-radius: 2px; } a.button:hover { color: #fff; background-color: #c0a7fd; border-color: #948CE2; } /* ---- */ i.fa.fa-heart { color: #AC8FFD; } h2 i.fa, h2 i.ps-icon { font-size: 16px; margin-right: 14px; line-height: 39px; text-align: center; color: #B7C6C9; background: #fff; border-radius: 50%; border: 4px solid #F4F6F7; display: inline-block; width: 47px; } .rainbow_border{ border-image: -webkit-linear-gradient(left, #E18728, #BE4C39 33%, #9351A6 66%, #4472B9,#4CA454,#D49B00) 2%; border-image: -ms-linear-gradient(left, #E18728, #BE4C39 33%, #9351A6 66%, #4472B9,#4CA454,#D49B00) 2%; border-image: -moz-linear-gradient(left, #E18728, #BE4C39 33%, #9351A6 66%, #4472B9,#4CA454,#D49B00) 2%; } .imp { color: #FAF46A; border-radius: 3px; } .left-logo { width: 170px; margin: 20px auto; display: block; } ul.top-links { list-style: none; margin: 0; padding: 0; } ul.top-links li { } ul.top-links li a { color: #8c8c8c; display: block; padding: 2px 10px; font-family: "Nunito", "Brandon Text Regular", sans-serif; text-decoration: none; } ul.top-links li a.active { color: #fff; font-weight: bolder } ul.top-links li a:hover { color: #fff; } blockquote { font-size: 15px; line-height: 1.5em; margin: 40px 0; background: rgba(0,0,0,.075); border-left: 5px solid #222; } .project-info { text-align: center; padding: 0 5px; } pre { display: block; padding: 20px; margin: 0 0 10px; font-size: 13px; line-height: 1.42857143; color: #dde4e8; word-break: break-all; word-wrap: break-word; background-color: rgba(22,22,22,.8); border: none; border-radius: 0; } .sharer-btn.text-center.sharer-0 { display: inline-block !important; } .sharer-btn.text-center.sharer-0 label { padding: 2px 13px !important; position: relative; top: 2px !important; background: #eeeeee !important; color: #555555 !important; border-radius: 2px !important; } .sharer-btn.text-center.sharer-0 label span { text-transform: capitalize !important; font-size: .85em !important; } .sharer-btn.text-center.sharer-0 .social.active.bottom { z-index: 9999; position: relative; } span.ps-icon { position: relative; top: 5px; } .top-links span.ps-icon { position: relative; top: 3px; text-align: center; margin-right: 12px; background: #222; border-radius: 5px; width: 25px; height: 25px; padding-top: 1px; display: inline-block; } select:focus { outline: none; } select { /* General styling */ height: 30px; width: 137px; padding-left: 10px; color: #222; border-radius: 3px; border: 0 solid #222; margin: 0 3px; /* Removes the default "; all = div.getElementsByTagName("*"); a = div.getElementsByTagName("a")[ 0 ]; a.style.cssText = "top:1px;float:left;opacity:.5"; // Can't get basic test support if ( !all || !all.length || !a ) { return {}; } // First batch of supports tests select = document.createElement("select"); opt = select.appendChild( document.createElement("option") ); input = div.getElementsByTagName("input")[ 0 ]; support = { // IE strips leading whitespace when .innerHTML is used leadingWhitespace: ( div.firstChild.nodeType === 3 ), // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText instead) style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) hrefNormalized: ( a.getAttribute("href") === "/a" ), // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 opacity: /^0.5/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) checkOn: ( input.value === "on" ), // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", // Tests for enctype support on a form(#6743) enctype: !!document.createElement("form").enctype, // Makes sure cloning an html5 element does not cause problems // Where outerHTML is undefined, this still works html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode boxModel: ( document.compatMode === "CSS1Compat" ), // Will be defined later submitBubbles: true, changeBubbles: true, focusinBubbles: false, deleteExpando: true, noCloneEvent: true, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, boxSizingReliable: true, pixelPosition: false }; // Make sure checked status is properly cloned input.checked = true; support.noCloneChecked = input.cloneNode( true ).checked; // Make sure that the options inside disabled selects aren't marked as disabled // (WebKit marks them as disabled) select.disabled = true; support.optDisabled = !opt.disabled; // Test to see if it's possible to delete an expando from an element // Fails in Internet Explorer try { delete div.test; } catch( e ) { support.deleteExpando = false; } if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { div.attachEvent( "onclick", clickFn = function() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) support.noCloneEvent = false; }); div.cloneNode( true ).fireEvent("onclick"); div.detachEvent( "onclick", clickFn ); } // Check if a radio maintains its value // after being appended to the DOM input = document.createElement("input"); input.value = "t"; input.setAttribute( "type", "radio" ); support.radioValue = input.value === "t"; input.setAttribute( "checked", "checked" ); // #11217 - WebKit loses check when the name is after the checked attribute input.setAttribute( "name", "t" ); div.appendChild( input ); fragment = document.createDocumentFragment(); fragment.appendChild( div.lastChild ); // WebKit doesn't clone checked state correctly in fragments support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; fragment.removeChild( input ); fragment.appendChild( div ); // Technique from Juriy Zaytsev // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ // We only care about the case where non-standard event systems // are used, namely in IE. Short-circuiting here helps us to // avoid an eval call (in setAttribute) which can cause CSP // to go haywire. See: https://developer.mozilla.org/en/Security/CSP if ( div.attachEvent ) { for ( i in { submit: true, change: true, focusin: true }) { eventName = "on" + i; isSupported = ( eventName in div ); if ( !isSupported ) { div.setAttribute( eventName, "return;" ); isSupported = ( typeof div[ eventName ] === "function" ); } support[ i + "Bubbles" ] = isSupported; } } // Run tests that need a body at doc ready jQuery(function() { var container, div, tds, marginDiv, divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", body = document.getElementsByTagName("body")[0]; if ( !body ) { // Return for frameset docs that don't have a body return; } container = document.createElement("div"); container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; body.insertBefore( container, body.firstChild ); // Construct the test element div = document.createElement("div"); container.appendChild( div ); // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). // (only IE 8 fails this test) div.innerHTML = "
        t
        "; tds = div.getElementsByTagName("td"); tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; isSupported = ( tds[ 0 ].offsetHeight === 0 ); tds[ 0 ].style.display = ""; tds[ 1 ].style.display = "none"; // Check if empty table cells still have offsetWidth/Height // (IE <= 8 fail this test) support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); // Check box-sizing and margin behavior div.innerHTML = ""; div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; support.boxSizing = ( div.offsetWidth === 4 ); support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); // NOTE: To any future maintainer, window.getComputedStyle was used here // instead of getComputedStyle because it gave a better gzip size. // The difference between window.getComputedStyle and getComputedStyle is // 7 bytes if ( window.getComputedStyle ) { support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; // Check if div with explicit width and no margin-right incorrectly // gets computed margin-right based on width of container. For more // info see bug #3333 // Fails in WebKit before Feb 2011 nightlies // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right marginDiv = document.createElement("div"); marginDiv.style.cssText = div.style.cssText = divReset; marginDiv.style.marginRight = marginDiv.style.width = "0"; div.style.width = "1px"; div.appendChild( marginDiv ); support.reliableMarginRight = !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); } if ( typeof div.style.zoom !== "undefined" ) { // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout // (IE < 8 does this) div.innerHTML = ""; div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); // Check if elements with layout shrink-wrap their children // (IE 6 does this) div.style.display = "block"; div.style.overflow = "visible"; div.innerHTML = "
        "; div.firstChild.style.width = "5px"; support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); container.style.zoom = 1; } // Null elements to avoid leaks in IE body.removeChild( container ); container = div = tds = marginDiv = null; }); // Null elements to avoid leaks in IE fragment.removeChild( div ); all = a = select = opt = input = fragment = div = null; return support; })(); var rbrace = /^(?:\{.*\}|\[.*\])$/, rmultiDash = /([A-Z])/g; jQuery.extend({ cache: {}, deletedIds: [], // Please use with caution uuid: 0, // Unique for each copy of jQuery on the page // Non-digits removed to match rinlinejQuery expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, // Ban all objects except for Flash (which handle expandos) "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", "applet": true }, hasData: function( elem ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data, pvt /* Internal Use Only */ ) { if ( !jQuery.acceptData( elem ) ) { return; } var thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string", // We have to handle DOM nodes and JS objects differently because IE6-7 // can't GC object references properly across the DOM-JS boundary isNode = elem.nodeType, // Only DOM nodes need the global jQuery cache; JS object data is // attached directly to the object so GC can occur automatically cache = isNode ? jQuery.cache : elem, // Only defining an ID for JS objects if its cache already exists allows // the code to shortcut on the same path as a DOM node with no cache id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; // Avoid doing any more work than we need to when trying to get data on an // object that has no data at all if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { return; } if ( !id ) { // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if ( isNode ) { elem[ internalKey ] = id = jQuery.deletedIds.pop() || ++jQuery.uuid; } else { id = internalKey; } } if ( !cache[ id ] ) { cache[ id ] = {}; // Avoids exposing jQuery metadata on plain JS objects when the object // is serialized using JSON.stringify if ( !isNode ) { cache[ id ].toJSON = jQuery.noop; } } // An object can be passed to jQuery.data instead of a key/value pair; this gets // shallow copied over onto the existing cache if ( typeof name === "object" || typeof name === "function" ) { if ( pvt ) { cache[ id ] = jQuery.extend( cache[ id ], name ); } else { cache[ id ].data = jQuery.extend( cache[ id ].data, name ); } } thisCache = cache[ id ]; // jQuery data() is stored in a separate object inside the object's internal data // cache in order to avoid key collisions between internal data and user-defined // data. if ( !pvt ) { if ( !thisCache.data ) { thisCache.data = {}; } thisCache = thisCache.data; } if ( data !== undefined ) { thisCache[ jQuery.camelCase( name ) ] = data; } // Check for both converted-to-camel and non-converted data property names // If a data property was specified if ( getByName ) { // First Try to find as-is property data ret = thisCache[ name ]; // Test for null|undefined property data if ( ret == null ) { // Try to find the camelCased property ret = thisCache[ jQuery.camelCase( name ) ]; } } else { ret = thisCache; } return ret; }, removeData: function( elem, name, pvt /* Internal Use Only */ ) { if ( !jQuery.acceptData( elem ) ) { return; } var thisCache, i, l, isNode = elem.nodeType, // See jQuery.data for more information cache = isNode ? jQuery.cache : elem, id = isNode ? elem[ jQuery.expando ] : jQuery.expando; // If there is already no cache entry for this object, there is no // purpose in continuing if ( !cache[ id ] ) { return; } if ( name ) { thisCache = pvt ? cache[ id ] : cache[ id ].data; if ( thisCache ) { // Support array or space separated string names for data keys if ( !jQuery.isArray( name ) ) { // try the string as a key before any manipulation if ( name in thisCache ) { name = [ name ]; } else { // split the camel cased version by spaces unless a key with the spaces exists name = jQuery.camelCase( name ); if ( name in thisCache ) { name = [ name ]; } else { name = name.split(" "); } } } for ( i = 0, l = name.length; i < l; i++ ) { delete thisCache[ name[i] ]; } // If there is no data left in the cache, we want to continue // and let the cache object itself get destroyed if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { return; } } } // See jQuery.data for more information if ( !pvt ) { delete cache[ id ].data; // Don't destroy the parent cache unless the internal data object // had been the only thing left in it if ( !isEmptyDataObject( cache[ id ] ) ) { return; } } // Destroy the cache if ( isNode ) { jQuery.cleanData( [ elem ], true ); // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) } else if ( jQuery.support.deleteExpando || cache != cache.window ) { delete cache[ id ]; // When all else fails, null } else { cache[ id ] = null; } }, // For internal use only. _data: function( elem, name, data ) { return jQuery.data( elem, name, data, true ); }, // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; // nodes accept data unless otherwise specified; rejection can be conditional return !noData || noData !== true && elem.getAttribute("classid") === noData; } }); jQuery.fn.extend({ data: function( key, value ) { var parts, part, attr, name, l, elem = this[0], i = 0, data = null; // Gets all values if ( key === undefined ) { if ( this.length ) { data = jQuery.data( elem ); if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { attr = elem.attributes; for ( l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { name = jQuery.camelCase( name.substring(5) ); dataAttr( elem, name, data[ name ] ); } } jQuery._data( elem, "parsedAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } parts = key.split( ".", 2 ); parts[1] = parts[1] ? "." + parts[1] : ""; part = parts[1] + "!"; return jQuery.access( this, function( value ) { if ( value === undefined ) { data = this.triggerHandler( "getData" + part, [ parts[0] ] ); // Try to fetch any internally stored data first if ( data === undefined && elem ) { data = jQuery.data( elem, key ); data = dataAttr( elem, key, data ); } return data === undefined && parts[1] ? this.data( parts[0] ) : data; } parts[1] = value; this.each(function() { var self = jQuery( this ); self.triggerHandler( "setData" + part, parts ); jQuery.data( this, key, value ); self.triggerHandler( "changeData" + part, parts ); }); }, null, value, arguments.length > 1, null, false ); }, removeData: function( key ) { return this.each(function() { jQuery.removeData( this, key ); }); } }); function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : // Only convert to a number if it doesn't change the string +data + "" === data ? +data : rbrace.test( data ) ? jQuery.parseJSON( data ) : data; } catch( e ) {} // Make sure we set the data so it isn't changed later jQuery.data( elem, key, data ); } else { data = undefined; } } return data; } // checks a cache object for emptiness function isEmptyDataObject( obj ) { var name; for ( name in obj ) { // if the public data object is empty, the private is still empty if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { continue; } if ( name !== "toJSON" ) { return false; } } return true; } jQuery.extend({ queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = jQuery._data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || jQuery.isArray(data) ) { queue = jQuery._data( elem, type, jQuery.makeArray(data) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !queue.length && hooks ) { hooks.empty.fire(); } }, // not intended for public consumption - generates a queueHooks object, or returns the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return jQuery._data( elem, key ) || jQuery._data( elem, key, { empty: jQuery.Callbacks("once memory").add(function() { jQuery.removeData( elem, type + "queue", true ); jQuery.removeData( elem, key, true ); }) }); } }); jQuery.fn.extend({ queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[0], type ); } return data === undefined ? this : this.each(function() { var queue = jQuery.queue( this, type, data ); // ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[0] !== "inprogress" ) { jQuery.dequeue( this, type ); } }); }, dequeue: function( type ) { return this.each(function() { jQuery.dequeue( this, type ); }); }, // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = setTimeout( next, time ); hooks.stop = function() { clearTimeout( timeout ); }; }); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while( i-- ) { if ( (tmp = jQuery._data( elements[ i ], type + "queueHooks" )) && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } }); var nodeHook, boolHook, fixSpecified, rclass = /[\t\r\n]/g, rreturn = /\r/g, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea|)$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each(function() { jQuery.removeAttr( this, name ); }); }, prop: function( name, value ) { return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); }, addClass: function( value ) { var classNames, i, l, elem, setClass, c, cl; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).addClass( value.call(this, j, this.className) ); }); } if ( value && typeof value === "string" ) { classNames = value.split( core_rspace ); for ( i = 0, l = this.length; i < l; i++ ) { elem = this[ i ]; if ( elem.nodeType === 1 ) { if ( !elem.className && classNames.length === 1 ) { elem.className = value; } else { setClass = " " + elem.className + " "; for ( c = 0, cl = classNames.length; c < cl; c++ ) { if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { setClass += classNames[ c ] + " "; } } elem.className = jQuery.trim( setClass ); } } } } return this; }, removeClass: function( value ) { var removes, className, elem, c, cl, i, l; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).removeClass( value.call(this, j, this.className) ); }); } if ( (value && typeof value === "string") || value === undefined ) { removes = ( value || "" ).split( core_rspace ); for ( i = 0, l = this.length; i < l; i++ ) { elem = this[ i ]; if ( elem.nodeType === 1 && elem.className ) { className = (" " + elem.className + " ").replace( rclass, " " ); // loop over each item in the removal list for ( c = 0, cl = removes.length; c < cl; c++ ) { // Remove until there is nothing to remove, while ( className.indexOf(" " + removes[ c ] + " ") > -1 ) { className = className.replace( " " + removes[ c ] + " " , " " ); } } elem.className = value ? jQuery.trim( className ) : ""; } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { return this.each(function( i ) { jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); }); } return this.each(function() { if ( type === "string" ) { // toggle individual class names var className, i = 0, self = jQuery( this ), state = stateVal, classNames = value.split( core_rspace ); while ( (className = classNames[ i++ ]) ) { // check each className given, space separated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( className ); } } else if ( type === "undefined" || type === "boolean" ) { if ( this.className ) { // store className if set jQuery._data( this, "__className__", this.className ); } // toggle whole className this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; } }); }, hasClass: function( selector ) { var className = " " + selector + " ", i = 0, l = this.length; for ( ; i < l; i++ ) { if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { return true; } } return false; }, val: function( value ) { var hooks, ret, isFunction, elem = this[0]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { return ret; } ret = elem.value; return typeof ret === "string" ? // handle most common string cases ret.replace(rreturn, "") : // handle cases where value is null/undef or number ret == null ? "" : ret; } return; } isFunction = jQuery.isFunction( value ); return this.each(function( i ) { var val, self = jQuery(this); if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call( this, i, self.val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( jQuery.isArray( val ) ) { val = jQuery.map(val, function ( value ) { return value == null ? "" : value + ""; }); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } }); } }); jQuery.extend({ valHooks: { option: { get: function( elem ) { // attributes.value is undefined in Blackberry 4.7 but // uses .value. See #6932 var val = elem.attributes.value; return !val || val.specified ? elem.value : elem.text; } }, select: { get: function( elem ) { var value, i, max, option, index = elem.selectedIndex, values = [], options = elem.options, one = elem.type === "select-one"; // Nothing was selected if ( index < 0 ) { return null; } // Loop through all the selected options i = one ? index : 0; max = one ? index + 1 : options.length; for ( ; i < max; i++ ) { option = options[ i ]; // Don't return options that are disabled or in a disabled optgroup if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } // Fixes Bug #2551 -- select.val() broken in IE after form.reset() if ( one && !values.length && options.length ) { return jQuery( options[ index ] ).val(); } return values; }, set: function( elem, value ) { var values = jQuery.makeArray( value ); jQuery(elem).find("option").each(function() { this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { elem.selectedIndex = -1; } return values; } } }, // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 attrFn: {}, attr: function( elem, name, value, pass ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { return jQuery( elem )[ name ]( value ); } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, "" + value ); return value; } } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined return ret === null ? undefined : ret; } }, removeAttr: function( elem, value ) { var propName, attrNames, name, isBool, i = 0; if ( value && elem.nodeType === 1 ) { attrNames = value.split( core_rspace ); for ( ; i < attrNames.length; i++ ) { name = attrNames[ i ]; if ( name ) { propName = jQuery.propFix[ name ] || name; isBool = rboolean.test( name ); // See #9699 for explanation of this approach (setting first, then removal) // Do not do this for boolean attributes (see #10870) if ( !isBool ) { jQuery.attr( elem, name, "" ); } elem.removeAttribute( getSetAttribute ? name : propName ); // Set corresponding property to false for boolean attributes if ( isBool && propName in elem ) { elem[ propName ] = false; } } } } }, attrHooks: { type: { set: function( elem, value ) { // We can't allow the type property to be changed (since it causes problems in IE) if ( rtype.test( elem.nodeName ) && elem.parentNode ) { jQuery.error( "type property can't be changed" ); } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { // Setting the type on a radio button after the value resets the value in IE6-9 // Reset value to it's default in case type is set after value // This is for element creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } }, // Use the value property for back compat // Use the nodeHook for button elements in IE6/7 (#1954) value: { get: function( elem, name ) { if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { return nodeHook.get( elem, name ); } return name in elem ? elem.value : null; }, set: function( elem, value, name ) { if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { return nodeHook.set( elem, value, name ); } // Does not return so that setAttribute is also used elem.value = value; } } }, propFix: { tabindex: "tabIndex", readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", cellspacing: "cellSpacing", cellpadding: "cellPadding", rowspan: "rowSpan", colspan: "colSpan", usemap: "useMap", frameborder: "frameBorder", contenteditable: "contentEditable" }, prop: function( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set properties on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( notxml ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return elem[ name ]; } } }, propHooks: { tabIndex: { get: function( elem ) { // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ var attributeNode = elem.getAttributeNode("tabindex"); return attributeNode && attributeNode.specified ? parseInt( attributeNode.value, 10 ) : rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 0 : undefined; } } } }); // Hook for boolean attributes boolHook = { get: function( elem, name ) { // Align boolean attributes with corresponding properties // Fall back to attribute presence where some booleans are not supported var attrNode, property = jQuery.prop( elem, name ); return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? name.toLowerCase() : undefined; }, set: function( elem, value, name ) { var propName; if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { // value is true since we know at this point it's type boolean and not false // Set boolean attributes to the same name and set the DOM property propName = jQuery.propFix[ name ] || name; if ( propName in elem ) { // Only set the IDL specifically if it already exists on the element elem[ propName ] = true; } elem.setAttribute( name, name.toLowerCase() ); } return name; } }; // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { fixSpecified = { name: true, id: true, coords: true }; // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret; ret = elem.getAttributeNode( name ); return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { ret = document.createAttribute( name ); elem.setAttributeNode( ret ); } return ( ret.value = value + "" ); } }; // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { if ( value === "" ) { value = "false"; } nodeHook.set( elem, value, name ); } }; } // Some attributes require a special call on IE if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret === null ? undefined : ret; } }); }); } if ( !jQuery.support.style ) { jQuery.attrHooks.style = { get: function( elem ) { // Return undefined in the case of empty string // Normalize to lowercase since IE uppercases css property names return elem.style.cssText.toLowerCase() || undefined; }, set: function( elem, value ) { return ( elem.style.cssText = "" + value ); } }; } // Safari mis-reports the default selected property of an option // Accessing the parent's selectedIndex property fixes it if ( !jQuery.support.optSelected ) { jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { get: function( elem ) { var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; // Make sure that it also works with optgroups, see #5701 if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } return null; } }); } // IE6/7 call enctype encoding if ( !jQuery.support.enctype ) { jQuery.propFix.enctype = "encoding"; } // Radios and checkboxes getter/setter if ( !jQuery.support.checkOn ) { jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { get: function( elem ) { // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified return elem.getAttribute("value") === null ? "on" : elem.value; } }; }); } jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); } } }); }); var rformElems = /^(?:textarea|input|select)$/i, rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, hoverHack = function( events ) { return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); }; /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { add: function( elem, types, handler, data, selector ) { var elemData, eventHandle, events, t, tns, type, namespaces, handleObj, handleObjIn, handlers, special; // Don't attach events to noData or text/comment nodes (allow plain objects tho) if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first events = elemData.events; if ( !events ) { elemData.events = events = {}; } eventHandle = elemData.handle; if ( !eventHandle ) { elemData.handle = eventHandle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events eventHandle.elem = elem; } // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = jQuery.trim( hoverHack(types) ).split( " " ); for ( t = 0; t < types.length; t++ ) { tns = rtypenamespace.exec( types[t] ) || []; type = tns[1]; namespaces = ( tns[2] || "" ).split( "." ).sort(); // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, origType: tns[1], data: data, handler: handler, guid: handler.guid, selector: selector, namespace: namespaces.join(".") }, handleObjIn ); // Init the event handler queue if we're the first handlers = events[ type ]; if ( !handlers ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener/attachEvent if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { // Bind the global event handler to the element if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle, false ); } else if ( elem.attachEvent ) { elem.attachEvent( "on" + type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } // Nullify elem to prevent memory leaks in IE elem = null; }, global: {}, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var t, tns, type, origType, namespaces, origCount, j, events, special, eventType, handleObj, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { return; } // Once for each type.namespace in types; type may be omitted types = jQuery.trim( hoverHack( types || "" ) ).split(" "); for ( t = 0; t < types.length; t++ ) { tns = rtypenamespace.exec( types[t] ) || []; type = origType = tns[1]; namespaces = tns[2]; // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector? special.delegateType : special.bindType ) || type; eventType = events[ type ] || []; origCount = eventType.length; namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; // Remove matching events for ( j = 0; j < eventType.length; j++ ) { handleObj = eventType[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !namespaces || namespaces.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { eventType.splice( j--, 1 ); if ( handleObj.selector ) { eventType.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( eventType.length === 0 && origCount !== eventType.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { delete elemData.handle; // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete jQuery.removeData( elem, "events", true ); } }, // Events that are safe to short-circuit if no handlers are attached. // Native DOM events should not be added, they may have inline handlers. customEvent: { "getData": true, "setData": true, "changeData": true }, trigger: function( event, data, elem, onlyHandlers ) { // Don't do events on text and comment nodes if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { return; } // Event object or event type var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, type = event.type || event, namespaces = []; // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "!" ) >= 0 ) { // Exclusive events trigger only for the exact event (no namespaces) type = type.slice(0, -1); exclusive = true; } if ( type.indexOf( "." ) >= 0 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); } if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { // No jQuery handlers for this event type, and it can't have inline handlers return; } // Caller can pass in an Event, Object, or just an event type string event = typeof event === "object" ? // jQuery.Event object event[ jQuery.expando ] ? event : // Object literal new jQuery.Event( type, event ) : // Just the event type (string) new jQuery.Event( type ); event.type = type; event.isTrigger = true; event.exclusive = exclusive; event.namespace = namespaces.join( "." ); event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; // Handle a global trigger if ( !elem ) { // TODO: Stop taunting the data cache; remove global events and always attach to document cache = jQuery.cache; for ( i in cache ) { if ( cache[ i ].events && cache[ i ].events[ type ] ) { jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); } } return; } // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data != null ? jQuery.makeArray( data ) : []; data.unshift( event ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) eventPath = [[ elem, special.bindType || type ]]; if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; for ( old = elem; cur; cur = cur.parentNode ) { eventPath.push([ cur, bubbleType ]); old = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( old === (elem.ownerDocument || document) ) { eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); } } // Fire handlers on the event path for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { cur = eventPath[i][0]; event.type = eventPath[i][1]; handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Note that this is a bare JS function and not a jQuery handler handle = ontype && cur[ ontype ]; if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { event.preventDefault(); } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction() check here because IE6/7 fails that test. // Don't do default actions on window, that's where global variables be (#6170) // IE<9 dies on focus/blur to hidden element (#1486) if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method old = elem[ ontype ]; if ( old ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; elem[ type ](); jQuery.event.triggered = undefined; if ( old ) { elem[ ontype ] = old; } } } } return event.result; }, dispatch: function( event ) { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event || window.event ); var i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related, handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), delegateCount = handlers.delegateCount, args = [].slice.call( arguments ), run_all = !event.exclusive && !event.namespace, special = jQuery.event.special[ event.type ] || {}, handlerQueue = []; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers that should run if there are delegated events // Avoid non-left-click bubbling in Firefox (#3861) if ( delegateCount && !(event.button && event.type === "click") ) { // Pregenerate a single jQuery object for reuse with .is() jqcur = jQuery(this); jqcur.context = this; for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #xxxx) if ( cur.disabled !== true || event.type !== "click" ) { selMatch = {}; matches = []; jqcur[0] = cur; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; sel = handleObj.selector; if ( selMatch[ sel ] === undefined ) { selMatch[ sel ] = jqcur.is( sel ); } if ( selMatch[ sel ] ) { matches.push( handleObj ); } } if ( matches.length ) { handlerQueue.push({ elem: cur, matches: matches }); } } } } // Add the remaining (directly-bound) handlers if ( handlers.length > delegateCount ) { handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); } // Run delegates first; they may want to stop propagation beneath us for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { matched = handlerQueue[ i ]; event.currentTarget = matched.elem; for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { handleObj = matched.matches[ j ]; // Triggered event must either 1) be non-exclusive and have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { event.data = handleObj.data; event.handleObj = handleObj; ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) .apply( matched.elem, args ); if ( ret !== undefined ) { event.result = ret; if ( ret === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, // Includes some event props shared by KeyEvent and MouseEvent // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), fixHooks: {}, keyHooks: { props: "char charCode key keyCode".split(" "), filter: function( event, original ) { // Add which for key events if ( event.which == null ) { event.which = original.charCode != null ? original.charCode : original.keyCode; } return event; } }, mouseHooks: { props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function( event, original ) { var eventDoc, doc, body, button = original.button, fromElement = original.fromElement; // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && original.clientX != null ) { eventDoc = event.target.ownerDocument || document; doc = eventDoc.documentElement; body = eventDoc.body; event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); } // Add relatedTarget, if necessary if ( !event.relatedTarget && fromElement ) { event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; } // Add which for click: 1 === left; 2 === middle; 3 === right // Note: button is not normalized, so don't use it if ( !event.which && button !== undefined ) { event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); } return event; } }, fix: function( event ) { if ( event[ jQuery.expando ] ) { return event; } // Create a writable copy of the event object and normalize some properties var i, prop, originalEvent = event, fixHook = jQuery.event.fixHooks[ event.type ] || {}, copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; event = jQuery.Event( originalEvent ); for ( i = copy.length; i; ) { prop = copy[ --i ]; event[ prop ] = originalEvent[ prop ]; } // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) if ( !event.target ) { event.target = originalEvent.srcElement || document; } // Target should not be a text node (#504, Safari) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; } // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) event.metaKey = !!event.metaKey; return fixHook.filter? fixHook.filter( event, originalEvent ) : event; }, special: { ready: { // Make sure the ready event is setup setup: jQuery.bindReady }, load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { delegateType: "focusin" }, blur: { delegateType: "focusout" }, beforeunload: { setup: function( data, namespaces, eventHandle ) { // We only want to do this special case on windows if ( jQuery.isWindow( this ) ) { this.onbeforeunload = eventHandle; } }, teardown: function( namespaces, eventHandle ) { if ( this.onbeforeunload === eventHandle ) { this.onbeforeunload = null; } } } }, simulate: function( type, elem, event, bubble ) { // Piggyback on a donor event to simulate a different one. // Fake originalEvent to avoid donor's stopPropagation, but if the // simulated event prevents default then we do the same on the donor. var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true, originalEvent: {} } ); if ( bubble ) { jQuery.event.trigger( e, null, elem ); } else { jQuery.event.dispatch.call( elem, e ); } if ( e.isDefaultPrevented() ) { event.preventDefault(); } } }; // Some plugins are using, but it's undocumented/deprecated and will be removed. // The 1.7 special event interface should provide all the hooks needed now. jQuery.event.handle = jQuery.event.dispatch; jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { elem.removeEventListener( type, handle, false ); } } : function( elem, type, handle ) { var name = "on" + type; if ( elem.detachEvent ) { // #8545, #7054, preventing memory leaks for custom events in IE6-8 – // detachEvent needed property on element, by name of that event, to properly expose it to GC if ( typeof elem[ name ] === "undefined" ) { elem[ name ] = null; } elem.detachEvent( name, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !(this instanceof jQuery.Event) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || jQuery.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; function returnFalse() { return false; } function returnTrue() { return true; } // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { preventDefault: function() { this.isDefaultPrevented = returnTrue; var e = this.originalEvent; if ( !e ) { return; } // if preventDefault exists run it on the original event if ( e.preventDefault ) { e.preventDefault(); // otherwise set the returnValue property of the original event to false (IE) } else { e.returnValue = false; } }, stopPropagation: function() { this.isPropagationStopped = returnTrue; var e = this.originalEvent; if ( !e ) { return; } // if stopPropagation exists run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } // otherwise set the cancelBubble property of the original event to true (IE) e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); }, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse }; // Create mouseenter/leave events using mouseover/out and event-time checks jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj, selector = handleObj.selector; // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || (related !== target && !jQuery.contains( target, related )) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; }); // IE submit delegation if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Lazy-add a submit handler when a descendant form may potentially be submitted jQuery.event.add( this, "click._submit keypress._submit", function( e ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; if ( form && !jQuery._data( form, "_submit_attached" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); jQuery._data( form, "_submit_attached", true ); } }); // return undefined since we don't need an event listener }, postDispatch: function( event ) { // If form was submitted by the user, bubble the event up the tree if ( event._submit_bubble ) { delete event._submit_bubble; if ( this.parentNode && !event.isTrigger ) { jQuery.event.simulate( "submit", this.parentNode, event, true ); } } }, teardown: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Remove delegated handlers; cleanData eventually reaps submit handlers attached above jQuery.event.remove( this, "._submit" ); } }; } // IE change delegation and checkbox/radio fix if ( !jQuery.support.changeBubbles ) { jQuery.event.special.change = { setup: function() { if ( rformElems.test( this.nodeName ) ) { // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if ( this.type === "checkbox" || this.type === "radio" ) { jQuery.event.add( this, "propertychange._change", function( event ) { if ( event.originalEvent.propertyName === "checked" ) { this._just_changed = true; } }); jQuery.event.add( this, "click._change", function( event ) { if ( this._just_changed && !event.isTrigger ) { this._just_changed = false; } // Allow triggered, simulated change events (#11500) jQuery.event.simulate( "change", this, event, true ); }); } return false; } // Delegated event; lazy-add a change handler on descendant inputs jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); jQuery._data( elem, "_change_attached", true ); } }); }, handle: function( event ) { var elem = event.target; // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { return event.handleObj.handler.apply( this, arguments ); } }, teardown: function() { jQuery.event.remove( this, "._change" ); return rformElems.test( this.nodeName ); } }; } // Create "bubbling" focus and blur events if ( !jQuery.support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler while someone wants focusin/focusout var attaches = 0, handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); }; jQuery.event.special[ fix ] = { setup: function() { if ( attaches++ === 0 ) { document.addEventListener( orig, handler, true ); } }, teardown: function() { if ( --attaches === 0 ) { document.removeEventListener( orig, handler, true ); } } }; }); } jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // && selector != null // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { this.on( type, selector, data, types[ type ], one ); } return this; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return this; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return this.each( function() { jQuery.event.add( this, types, fn, data, selector ); }); }, one: function( types, selector, data, fn ) { return this.on( types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each(function() { jQuery.event.remove( this, types, fn, selector ); }); }, bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, live: function( types, data, fn ) { jQuery( this.context ).on( types, this.selector, data, fn ); return this; }, die: function( types, fn ) { jQuery( this.context ).off( types, this.selector || "**", fn ); return this; }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, trigger: function( type, data ) { return this.each(function() { jQuery.event.trigger( type, data, this ); }); }, triggerHandler: function( type, data ) { if ( this[0] ) { return jQuery.event.trigger( type, data, this[0], true ); } }, toggle: function( fn ) { // Save reference to arguments for access in closure var args = arguments, guid = fn.guid || jQuery.guid++, i = 0, toggler = function( event ) { // Figure out which function to execute var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); // Make sure that clicks stop event.preventDefault(); // and execute the function return args[ lastToggle ].apply( this, arguments ) || false; }; // link all the functions, so any of them can unbind this click handler toggler.guid = guid; while ( i < args.length ) { args[ i++ ].guid = guid; } return this.click( toggler ); }, hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } }); jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { if ( fn == null ) { fn = data; data = null; } return arguments.length > 0 ? this.on( name, null, data, fn ) : this.trigger( name ); }; if ( rkeyEvent.test( name ) ) { jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; } if ( rmouseEvent.test( name ) ) { jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; } }); /*! * Sizzle CSS Selector Engine * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license * http://sizzlejs.com/ */ (function( window, undefined ) { var cachedruns, dirruns, sortOrder, siblingCheck, assertGetIdNotName, document = window.document, docElem = document.documentElement, strundefined = "undefined", hasDuplicate = false, baseHasDuplicate = true, done = 0, slice = [].slice, push = [].push, expando = ( "sizcache" + Math.random() ).replace( ".", "" ), // Regex // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/css3-syntax/#characters characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", // Loosely modeled on CSS identifier characters // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = characterEncoding.replace( "w", "w#" ), // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors operators = "([*^$|!~]?=)", attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)", pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)", combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*", groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcombinators = new RegExp( "^" + combinators ), // All simple (non-comma) selectors, excluding insignifant trailing whitespace rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ), // A selector, or everything after leading whitespace // Optionally followed in either case by a ")" for terminating sub-selectors rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ), // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ), // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, rsibling = /[\x20\t\r\n\f]*[+~]/, rendsWithNot = /:not\($/, rheader = /h\d/i, rinputs = /input|select|textarea|button/i, rbackslash = /\\(?!\\)/g, matchExpr = { "ID": new RegExp( "^#(" + characterEncoding + ")" ), "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "POS": new RegExp( pos, "ig" ), // For use in libraries implementing .is() "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) }, classCache = {}, cachedClasses = [], compilerCache = {}, cachedSelectors = [], // Mark a function for use in filtering markFunction = function( fn ) { fn.sizzleFilter = true; return fn; }, // Returns a function to use in pseudos for input types createInputFunction = function( type ) { return function( elem ) { // Check the input's nodeName and type return elem.nodeName.toLowerCase() === "input" && elem.type === type; }; }, // Returns a function to use in pseudos for buttons createButtonFunction = function( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; }, // Used for testing something on an element assert = function( fn ) { var pass = false, div = document.createElement("div"); try { pass = fn( div ); } catch (e) {} // release memory in IE div = null; return pass; }, // Check if attributes should be retrieved by attribute nodes assertAttributes = assert(function( div ) { div.innerHTML = ""; var type = typeof div.lastChild.getAttribute("multiple"); // IE8 returns a string for some attributes even when not present return type !== "boolean" && type !== "string"; }), // Check if getElementById returns elements by name // Check if getElementsByName privileges form controls or returns elements by ID assertUsableName = assert(function( div ) { // Inject content div.id = expando + 0; div.innerHTML = "
        "; docElem.insertBefore( div, docElem.firstChild ); // Test var pass = document.getElementsByName && // buggy browsers will return fewer than the correct 2 document.getElementsByName( expando ).length === // buggy browsers will return more than the correct 0 2 + document.getElementsByName( expando + 0 ).length; assertGetIdNotName = !document.getElementById( expando ); // Cleanup docElem.removeChild( div ); return pass; }), // Check if the browser returns only elements // when doing getElementsByTagName("*") assertTagNameNoComments = assert(function( div ) { div.appendChild( document.createComment("") ); return div.getElementsByTagName("*").length === 0; }), // Check if getAttribute returns normalized href attributes assertHrefNotNormalized = assert(function( div ) { div.innerHTML = ""; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }), // Check if getElementsByClassName can be trusted assertUsableClassName = assert(function( div ) { // Opera can't find a second classname (in 9.6) div.innerHTML = ""; if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { return false; } // Safari caches class attributes, doesn't catch changes (in 3.2) div.lastChild.className = "e"; return div.getElementsByClassName("e").length !== 1; }); var Sizzle = function( selector, context, results, seed ) { results = results || []; context = context || document; var match, elem, xml, m, nodeType = context.nodeType; if ( nodeType !== 1 && nodeType !== 9 ) { return []; } if ( !selector || typeof selector !== "string" ) { return results; } xml = isXML( context ); if ( !xml && !seed ) { if ( (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Speed-up: Sizzle("TAG") } else if ( match[2] ) { push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); return results; // Speed-up: Sizzle(".CLASS") } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); return results; } } } // All others return select( selector, context, results, seed, xml ); }; var Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, match: matchExpr, order: [ "ID", "TAG" ], attrHandle: {}, createPseudo: markFunction, find: { "ID": assertGetIdNotName ? function( id, context, xml ) { if ( typeof context.getElementById !== strundefined && !xml ) { var m = context.getElementById( id ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 return m && m.parentNode ? [m] : []; } } : function( id, context, xml ) { if ( typeof context.getElementById !== strundefined && !xml ) { var m = context.getElementById( id ); return m ? m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? [m] : undefined : []; } }, "TAG": assertTagNameNoComments ? function( tag, context ) { if ( typeof context.getElementsByTagName !== strundefined ) { return context.getElementsByTagName( tag ); } } : function( tag, context ) { var results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { var elem, tmp = [], i = 0; for ( ; (elem = results[i]); i++ ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; } }, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[1] = match[1].replace( rbackslash, "" ); // Move the given value to match[3] whether quoted or unquoted match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr.CHILD 1 type (only|nth|...) 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 3 xn-component of xn+y argument ([+-]?\d*n|) 4 sign of xn-component 5 x of xn-component 6 sign of y-component 7 y of y-component */ match[1] = match[1].toLowerCase(); if ( match[1] === "nth" ) { // nth-child requires argument if ( !match[2] ) { Sizzle.error( match[0] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); // other types prohibit arguments } else if ( match[2] ) { Sizzle.error( match[0] ); } return match; }, "PSEUDO": function( match ) { var argument, unquoted = match[4]; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } // Relinquish our claim on characters in `unquoted` from a closing parenthesis on if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) { match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 ); unquoted = argument[0].slice( 0, -1 ); } // Quoted or unquoted, we have the full argument // Return only captures needed by the pseudo filter method (type and argument) match.splice( 2, 3, unquoted || match[3] ); return match; } }, filter: { "ID": assertGetIdNotName ? function( id ) { id = id.replace( rbackslash, "" ); return function( elem ) { return elem.getAttribute("id") === id; }; } : function( id ) { id = id.replace( rbackslash, "" ); return function( elem ) { var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); return node && node.value === id; }; }, "TAG": function( nodeName ) { if ( nodeName === "*" ) { return function() { return true; }; } nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); return function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className ]; if ( !pattern ) { pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" ); cachedClasses.push( className ); // Avoid too large of a cache if ( cachedClasses.length > Expr.cacheLength ) { delete classCache[ cachedClasses.shift() ]; } } return function( elem ) { return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); }; }, "ATTR": function( name, operator, check ) { if ( !operator ) { return function( elem ) { return Sizzle.attr( elem, name ) != null; }; } return function( elem ) { var result = Sizzle.attr( elem, name ), value = result + ""; if ( result == null ) { return operator === "!="; } switch ( operator ) { case "=": return value === check; case "!=": return value !== check; case "^=": return check && value.indexOf( check ) === 0; case "*=": return check && value.indexOf( check ) > -1; case "$=": return check && value.substr( value.length - check.length ) === check; case "~=": return ( " " + value + " " ).indexOf( check ) > -1; case "|=": return value === check || value.substr( 0, check.length + 1 ) === check + "-"; } }; }, "CHILD": function( type, argument, first, last ) { if ( type === "nth" ) { var doneName = done++; return function( elem ) { var parent, diff, count = 0, node = elem; if ( first === 1 && last === 0 ) { return true; } parent = elem.parentNode; if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) { for ( node = parent.firstChild; node; node = node.nextSibling ) { if ( node.nodeType === 1 ) { node.sizset = ++count; if ( node === elem ) { break; } } } parent[ expando ] = doneName; } diff = elem.sizset - last; if ( first === 0 ) { return diff === 0; } else { return ( diff % first === 0 && diff / first >= 0 ); } }; } return function( elem ) { var node = elem; switch ( type ) { case "only": case "first": while ( (node = node.previousSibling) ) { if ( node.nodeType === 1 ) { return false; } } if ( type === "first" ) { return true; } node = elem; /* falls through */ case "last": while ( (node = node.nextSibling) ) { if ( node.nodeType === 1 ) { return false; } } return true; } }; }, "PSEUDO": function( pseudo, argument, context, xml ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ]; if ( !fn ) { Sizzle.error( "unsupported pseudo: " + pseudo ); } // The user may set fn.sizzleFilter to indicate // that arguments are needed to create the filter function // just as Sizzle does if ( !fn.sizzleFilter ) { return fn; } return fn( argument, context, xml ); } }, pseudos: { "not": markFunction(function( selector, context, xml ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var matcher = compile( selector.replace( rtrim, "$1" ), context, xml ); return function( elem ) { return !matcher( elem ); }; }), "enabled": function( elem ) { return elem.disabled === false; }, "disabled": function( elem ) { return elem.disabled === true; }, "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { elem.parentNode.selectedIndex; } return elem.selected === true; }, "parent": function( elem ) { return !Expr.pseudos["empty"]( elem ); }, "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), // not comment, processing instructions, or others // Thanks to Diego Perini for the nodeName shortcut // Greater than "@" means alpha characters (specifically not starting with "#" or "?") var nodeType; elem = elem.firstChild; while ( elem ) { if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { return false; } elem = elem.nextSibling; } return true; }, "contains": markFunction(function( text ) { return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), "has": markFunction(function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; }), "header": function( elem ) { return rheader.test( elem.nodeName ); }, "text": function( elem ) { var type, attr; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && (type = elem.type) === "text" && ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); }, // Input types "radio": createInputFunction("radio"), "checkbox": createInputFunction("checkbox"), "file": createInputFunction("file"), "password": createInputFunction("password"), "image": createInputFunction("image"), "submit": createButtonFunction("submit"), "reset": createButtonFunction("reset"), "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "focus": function( elem ) { var doc = elem.ownerDocument; return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href); }, "active": function( elem ) { return elem === elem.ownerDocument.activeElement; } }, setFilters: { "first": function( elements, argument, not ) { return not ? elements.slice( 1 ) : [ elements[0] ]; }, "last": function( elements, argument, not ) { var elem = elements.pop(); return not ? elements : [ elem ]; }, "even": function( elements, argument, not ) { var results = [], i = not ? 1 : 0, len = elements.length; for ( ; i < len; i = i + 2 ) { results.push( elements[i] ); } return results; }, "odd": function( elements, argument, not ) { var results = [], i = not ? 0 : 1, len = elements.length; for ( ; i < len; i = i + 2 ) { results.push( elements[i] ); } return results; }, "lt": function( elements, argument, not ) { return not ? elements.slice( +argument ) : elements.slice( 0, +argument ); }, "gt": function( elements, argument, not ) { return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 ); }, "eq": function( elements, argument, not ) { var elem = elements.splice( +argument, 1 ); return not ? elements : elem; } } }; // Deprecated Expr.setFilters["nth"] = Expr.setFilters["eq"]; // Back-compat Expr.filters = Expr.pseudos; // IE6/7 return a modified href if ( !assertHrefNotNormalized ) { Expr.attrHandle = { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; } // Add getElementsByName if usable if ( assertUsableName ) { Expr.order.push("NAME"); Expr.find["NAME"] = function( name, context ) { if ( typeof context.getElementsByName !== strundefined ) { return context.getElementsByName( name ); } }; } // Add getElementsByClassName if usable if ( assertUsableClassName ) { Expr.order.splice( 1, 0, "CLASS" ); Expr.find["CLASS"] = function( className, context, xml ) { if ( typeof context.getElementsByClassName !== strundefined && !xml ) { return context.getElementsByClassName( className ); } }; } // If slice is not available, provide a backup try { slice.call( docElem.childNodes, 0 )[0].nodeType; } catch ( e ) { slice = function( i ) { var elem, results = []; for ( ; (elem = this[i]); i++ ) { results.push( elem ); } return results; }; } var isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; // Element contains another var contains = Sizzle.contains = docElem.compareDocumentPosition ? function( a, b ) { return !!( a.compareDocumentPosition( b ) & 16 ); } : docElem.contains ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); } : function( a, b ) { while ( (b = b.parentNode) ) { if ( b === a ) { return true; } } return false; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ var getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( nodeType ) { if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (see #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes } else { // If no nodeType, this is expected to be an array for ( ; (node = elem[i]); i++ ) { // Do not traverse comment nodes ret += getText( node ); } } return ret; }; Sizzle.attr = function( elem, name ) { var attr, xml = isXML( elem ); if ( !xml ) { name = name.toLowerCase(); } if ( Expr.attrHandle[ name ] ) { return Expr.attrHandle[ name ]( elem ); } if ( assertAttributes || xml ) { return elem.getAttribute( name ); } attr = elem.getAttributeNode( name ); return attr ? typeof elem[ name ] === "boolean" ? elem[ name ] ? name : null : attr.specified ? attr.value : null : null; }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; // Check if the JavaScript engine is using some sort of // optimization where it does not always call our comparision // function. If that is the case, discard the hasDuplicate value. // Thus far that includes Google Chrome. [0, 0].sort(function() { return (baseHasDuplicate = 0); }); if ( docElem.compareDocumentPosition ) { sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; return 0; } return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? a.compareDocumentPosition : a.compareDocumentPosition(b) & 4 ) ? -1 : 1; }; } else { sortOrder = function( a, b ) { // The nodes are identical, we can exit early if ( a === b ) { hasDuplicate = true; return 0; // Fallback to using sourceIndex (in IE) if it's available on both nodes } else if ( a.sourceIndex && b.sourceIndex ) { return a.sourceIndex - b.sourceIndex; } var al, bl, ap = [], bp = [], aup = a.parentNode, bup = b.parentNode, cur = aup; // If the nodes are siblings (or identical) we can do a quick check if ( aup === bup ) { return siblingCheck( a, b ); // If no parents were found then the nodes are disconnected } else if ( !aup ) { return -1; } else if ( !bup ) { return 1; } // Otherwise they're somewhere else in the tree so we need // to build up a full list of the parentNodes for comparison while ( cur ) { ap.unshift( cur ); cur = cur.parentNode; } cur = bup; while ( cur ) { bp.unshift( cur ); cur = cur.parentNode; } al = ap.length; bl = bp.length; // Start walking down the tree looking for a discrepancy for ( var i = 0; i < al && i < bl; i++ ) { if ( ap[i] !== bp[i] ) { return siblingCheck( ap[i], bp[i] ); } } // We ended someplace up the tree so do a sibling check return i === al ? siblingCheck( a, bp[i], -1 ) : siblingCheck( ap[i], b, 1 ); }; siblingCheck = function( a, b, ret ) { if ( a === b ) { return ret; } var cur = a.nextSibling; while ( cur ) { if ( cur === b ) { return -1; } cur = cur.nextSibling; } return 1; }; } // Document sorting and removing duplicates Sizzle.uniqueSort = function( results ) { var elem, i = 1; if ( sortOrder ) { hasDuplicate = baseHasDuplicate; results.sort( sortOrder ); if ( hasDuplicate ) { for ( ; (elem = results[i]); i++ ) { if ( elem === results[ i - 1 ] ) { results.splice( i--, 1 ); } } } } return results; }; function multipleContexts( selector, contexts, results, seed ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results, seed ); } } function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) { var results, fn = Expr.setFilters[ posfilter.toLowerCase() ]; if ( !fn ) { Sizzle.error( posfilter ); } if ( selector || !(results = seed) ) { multipleContexts( selector || "*", contexts, (results = []), seed ); } return results.length > 0 ? fn( results, argument, not ) : []; } function handlePOS( selector, context, results, seed, groups ) { var match, not, anchor, ret, elements, currentContexts, part, lastIndex, i = 0, len = groups.length, rpos = matchExpr["POS"], // This is generated here in case matchExpr["POS"] is extended rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ), // This is for making sure non-participating // matching groups are represented cross-browser (IE6-8) setUndefined = function() { var i = 1, len = arguments.length - 2; for ( ; i < len; i++ ) { if ( arguments[i] === undefined ) { match[i] = undefined; } } }; for ( ; i < len; i++ ) { // Reset regex index to 0 rpos.exec(""); selector = groups[i]; ret = []; anchor = 0; elements = seed; while ( (match = rpos.exec( selector )) ) { lastIndex = rpos.lastIndex = match.index + match[0].length; if ( lastIndex > anchor ) { part = selector.slice( anchor, match.index ); anchor = lastIndex; currentContexts = [ context ]; if ( rcombinators.test(part) ) { if ( elements ) { currentContexts = elements; } elements = seed; } if ( (not = rendsWithNot.test( part )) ) { part = part.slice( 0, -5 ).replace( rcombinators, "$&*" ); } if ( match.length > 1 ) { match[0].replace( rposgroups, setUndefined ); } elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not ); } } if ( elements ) { ret = ret.concat( elements ); if ( (part = selector.slice( anchor )) && part !== ")" ) { if ( rcombinators.test(part) ) { multipleContexts( part, ret, results, seed ); } else { Sizzle( part, context, results, seed ? seed.concat(elements) : elements ); } } else { push.apply( results, ret ); } } else { Sizzle( selector, context, results, seed ); } } // Do not sort if this is a single filter return len === 1 ? results : Sizzle.uniqueSort( results ); } function tokenize( selector, context, xml ) { var tokens, soFar, type, groups = [], i = 0, // Catch obvious selector issues: terminal ")"; nonempty fallback match // rselector never fails to match *something* match = rselector.exec( selector ), matched = !match.pop() && !match.pop(), selectorGroups = matched && selector.match( rgroups ) || [""], preFilters = Expr.preFilter, filters = Expr.filter, checkContext = !xml && context !== document; for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) { groups.push( tokens = [] ); // Need to make sure we're within a narrower context if necessary // Adding a descendant combinator will generate what is needed if ( checkContext ) { soFar = " " + soFar; } while ( soFar ) { matched = false; // Combinators if ( (match = rcombinators.exec( soFar )) ) { soFar = soFar.slice( match[0].length ); // Cast descendant combinators to space matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match }); } // Filters for ( type in filters ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match, context, xml )) ) ) { soFar = soFar.slice( match.shift().length ); matched = tokens.push({ part: type, captures: match }); } } if ( !matched ) { break; } } } if ( !matched ) { Sizzle.error( selector ); } return groups; } function addCombinator( matcher, combinator, context ) { var dir = combinator.dir, doneName = done++; if ( !matcher ) { // If there is no matcher to check, check against the context matcher = function( elem ) { return elem === context; }; } return combinator.first ? function( elem, context ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 ) { return matcher( elem, context ) && elem; } } } : function( elem, context ) { var cache, dirkey = doneName + "." + dirruns, cachedkey = dirkey + "." + cachedruns; while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 ) { if ( (cache = elem[ expando ]) === cachedkey ) { return elem.sizset; } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { if ( elem.sizset ) { return elem; } } else { elem[ expando ] = cachedkey; if ( matcher( elem, context ) ) { elem.sizset = true; return elem; } elem.sizset = false; } } } }; } function addMatcher( higher, deeper ) { return higher ? function( elem, context ) { var result = deeper( elem, context ); return result && higher( result === true ? elem : result, context ); } : deeper; } // ["TAG", ">", "ID", " ", "CLASS"] function matcherFromTokens( tokens, context, xml ) { var token, matcher, i = 0; for ( ; (token = tokens[i]); i++ ) { if ( Expr.relative[ token.part ] ) { matcher = addCombinator( matcher, Expr.relative[ token.part ], context ); } else { token.captures.push( context, xml ); matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) ); } } return matcher; } function matcherFromGroupMatchers( matchers ) { return function( elem, context ) { var matcher, j = 0; for ( ; (matcher = matchers[j]); j++ ) { if ( matcher(elem, context) ) { return true; } } return false; }; } var compile = Sizzle.compile = function( selector, context, xml ) { var tokens, group, i, cached = compilerCache[ selector ]; // Return a cached group function if already generated (context dependent) if ( cached && cached.context === context ) { return cached; } // Generate a function of recursive functions that can be used to check each element group = tokenize( selector, context, xml ); for ( i = 0; (tokens = group[i]); i++ ) { group[i] = matcherFromTokens( tokens, context, xml ); } // Cache the compiled function cached = compilerCache[ selector ] = matcherFromGroupMatchers( group ); cached.context = context; cached.runs = cached.dirruns = 0; cachedSelectors.push( selector ); // Ensure only the most recent are cached if ( cachedSelectors.length > Expr.cacheLength ) { delete compilerCache[ cachedSelectors.shift() ]; } return cached; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { return Sizzle( expr, null, null, [ elem ] ).length > 0; }; var select = function( selector, context, results, seed, xml ) { // Remove excessive whitespace selector = selector.replace( rtrim, "$1" ); var elements, matcher, i, len, elem, token, type, findContext, notTokens, match = selector.match( rgroups ), tokens = selector.match( rtokens ), contextNodeType = context.nodeType; // POS handling if ( matchExpr["POS"].test(selector) ) { return handlePOS( selector, context, results, seed, match ); } if ( seed ) { elements = slice.call( seed, 0 ); // To maintain document order, only narrow the // set if there is one group } else if ( match && match.length === 1 ) { // Take a shortcut and set the context if the root selector is an ID if ( tokens.length > 1 && contextNodeType === 9 && !xml && (match = matchExpr["ID"].exec( tokens[0] )) ) { context = Expr.find["ID"]( match[1], context, xml )[0]; if ( !context ) { return results; } selector = selector.slice( tokens.shift().length ); } findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context; // Get the last token, excluding :not notTokens = tokens.pop(); token = notTokens.split(":not")[0]; for ( i = 0, len = Expr.order.length; i < len; i++ ) { type = Expr.order[i]; if ( (match = matchExpr[ type ].exec( token )) ) { elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml ); if ( elements == null ) { continue; } if ( token === notTokens ) { selector = selector.slice( 0, selector.length - notTokens.length ) + token.replace( matchExpr[ type ], "" ); if ( !selector ) { push.apply( results, slice.call(elements, 0) ); } } break; } } } // Only loop over the given elements once // If selector is empty, we're already done if ( selector ) { matcher = compile( selector, context, xml ); dirruns = matcher.dirruns++; if ( elements == null ) { elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context ); } for ( i = 0; (elem = elements[i]); i++ ) { cachedruns = matcher.runs++; if ( matcher(elem, context) ) { results.push( elem ); } } } return results; }; if ( document.querySelectorAll ) { (function() { var disconnectedMatch, oldSelect = select, rescape = /'|\\/g, rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, rbuggyQSA = [], // matchesSelector(:active) reports false when true (IE9/Opera 11.5) // A support test would require too much code (would include document ready) // just skip matchesSelector for :active rbuggyMatches = [":active"], matches = docElem.matchesSelector || docElem.mozMatchesSelector || docElem.webkitMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector; // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( div ) { div.innerHTML = ""; // IE8 - Some boolean attributes are not treated correctly if ( !div.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here (do not put tests after this one) if ( !div.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } }); assert(function( div ) { // Opera 10-12/IE9 - ^= $= *= and empty values // Should not select anything div.innerHTML = "

        "; if ( div.querySelectorAll("[test^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here (do not put tests after this one) div.innerHTML = ""; if ( !div.querySelectorAll(":enabled").length ) { rbuggyQSA.push(":enabled", ":disabled"); } }); rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); select = function( selector, context, results, seed, xml ) { // Only use querySelectorAll when not filtering, // when this is not xml, // and when no QSA bugs apply if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { if ( context.nodeType === 9 ) { try { push.apply( results, slice.call(context.querySelectorAll( selector ), 0) ); return results; } catch(qsaError) {} // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { var old = context.getAttribute("id"), nid = old || expando, newContext = rsibling.test( selector ) && context.parentNode || context; if ( old ) { nid = nid.replace( rescape, "\\$&" ); } else { context.setAttribute( "id", nid ); } try { push.apply( results, slice.call( newContext.querySelectorAll( selector.replace( rgroups, "[id='" + nid + "'] $&" ) ), 0 ) ); return results; } catch(qsaError) { } finally { if ( !old ) { context.removeAttribute("id"); } } } } return oldSelect( selector, context, results, seed, xml ); }; if ( matches ) { assert(function( div ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) disconnectedMatch = matches.call( div, "div" ); // This should fail with an exception // Gecko does not error, returns false instead try { matches.call( div, "[test!='']:sizzle" ); rbuggyMatches.push( Expr.match.PSEUDO ); } catch ( e ) {} }); // rbuggyMatches always contains :active, so no need for a length check rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); Sizzle.matchesSelector = function( elem, expr ) { // Make sure that attribute selectors are quoted expr = expr.replace( rattributeQuotes, "='$1']" ); // rbuggyMatches always contains :active, so no need for an existence check if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch(e) {} } return Sizzle( expr, null, null, [ elem ] ).length > 0; }; } })(); } // Override sizzle attribute retrieval Sizzle.attr = jQuery.attr; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; })( window ); var runtil = /Until$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, rneedsContext = jQuery.expr.match.needsContext, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend({ find: function( selector ) { var i, l, length, n, r, ret, self = this; if ( typeof selector !== "string" ) { return jQuery( selector ).filter(function() { for ( i = 0, l = self.length; i < l; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }); } ret = this.pushStack( "", "find", selector ); for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique for ( n = length; n < ret.length; n++ ) { for ( r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; } } } } } return ret; }, has: function( target ) { var i, targets = jQuery( target, this ), len = targets.length; return this.filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } } }); }, not: function( selector ) { return this.pushStack( winnow(this, selector, false), "not", selector); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true), "filter", selector ); }, is: function( selector ) { return !!selector && ( typeof selector === "string" ? // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". rneedsContext.test( selector ) ? jQuery( selector, this.context ).index( this[0] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, ret = [], pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0; for ( ; i < l; i++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } cur = cur.parentNode; } } ret = ret.length > 1 ? jQuery.unique( ret ) : ret; return this.pushStack( ret, "closest", selectors ); }, // Determine the position of an element within // the matched set of elements index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; } // index in selector if ( typeof elem === "string" ) { return jQuery.inArray( this[0], jQuery( elem ) ); } // Locate the position of the desired element return jQuery.inArray( // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem, this ); }, add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? all : jQuery.unique( all ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) ); } }); jQuery.fn.andSelf = jQuery.fn.addBack; // A painfully simple check to see if an element is disconnected // from a document (should be improved, where feasible). function isDisconnected( node ) { return !node || !node.parentNode || node.parentNode.nodeType === 11; } function sibling( cur, dir ) { do { cur = cur[ dir ]; } while ( cur && cur.nodeType !== 1 ); return cur; } jQuery.each({ parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return jQuery.dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return jQuery.dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return jQuery.dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return jQuery.dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return jQuery.dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return jQuery.dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return jQuery.sibling( elem.firstChild ); }, contents: function( elem ) { return jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ); if ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); } ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); } return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, dir: function( elem, dir, until ) { var matched = [], cur = elem[ dir ]; while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { if ( cur.nodeType === 1 ) { matched.push( cur ); } cur = cur[dir]; } return matched; }, sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; } }); // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem, i ) { return ( elem === qualifier ) === keep; }); } else if ( typeof qualifier === "string" ) { var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { qualifier = jQuery.filter( qualifier, filtered ); } } return jQuery.grep(elements, function( elem, i ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); } function createSafeFragment( document ) { var list = nodeNames.split( "|" ), safeFrag = document.createDocumentFragment(); if ( safeFrag.createElement ) { while ( list.length ) { safeFrag.createElement( list.pop() ); } } return safeFrag; } var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, rtagName = /<([\w:]+)/, rtbody = /]", "i"), rcheckableType = /^(?:checkbox|radio)$/, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rscriptType = /\/(java|ecma)script/i, rcleanScript = /^\s*\s*$/g, wrapMap = { option: [ 1, "" ], legend: [ 1, "
        ", "
        " ], thead: [ 1, "", "
        " ], tr: [ 2, "", "
        " ], td: [ 3, "", "
        " ], col: [ 2, "", "
        " ], area: [ 1, "", "" ], _default: [ 0, "", "" ] }, safeFragment = createSafeFragment( document ), fragmentDiv = safeFragment.appendChild( document.createElement("div") ); wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. if ( !jQuery.support.htmlSerialize ) { wrapMap._default = [ 1, "X
        ", "
        " ]; } jQuery.fn.extend({ text: function( value ) { return jQuery.access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); }, null, value, arguments.length ); }, wrapAll: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each(function(i) { jQuery(this).wrapAll( html.call(this, i) ); }); } if ( this[0] ) { // The elements to wrap the target around var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); if ( this[0].parentNode ) { wrap.insertBefore( this[0] ); } wrap.map(function() { var elem = this; while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { elem = elem.firstChild; } return elem; }).append( this ); } return this; }, wrapInner: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each(function(i) { jQuery(this).wrapInner( html.call(this, i) ); }); } return this.each(function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } }); }, wrap: function( html ) { var isFunction = jQuery.isFunction( html ); return this.each(function(i) { jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); }); }, unwrap: function() { return this.parent().each(function() { if ( !jQuery.nodeName( this, "body" ) ) { jQuery( this ).replaceWith( this.childNodes ); } }).end(); }, append: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 ) { this.appendChild( elem ); } }); }, prepend: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 ) { this.insertBefore( elem, this.firstChild ); } }); }, before: function() { if ( !isDisconnected( this[0] ) ) { return this.domManip(arguments, false, function( elem ) { this.parentNode.insertBefore( elem, this ); }); } if ( arguments.length ) { var set = jQuery.clean( arguments ); return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); } }, after: function() { if ( !isDisconnected( this[0] ) ) { return this.domManip(arguments, false, function( elem ) { this.parentNode.insertBefore( elem, this.nextSibling ); }); } if ( arguments.length ) { var set = jQuery.clean( arguments ); return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); } }, // keepData is for internal use only--do not document remove: function( selector, keepData ) { var elem, i = 0; for ( ; (elem = this[i]) != null; i++ ) { if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { if ( !keepData && elem.nodeType === 1 ) { jQuery.cleanData( elem.getElementsByTagName("*") ); jQuery.cleanData( [ elem ] ); } if ( elem.parentNode ) { elem.parentNode.removeChild( elem ); } } } return this; }, empty: function() { var elem, i = 0; for ( ; (elem = this[i]) != null; i++ ) { // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( elem.getElementsByTagName("*") ); } // Remove any remaining nodes while ( elem.firstChild ) { elem.removeChild( elem.firstChild ); } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function () { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); }); }, html: function( value ) { return jQuery.access( this, function( value ) { var elem = this[0] || {}, i = 0, l = this.length; if ( value === undefined ) { return elem.nodeType === 1 ? elem.innerHTML.replace( rinlinejQuery, "" ) : undefined; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { value = value.replace( rxhtmlTag, "<$1>" ); try { for (; i < l; i++ ) { // Remove element nodes and prevent memory leaks elem = this[i] || {}; if ( elem.nodeType === 1 ) { jQuery.cleanData( elem.getElementsByTagName( "*" ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch(e) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function( value ) { if ( !isDisconnected( this[0] ) ) { // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( jQuery.isFunction( value ) ) { return this.each(function(i) { var self = jQuery(this), old = self.html(); self.replaceWith( value.call( this, i, old ) ); }); } if ( typeof value !== "string" ) { value = jQuery( value ).detach(); } return this.each(function() { var next = this.nextSibling, parent = this.parentNode; jQuery( this ).remove(); if ( next ) { jQuery(next).before( value ); } else { jQuery(parent).append( value ); } }); } return this.length ? this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : this; }, detach: function( selector ) { return this.remove( selector, true ); }, domManip: function( args, table, callback ) { // Flatten any nested arrays args = [].concat.apply( [], args ); var results, first, fragment, iNoClone, i = 0, value = args[0], scripts = [], l = this.length; // We can't cloneNode fragments that contain checked, in WebKit if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { return this.each(function() { jQuery(this).domManip( args, table, callback ); }); } if ( jQuery.isFunction(value) ) { return this.each(function(i) { var self = jQuery(this); args[0] = value.call( this, i, table ? self.html() : undefined ); self.domManip( args, table, callback ); }); } if ( this[0] ) { results = jQuery.buildFragment( args, this, scripts ); fragment = results.fragment; first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } if ( first ) { table = table && jQuery.nodeName( first, "tr" ); // Use the original fragment for the last item instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). // Fragments from the fragment cache must always be cloned and never used in place. for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { callback.call( table && jQuery.nodeName( this[i], "table" ) ? findOrAppend( this[i], "tbody" ) : this[i], i === iNoClone ? fragment : jQuery.clone( fragment, true, true ) ); } } // Fix #11809: Avoid leaking memory fragment = first = null; if ( scripts.length ) { jQuery.each( scripts, function( i, elem ) { if ( elem.src ) { if ( jQuery.ajax ) { jQuery.ajax({ url: elem.src, type: "GET", dataType: "script", async: false, global: false, "throws": true }); } else { jQuery.error("no ajax"); } } else { jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); } if ( elem.parentNode ) { elem.parentNode.removeChild( elem ); } }); } } return this; } }); function findOrAppend( elem, tag ) { return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); } function cloneCopyEvent( src, dest ) { if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { return; } var type, i, l, oldData = jQuery._data( src ), curData = jQuery._data( dest, oldData ), events = oldData.events; if ( events ) { delete curData.handle; curData.events = {}; for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } // make the cloned public data object a copy from the original if ( curData.data ) { curData.data = jQuery.extend( {}, curData.data ); } } function cloneFixAttributes( src, dest ) { var nodeName; // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } // clearAttributes removes the attributes, which we don't want, // but also removes the attachEvent events, which we *do* want if ( dest.clearAttributes ) { dest.clearAttributes(); } // mergeAttributes, in contrast, only merges back on the // original attributes, not the events if ( dest.mergeAttributes ) { dest.mergeAttributes( src ); } nodeName = dest.nodeName.toLowerCase(); if ( nodeName === "object" ) { // IE6-10 improperly clones children of object elements using classid. // IE10 throws NoModificationAllowedError if parent is null, #12132. if ( dest.parentNode ) { dest.outerHTML = src.outerHTML; } // This path appears unavoidable for IE9. When cloning an object // element in IE9, the outerHTML strategy above is not sufficient. // If the src has innerHTML and the destination does not, // copy the src.innerHTML into the dest.innerHTML. #10324 if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { dest.innerHTML = src.innerHTML; } } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set dest.defaultChecked = dest.checked = src.checked; // IE6-7 get confused and end up setting the value of a cloned // checkbox/radio button to an empty string instead of "on" if ( dest.value !== src.value ) { dest.value = src.value; } // IE6-8 fails to return the selected option to the default selected // state when cloning options } else if ( nodeName === "option" ) { dest.selected = src.defaultSelected; // IE6-8 fails to set the defaultValue to the correct value when // cloning other types of input fields } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; // IE blanks contents when cloning scripts } else if ( nodeName === "script" && dest.text !== src.text ) { dest.text = src.text; } // Event data gets referenced instead of copied if the expando // gets copied too dest.removeAttribute( jQuery.expando ); } jQuery.buildFragment = function( args, context, scripts ) { var fragment, cacheable, cachehit, first = args[ 0 ]; // Set context from what may come in as undefined or a jQuery collection or a node context = context || document; context = (context[0] || context).ownerDocument || context[0] || context; // Ensure that an attr object doesn't incorrectly stand in as a document object // Chrome and Firefox seem to allow this to occur and will throw exception // Fixes #8950 if ( typeof context.createDocumentFragment === "undefined" ) { context = document; } // Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Cloning options loses the selected state, so don't cache them // IE 6 doesn't like it when you put or elements in a fragment // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && first.charAt(0) === "<" && !rnocache.test( first ) && (jQuery.support.checkClone || !rchecked.test( first )) && (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { // Mark cacheable and look for a hit cacheable = true; fragment = jQuery.fragments[ first ]; cachehit = fragment !== undefined; } if ( !fragment ) { fragment = context.createDocumentFragment(); jQuery.clean( args, context, fragment, scripts ); // Update the cache, but only store false // unless this is a second parsing of the same content if ( cacheable ) { jQuery.fragments[ first ] = cachehit && fragment; } } return { fragment: fragment, cacheable: cacheable }; }; jQuery.fragments = {}; jQuery.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, i = 0, ret = [], insert = jQuery( selector ), l = insert.length, parent = this.length === 1 && this[0].parentNode; if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { insert[ original ]( this[0] ); return this; } else { for ( ; i < l; i++ ) { elems = ( i > 0 ? this.clone(true) : this ).get(); jQuery( insert[i] )[ original ]( elems ); ret = ret.concat( elems ); } return this.pushStack( ret, name, insert.selector ); } }; }); function getAll( elem ) { if ( typeof elem.getElementsByTagName !== "undefined" ) { return elem.getElementsByTagName( "*" ); } else if ( typeof elem.querySelectorAll !== "undefined" ) { return elem.querySelectorAll( "*" ); } else { return []; } } // Used in clean, fixes the defaultChecked property function fixDefaultChecked( elem ) { if ( rcheckableType.test( elem.type ) ) { elem.defaultChecked = elem.checked; } } jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var srcElements, destElements, i, clone; if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { clone = elem.cloneNode( true ); // IE<=8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML; fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); } if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // IE copies events bound via attachEvent when using cloneNode. // Calling detachEvent on the clone will also remove the events // from the original. In order to get around this, we use some // proprietary methods to clear the events. Thanks to MooTools // guys for this hotness. cloneFixAttributes( elem, clone ); // Using Sizzle here is crazy slow, so we use getElementsByTagName instead srcElements = getAll( elem ); destElements = getAll( clone ); // Weird iteration because IE will replace the length property // with an element if you are cloning the body and one of the // elements on the page has a name or id of "length" for ( i = 0; srcElements[i]; ++i ) { // Ensure that the destination node is not null; Fixes #9587 if ( destElements[i] ) { cloneFixAttributes( srcElements[i], destElements[i] ); } } } // Copy the events from the original to the clone if ( dataAndEvents ) { cloneCopyEvent( elem, clone ); if ( deepDataAndEvents ) { srcElements = getAll( elem ); destElements = getAll( clone ); for ( i = 0; srcElements[i]; ++i ) { cloneCopyEvent( srcElements[i], destElements[i] ); } } } srcElements = destElements = null; // Return the cloned set return clone; }, clean: function( elems, context, fragment, scripts ) { var j, safe, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, i = 0, ret = []; // Ensure that context is a document if ( !context || typeof context.createDocumentFragment === "undefined" ) { context = document; } // Use the already-created safe fragment if context permits for ( safe = context === document && safeFragment; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { elem += ""; } if ( !elem ) { continue; } // Convert html string into DOM nodes if ( typeof elem === "string" ) { if ( !rhtml.test( elem ) ) { elem = context.createTextNode( elem ); } else { // Ensure a safe container in which to render the html safe = safe || createSafeFragment( context ); div = div || safe.appendChild( context.createElement("div") ); // Fix "XHTML"-style tags in all browsers elem = elem.replace(rxhtmlTag, "<$1>"); // Go to html and back, then peel off extra wrappers tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; depth = wrap[0]; div.innerHTML = wrap[1] + elem + wrap[2]; // Move to the right depth while ( depth-- ) { div = div.lastChild; } // Remove IE's autoinserted from table fragments if ( !jQuery.support.tbody ) { // String was a , *may* have spurious hasBody = rtbody.test(elem); tbody = tag === "table" && !hasBody ? div.firstChild && div.firstChild.childNodes : // String was a bare or wrap[1] === "
        " && !hasBody ? div.childNodes : []; for ( j = tbody.length - 1; j >= 0 ; --j ) { if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { tbody[ j ].parentNode.removeChild( tbody[ j ] ); } } } // IE completely kills leading whitespace when innerHTML is used if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); } elem = div.childNodes; // Remember the top-level container for proper cleanup div = safe.lastChild; } } if ( elem.nodeType ) { ret.push( elem ); } else { ret = jQuery.merge( ret, elem ); } } // Fix #11356: Clear elements from safeFragment if ( div ) { safe.removeChild( div ); elem = div = safe = null; } // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { for ( i = 0; (elem = ret[i]) != null; i++ ) { if ( jQuery.nodeName( elem, "input" ) ) { fixDefaultChecked( elem ); } else if ( typeof elem.getElementsByTagName !== "undefined" ) { jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); } } } // Append elements to a provided document fragment if ( fragment ) { // Special handling of each script element handleScript = function( elem ) { // Check if we consider it executable if ( !elem.type || rscriptType.test( elem.type ) ) { // Detach the script and store it in the scripts array (if provided) or the fragment // Return truthy to indicate that it has been handled return scripts ? scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : fragment.appendChild( elem ); } }; for ( i = 0; (elem = ret[i]) != null; i++ ) { // Check if we're done after handling an executable script if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { // Append to fragment and handle embedded scripts fragment.appendChild( elem ); if ( typeof elem.getElementsByTagName !== "undefined" ) { // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); // Splice the scripts into ret after their former ancestor and advance our index beyond them ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); i += jsTags.length; } } } } return ret; }, cleanData: function( elems, /* internal */ acceptData ) { var data, id, elem, type, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, deleteExpando = jQuery.support.deleteExpando, special = jQuery.event.special; for ( ; (elem = elems[i]) != null; i++ ) { if ( acceptData || jQuery.acceptData( elem ) ) { id = elem[ internalKey ]; data = id && cache[ id ]; if ( data ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Remove cache only if it was not already removed by jQuery.event.remove if ( cache[ id ] ) { delete cache[ id ]; // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if ( deleteExpando ) { delete elem[ internalKey ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } jQuery.deletedIds.push( id ); } } } } } }); // Limit scope pollution from any deprecated API (function() { var matched, browser; // Use of jQuery.browser is frowned upon. // More details: http://api.jquery.com/jQuery.browser // jQuery.uaMatch maintained for back-compat jQuery.uaMatch = function( ua ) { ua = ua.toLowerCase(); var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || /(webkit)[ \/]([\w.]+)/.exec( ua ) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || /(msie) ([\w.]+)/.exec( ua ) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || []; return { browser: match[ 1 ] || "", version: match[ 2 ] || "0" }; }; matched = jQuery.uaMatch( navigator.userAgent ); browser = {}; if ( matched.browser ) { browser[ matched.browser ] = true; browser.version = matched.version; } // Deprecated, use jQuery.browser.webkit instead // Maintained for back-compat only if ( browser.webkit ) { browser.safari = true; } jQuery.browser = browser; jQuery.sub = function() { function jQuerySub( selector, context ) { return new jQuerySub.fn.init( selector, context ); } jQuery.extend( true, jQuerySub, this ); jQuerySub.superclass = this; jQuerySub.fn = jQuerySub.prototype = this(); jQuerySub.fn.constructor = jQuerySub; jQuerySub.sub = this.sub; jQuerySub.fn.init = function init( selector, context ) { if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { context = jQuerySub( context ); } return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); }; jQuerySub.fn.init.prototype = jQuerySub.fn; var rootjQuerySub = jQuerySub(document); return jQuerySub; }; })(); var curCSS, iframe, iframeDoc, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, rposition = /^(top|right|bottom|left)$/, rmargin = /^margin/, rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), elemdisplay = {}, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: 0, fontWeight: 400, lineHeight: 1 }, cssExpand = [ "Top", "Right", "Bottom", "Left" ], cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], eventsToggle = jQuery.fn.toggle; // return a css property mapped to a potentially vendor prefixed property function vendorPropName( style, name ) { // shortcut for names that are not vendor prefixed if ( name in style ) { return name; } // check for vendor prefixed names var capName = name.charAt(0).toUpperCase() + name.slice(1), origName = name, i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in style ) { return name; } } return origName; } function isHidden( elem, el ) { elem = el || elem; return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); } function showHide( elements, show ) { var elem, display, values = [], index = 0, length = elements.length; for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } values[ index ] = jQuery._data( elem, "olddisplay" ); if ( show ) { // Reset the inline display of this element to learn if it is // being hidden by cascaded rules or not if ( !values[ index ] && elem.style.display === "none" ) { elem.style.display = ""; } // Set elements which have been overridden with display: none // in a stylesheet to whatever the default browser style is // for such an element if ( elem.style.display === "" && isHidden( elem ) ) { values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); } } else { display = curCSS( elem, "display" ); if ( !values[ index ] && display !== "none" ) { jQuery._data( elem, "olddisplay", display ); } } } // Set the display of most of the elements in a second loop // to avoid the constant reflow for ( index = 0; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } if ( !show || elem.style.display === "none" || elem.style.display === "" ) { elem.style.display = show ? values[ index ] || "" : "none"; } } return elements; } jQuery.fn.extend({ css: function( name, value ) { return jQuery.access( this, function( elem, name, value ) { return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); }, show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state, fn2 ) { var bool = typeof state === "boolean"; if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { return eventsToggle.apply( this, arguments ); } return this.each(function() { if ( bool ? state : isHidden( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } }); } }); jQuery.extend({ // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Exclude the following css properties to add px cssNumber: { "fillOpacity": true, "fontWeight": true, "lineHeight": true, "opacity": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: { // normalize float css property "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" }, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = jQuery.camelCase( name ), style = elem.style; name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // convert relative number strings (+= or -=) to relative numbers. #7345 if ( type === "string" && (ret = rrelNum.exec( value )) ) { value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); // Fixes bug #9237 type = "number"; } // Make sure that NaN and null values aren't set. See: #7116 if ( value == null || type === "number" && isNaN( value ) ) { return; } // If a number was passed in, add 'px' to the (except for certain CSS properties) if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { // Wrapped to prevent IE from throwing errors when 'invalid' values are provided // Fixes bug #5509 try { style[ name ] = value; } catch(e) {} } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, numeric, extra ) { var val, num, hooks, origName = jQuery.camelCase( name ); // Make sure that we're working with the right name name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name ); } //convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Return, converting to number if forced or a qualifier was provided and val looks numeric if ( numeric || extra !== undefined ) { num = parseFloat( val ); return numeric || jQuery.isNumeric( num ) ? num || 0 : val; } return val; }, // A method for quickly swapping in/out CSS properties to get correct calculations swap: function( elem, options, callback ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; } }); // NOTE: To any future maintainer, we've used both window.getComputedStyle // and getComputedStyle here to produce a better gzip size if ( window.getComputedStyle ) { curCSS = function( elem, name ) { var ret, width, minWidth, maxWidth, computed = getComputedStyle( elem, null ), style = elem.style; if ( computed ) { ret = computed[ name ]; if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret; }; } else if ( document.documentElement.currentStyle ) { curCSS = function( elem, name ) { var left, rsLeft, ret = elem.currentStyle && elem.currentStyle[ name ], style = elem.style; // Avoid setting ret to empty string here // so we don't default to auto if ( ret == null && style && style[ name ] ) { ret = style[ name ]; } // From the awesome hack by Dean Edwards // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels // but not position css attributes, as those are proportional to the parent element instead // and we can't measure the parent instead because it might trigger a "stacking dolls" problem if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { // Remember the original values left = style.left; rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; // Put in the new values to get a computed value out if ( rsLeft ) { elem.runtimeStyle.left = elem.currentStyle.left; } style.left = name === "fontSize" ? "1em" : ret; ret = style.pixelLeft + "px"; // Revert the changed values style.left = left; if ( rsLeft ) { elem.runtimeStyle.left = rsLeft; } } return ret === "" ? "auto" : ret; }; } function setPositiveNumber( elem, value, subtract ) { var matches = rnumsplit.exec( value ); return matches ? Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : value; } function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { var i = extra === ( isBorderBox ? "border" : "content" ) ? // If we already have the right measurement, avoid augmentation 4 : // Otherwise initialize for horizontal or vertical properties name === "width" ? 1 : 0, val = 0; for ( ; i < 4; i += 2 ) { // both box models exclude margin, so add it if we want it if ( extra === "margin" ) { // we use jQuery.css instead of curCSS here // because of the reliableMarginRight CSS hook! val += jQuery.css( elem, extra + cssExpand[ i ], true ); } // From this point on we use curCSS for maximum performance (relevant in animations) if ( isBorderBox ) { // border-box includes padding, so remove it if we want content if ( extra === "content" ) { val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; } // at this point, extra isn't border nor margin, so remove border if ( extra !== "margin" ) { val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; } } else { // at this point, extra isn't content, so add padding val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; // at this point, extra isn't content nor padding, so add border if ( extra !== "padding" ) { val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; } } } return val; } function getWidthOrHeight( elem, name, extra ) { // Start with offset property, which is equivalent to the border-box value var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, valueIsBorderBox = true, isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; if ( val <= 0 ) { // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name ); if ( val < 0 || val == null ) { val = elem.style[ name ]; } // Computed unit is not pixels. Stop here and return. if ( rnumnonpx.test(val) ) { return val; } // we need the check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); // Normalize "", auto, and prepare for extra val = parseFloat( val ) || 0; } // use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, name, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox ) ) + "px"; } // Try to determine the default display value of an element function css_defaultDisplay( nodeName ) { if ( elemdisplay[ nodeName ] ) { return elemdisplay[ nodeName ]; } var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), display = elem.css("display"); elem.remove(); // If the simple way fails, // get element's real default display by attaching it to a temp iframe if ( display === "none" || display === "" ) { // Use the already-created iframe if possible iframe = document.body.appendChild( iframe || jQuery.extend( document.createElement("iframe"), { frameBorder: 0, width: 0, height: 0 }) ); // Create a cacheable copy of the iframe document on first call. // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML // document to it; WebKit & Firefox won't allow reusing the iframe document. if ( !iframeDoc || !iframe.createElement ) { iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; iframeDoc.write(""); iframeDoc.close(); } elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); display = curCSS( elem, "display" ); document.body.removeChild( iframe ); } // Store the correct default display elemdisplay[ nodeName ] = display; return display; } jQuery.each([ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { if ( computed ) { if ( elem.offsetWidth !== 0 || curCSS( elem, "display" ) !== "none" ) { return getWidthOrHeight( elem, name, extra ); } else { return jQuery.swap( elem, cssShow, function() { return getWidthOrHeight( elem, name, extra ); }); } } }, set: function( elem, value, extra ) { return setPositiveNumber( elem, value, extra ? augmentWidthOrHeight( elem, name, extra, jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" ) : 0 ); } }; }); if ( !jQuery.support.opacity ) { jQuery.cssHooks.opacity = { get: function( elem, computed ) { // IE uses filters for opacity return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : computed ? "1" : ""; }, set: function( elem, value ) { var style = elem.style, currentStyle = elem.currentStyle, opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", filter = currentStyle && currentStyle.filter || style.filter || ""; // IE has trouble with opacity if it does not have layout // Force it by setting the zoom level style.zoom = 1; // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && style.removeAttribute ) { // Setting style.filter to null, "" & " " still leave "filter:" in the cssText // if "filter:" is present at all, clearType is disabled, we want to avoid this // style.removeAttribute is IE Only, but so apparently is this code path... style.removeAttribute( "filter" ); // if there there is no filter style applied in a css rule, we are done if ( currentStyle && !currentStyle.filter ) { return; } } // otherwise, set new filter values style.filter = ralpha.test( filter ) ? filter.replace( ralpha, opacity ) : filter + " " + opacity; } }; } // These hooks cannot be added until DOM ready because the support test // for it is not run until after DOM ready jQuery(function() { if ( !jQuery.support.reliableMarginRight ) { jQuery.cssHooks.marginRight = { get: function( elem, computed ) { // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right // Work around by temporarily setting element display to inline-block return jQuery.swap( elem, { "display": "inline-block" }, function() { if ( computed ) { return curCSS( elem, "marginRight" ); } }); } }; } // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 // getComputedStyle returns percent when specified for top/left/bottom/right // rather than make the css module depend on the offset module, we just check for it here if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { jQuery.each( [ "top", "left" ], function( i, prop ) { jQuery.cssHooks[ prop ] = { get: function( elem, computed ) { if ( computed ) { var ret = curCSS( elem, prop ); // if curCSS returns percentage, fallback to offset return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; } } }; }); } }); if ( jQuery.expr && jQuery.expr.filters ) { jQuery.expr.filters.hidden = function( elem ) { return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); }; jQuery.expr.filters.visible = function( elem ) { return !jQuery.expr.filters.hidden( elem ); }; } // These hooks are used by animate to expand properties jQuery.each({ margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i, // assumes a single number if not a string parts = typeof value === "string" ? value.split(" ") : [ value ], expanded = {}; for ( i = 0; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( !rmargin.test( prefix ) ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } }); var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, rselectTextarea = /^(?:select|textarea)/i; jQuery.fn.extend({ serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map(function(){ return this.elements ? jQuery.makeArray( this.elements ) : this; }) .filter(function(){ return this.name && !this.disabled && ( this.checked || rselectTextarea.test( this.nodeName ) || rinput.test( this.type ) ); }) .map(function( i, elem ){ var val = jQuery( this ).val(); return val == null ? null : jQuery.isArray( val ) ? jQuery.map( val, function( val, i ){ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; }) : { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; }).get(); } }); //Serialize an array of form elements or a set of //key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, value ) { // If value is a function, invoke it and return its value value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); }; // Set traditional to true for jQuery <= 1.3.2 behavior. if ( traditional === undefined ) { traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; } // If an array was passed in, assume that it is an array of form elements. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); }); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ).replace( r20, "+" ); }; function buildParams( prefix, obj, traditional, add ) { var name; if ( jQuery.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // If array item is non-scalar (array or object), encode its // numeric index to resolve deserialization ambiguity issues. // Note that rack (as of 1.0.0) can't currently deserialize // nested arrays properly, and attempting to do so may cause // a server error. Possible fixes are to modify rack's // deserialization algorithm or to provide an option or flag // to force array serialization to be shallow. buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); } }); } else if ( !traditional && jQuery.type( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } var // Document location ajaxLocation, // Document location segments ajaxLocParts, rhash = /#.*$/, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, rscript = /)<[^<]*)*<\/script>/gi, rts = /([?&])_=[^&]*/, rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, // Keep a copy of the old load method _load = jQuery.fn.load, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = ["*/"] + ["*"]; // #8138, IE may throw an exception when accessing // a field from window.location if document.domain has been set try { ajaxLocation = location.href; } catch( e ) { // Use the href attribute of an A element // since IE will modify it given document.location ajaxLocation = document.createElement( "a" ); ajaxLocation.href = ""; ajaxLocation = ajaxLocation.href; } // Segment location into parts ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, list, placeBefore, dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), i = 0, length = dataTypes.length; if ( jQuery.isFunction( func ) ) { // For each dataType in the dataTypeExpression for ( ; i < length; i++ ) { dataType = dataTypes[ i ]; // We control if we're asked to add before // any existing element placeBefore = /^\+/.test( dataType ); if ( placeBefore ) { dataType = dataType.substr( 1 ) || "*"; } list = structure[ dataType ] = structure[ dataType ] || []; // then we add to the structure accordingly list[ placeBefore ? "unshift" : "push" ]( func ); } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, dataType /* internal */, inspected /* internal */ ) { dataType = dataType || options.dataTypes[ 0 ]; inspected = inspected || {}; inspected[ dataType ] = true; var selection, list = structure[ dataType ], i = 0, length = list ? list.length : 0, executeOnly = ( structure === prefilters ); for ( ; i < length && ( executeOnly || !selection ); i++ ) { selection = list[ i ]( options, originalOptions, jqXHR ); // If we got redirected to another dataType // we try there if executing only and not done already if ( typeof selection === "string" ) { if ( !executeOnly || inspected[ selection ] ) { selection = undefined; } else { options.dataTypes.unshift( selection ); selection = inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, selection, inspected ); } } } // If we're only executing or nothing was selected // we try the catchall dataType if not done already if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { selection = inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, "*", inspected ); } // unnecessary when only executing (prefilters) // but it'll be ignored by the caller in that case return selection; } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } } jQuery.fn.load = function( url, params, callback ) { if ( typeof url !== "string" && _load ) { return _load.apply( this, arguments ); } // Don't do a request if no elements are being requested if ( !this.length ) { return this; } var selector, type, response, self = this, off = url.indexOf(" "); if ( off >= 0 ) { selector = url.slice( off, url.length ); url = url.slice( 0, off ); } // If it's a function if ( jQuery.isFunction( params ) ) { // We assume that it's the callback callback = params; params = undefined; // Otherwise, build a param string } else if ( typeof params === "object" ) { type = "POST"; } // Request the remote document jQuery.ajax({ url: url, // if "type" variable is undefined, then "GET" method will be used type: type, dataType: "html", data: params, complete: function( jqXHR, status ) { if ( callback ) { self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); } } }).done(function( responseText ) { // Save response for use in complete callback response = arguments; // See if a selector was specified self.html( selector ? // Create a dummy div to hold the results jQuery("
        ") // inject the contents of the document in, removing the scripts // to avoid any 'Permission Denied' errors in IE .append( responseText.replace( rscript, "" ) ) // Locate the specified elements .find( selector ) : // If not, just inject the full result responseText ); }); return this; }; // Attach a bunch of functions for handling common AJAX events jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ jQuery.fn[ o ] = function( f ){ return this.on( o, f ); }; }); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // shift arguments if data argument was omitted if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } return jQuery.ajax({ type: method, url: url, data: data, success: callback, dataType: type }); }; }); jQuery.extend({ getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { if ( settings ) { // Building a settings object ajaxExtend( target, jQuery.ajaxSettings ); } else { // Extending ajaxSettings settings = target; target = jQuery.ajaxSettings; } ajaxExtend( target, settings ); return target; }, ajaxSettings: { url: ajaxLocation, isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), global: true, type: "GET", contentType: "application/x-www-form-urlencoded; charset=UTF-8", processData: true, async: true, /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { xml: "application/xml, text/xml", html: "text/html", text: "text/plain", json: "application/json, text/javascript", "*": allTypes }, contents: { xml: /xml/, html: /html/, json: /json/ }, responseFields: { xml: "responseXML", text: "responseText" }, // List of data converters // 1) key format is "source_type destination_type" (a single space in-between) // 2) the catchall symbol "*" can be used for source_type converters: { // Convert anything to text "* text": window.String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": jQuery.parseJSON, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { context: true, url: true } }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var // ifModified key ifModifiedKey, // Response headers responseHeadersString, responseHeaders, // transport transport, // timeout handle timeoutTimer, // Cross-domain detection vars parts, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events // It's the callbackContext if one was provided in the options // and if it's a DOM node or a jQuery collection globalEventContext = callbackContext !== s && ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // The jqXHR state state = 0, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Caches the header setRequestHeader: function( name, value ) { if ( !state ) { var lname = name.toLowerCase(); name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; requestHeaders[ name ] = value; } return this; }, // Raw string getAllResponseHeaders: function() { return state === 2 ? responseHeadersString : null; }, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( state === 2 ) { if ( !responseHeaders ) { responseHeaders = {}; while( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; } } match = responseHeaders[ key.toLowerCase() ]; } return match === undefined ? null : match; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( !state ) { s.mimeType = type; } return this; }, // Cancel the request abort: function( statusText ) { statusText = statusText || strAbort; if ( transport ) { transport.abort( statusText ); } done( 0, statusText ); return this; } }; // Callback for when everything is done // It is defined here because jslint complains if it is declared // at the end of the function (which would be more logical and readable) function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Called once if ( state === 2 ) { return; } // State is "done" now state = 2; // Clear timeout if it exists if ( timeoutTimer ) { clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // If successful, handle type chaining if ( status >= 200 && status < 300 || status === 304 ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader("Last-Modified"); if ( modified ) { jQuery.lastModified[ ifModifiedKey ] = modified; } modified = jqXHR.getResponseHeader("Etag"); if ( modified ) { jQuery.etag[ ifModifiedKey ] = modified; } } // If not modified if ( status === 304 ) { statusText = "notmodified"; isSuccess = true; // If we have data } else { isSuccess = ajaxConvert( s, response ); statusText = isSuccess.state; success = isSuccess.data; error = isSuccess.error; isSuccess = !error; } } else { // We extract error from statusText // then normalize statusText and status for non-aborts error = statusText; if ( !statusText || status ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = "" + ( nativeStatusText || statusText ); // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } // Attach deferreds deferred.promise( jqXHR ); jqXHR.success = jqXHR.done; jqXHR.error = jqXHR.fail; jqXHR.complete = completeDeferred.add; // Status-dependent callbacks jqXHR.statusCode = function( map ) { if ( map ) { var tmp; if ( state < 2 ) { for ( tmp in map ) { statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; } } else { tmp = map[ jqXHR.status ]; jqXHR.always( tmp ); } } return this; }; // Remove hash character (#7531: and string promotion) // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) // We also use the url parameter if available s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); // Determine if a cross-domain request is in order if ( s.crossDomain == null ) { parts = rurl.exec( s.url.toLowerCase() ); s.crossDomain = !!( parts && ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) ); } // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there if ( state === 2 ) { return jqXHR; } // We can fire global events as of now if asked to fireGlobals = s.global; // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // More options handling for requests with no content if ( !s.hasContent ) { // If data is available, append data to url if ( s.data ) { s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Get ifModifiedKey before adding the anti-cache parameter ifModifiedKey = s.url; // Add anti-cache in url if needed if ( s.cache === false ) { var ts = jQuery.now(), // try replacing _= if it is there ret = s.url.replace( rts, "$1_=" + ts ); // if nothing was replaced, add timestamp to the end s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { ifModifiedKey = ifModifiedKey || s.url; if ( jQuery.lastModified[ ifModifiedKey ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); } if ( jQuery.etag[ ifModifiedKey ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); } } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { // Abort if not done already and return return jqXHR.abort(); } // aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds for ( i in { success: 1, error: 1, complete: 1 } ) { jqXHR[ i ]( s[ i ] ); } // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = setTimeout( function(){ jqXHR.abort( "timeout" ); }, s.timeout ); } try { state = 1; transport.send( requestHeaders, done ); } catch (e) { // Propagate exception as error if not done if ( state < 2 ) { done( -1, e ); // Simply rethrow otherwise } else { throw e; } } } return jqXHR; }, // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {} }); /* Handles responses to an ajax request: * - sets all responseXXX fields accordingly * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes, responseFields = s.responseFields; // Fill responseXXX fields for ( type in responseFields ) { if ( type in responses ) { jqXHR[ responseFields[type] ] = responses[ type ]; } } // Remove auto dataType and get content-type in the process while( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } // Chain conversions given the request and the original response function ajaxConvert( s, response ) { var conv, conv2, current, tmp, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(), prev = dataTypes[ 0 ], converters = {}, i = 0; // Apply the dataFilter if provided if ( s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } // Convert to each sequential dataType, tolerating list modification for ( ; (current = dataTypes[++i]); ) { // There's only work to do if current dataType is non-auto if ( current !== "*" ) { // Convert response if prev dataType is non-auto and differs from current if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split(" "); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.splice( i--, 0, current ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s["throws"] ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } // Update prev for next iteration prev = current; } } return { state: "success", data: response }; } var oldCallbacks = [], rquestion = /\?/, rjsonp = /(=)\?(?=&|$)|\?\?/, nonce = jQuery.now(); // Default jsonp settings jQuery.ajaxSetup({ jsonp: "callback", jsonpCallback: function() { var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); this[ callback ] = true; return callback; } }); // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer, data = s.data, url = s.url, hasCallback = s.jsonp !== false, replaceInUrl = hasCallback && rjsonp.test( url ), replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( data ); // Handle iff the expected data type is "jsonp" or we have a parameter to set if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { // Get callback name, remembering preexisting value associated with it callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback; overwritten = window[ callbackName ]; // Insert callback into url or form data if ( replaceInUrl ) { s.url = url.replace( rjsonp, "$1" + callbackName ); } else if ( replaceInData ) { s.data = data.replace( rjsonp, "$1" + callbackName ); } else if ( hasCallback ) { s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; } // Use data converter to retrieve json after script execution s.converters["script json"] = function() { if ( !responseContainer ) { jQuery.error( callbackName + " was not called" ); } return responseContainer[ 0 ]; }; // force json dataType s.dataTypes[ 0 ] = "json"; // Install callback window[ callbackName ] = function() { responseContainer = arguments; }; // Clean-up function (fires after converters) jqXHR.always(function() { // Restore preexisting value window[ callbackName ] = overwritten; // Save back as free if ( s[ callbackName ] ) { // make sure that re-using the options doesn't screw things around s.jsonpCallback = originalSettings.jsonpCallback; // save the callback name for future use oldCallbacks.push( callbackName ); } // Call if it was a function and we have a response if ( responseContainer && jQuery.isFunction( overwritten ) ) { overwritten( responseContainer[ 0 ] ); } responseContainer = overwritten = undefined; }); // Delegate to script return "script"; } }); // Install script dataType jQuery.ajaxSetup({ accepts: { script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" }, contents: { script: /javascript|ecmascript/ }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } }); // Handle cache's special case and global jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } if ( s.crossDomain ) { s.type = "GET"; s.global = false; } }); // Bind script tag hack transport jQuery.ajaxTransport( "script", function(s) { // This transport only deals with cross domain requests if ( s.crossDomain ) { var script, head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; return { send: function( _, callback ) { script = document.createElement( "script" ); script.async = "async"; if ( s.scriptCharset ) { script.charset = s.scriptCharset; } script.src = s.url; // Attach handlers for all browsers script.onload = script.onreadystatechange = function( _, isAbort ) { if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { // Handle memory leak in IE script.onload = script.onreadystatechange = null; // Remove the script if ( head && script.parentNode ) { head.removeChild( script ); } // Dereference the script script = undefined; // Callback if not abort if ( !isAbort ) { callback( 200, "success" ); } } }; // Use insertBefore instead of appendChild to circumvent an IE6 bug. // This arises when a base node is used (#2709 and #4378). head.insertBefore( script, head.firstChild ); }, abort: function() { if ( script ) { script.onload( 0, 1 ); } } }; } }); var xhrCallbacks, // #5280: Internet Explorer will keep connections alive if we don't abort on unload xhrOnUnloadAbort = window.ActiveXObject ? function() { // Abort all pending requests for ( var key in xhrCallbacks ) { xhrCallbacks[ key ]( 0, 1 ); } } : false, xhrId = 0; // Functions to create xhrs function createStandardXHR() { try { return new window.XMLHttpRequest(); } catch( e ) {} } function createActiveXHR() { try { return new window.ActiveXObject( "Microsoft.XMLHTTP" ); } catch( e ) {} } // Create the request object // (This is still attached to ajaxSettings for backward compatibility) jQuery.ajaxSettings.xhr = window.ActiveXObject ? /* Microsoft failed to properly * implement the XMLHttpRequest in IE7 (can't request local files), * so we use the ActiveXObject when it is available * Additionally XMLHttpRequest can be disabled in IE7/IE8 so * we need a fallback. */ function() { return !this.isLocal && createStandardXHR() || createActiveXHR(); } : // For all other browsers, use the standard XMLHttpRequest object createStandardXHR; // Determine support properties (function( xhr ) { jQuery.extend( jQuery.support, { ajax: !!xhr, cors: !!xhr && ( "withCredentials" in xhr ) }); })( jQuery.ajaxSettings.xhr() ); // Create transport if the browser can provide an xhr if ( jQuery.support.ajax ) { jQuery.ajaxTransport(function( s ) { // Cross domain only allowed if supported through XMLHttpRequest if ( !s.crossDomain || jQuery.support.cors ) { var callback; return { send: function( headers, complete ) { // Get a new xhr var handle, i, xhr = s.xhr(); // Open the socket // Passing null username, generates a login popup on Opera (#2865) if ( s.username ) { xhr.open( s.type, s.url, s.async, s.username, s.password ); } else { xhr.open( s.type, s.url, s.async ); } // Apply custom fields if provided if ( s.xhrFields ) { for ( i in s.xhrFields ) { xhr[ i ] = s.xhrFields[ i ]; } } // Override mime type if needed if ( s.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( s.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !s.crossDomain && !headers["X-Requested-With"] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Need an extra try/catch for cross domain requests in Firefox 3 try { for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } } catch( _ ) {} // Do send the request // This may raise an exception which is actually // handled in jQuery.ajax (so no try/catch here) xhr.send( ( s.hasContent && s.data ) || null ); // Listener callback = function( _, isAbort ) { var status, statusText, responseHeaders, responses, xml; // Firefox throws exceptions when accessing properties // of an xhr when a network error occurred // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) try { // Was never called and is aborted or complete if ( callback && ( isAbort || xhr.readyState === 4 ) ) { // Only called once callback = undefined; // Do not keep as active anymore if ( handle ) { xhr.onreadystatechange = jQuery.noop; if ( xhrOnUnloadAbort ) { delete xhrCallbacks[ handle ]; } } // If it's an abort if ( isAbort ) { // Abort it manually if needed if ( xhr.readyState !== 4 ) { xhr.abort(); } } else { status = xhr.status; responseHeaders = xhr.getAllResponseHeaders(); responses = {}; xml = xhr.responseXML; // Construct response list if ( xml && xml.documentElement /* #4958 */ ) { responses.xml = xml; } // When requesting binary data, IE6-9 will throw an exception // on any attempt to access responseText (#11426) try { responses.text = xhr.responseText; } catch( _ ) { } // Firefox throws an exception when accessing // statusText for faulty cross-domain requests try { statusText = xhr.statusText; } catch( e ) { // We normalize with Webkit giving an empty statusText statusText = ""; } // Filter status for non standard behaviors // If the request is local and we have data: assume a success // (success with no data won't get notified, that's the best we // can do given current implementations) if ( !status && s.isLocal && !s.crossDomain ) { status = responses.text ? 200 : 404; // IE - #1450: sometimes returns 1223 when it should be 204 } else if ( status === 1223 ) { status = 204; } } } } catch( firefoxAccessException ) { if ( !isAbort ) { complete( -1, firefoxAccessException ); } } // Call complete if needed if ( responses ) { complete( status, statusText, responses, responseHeaders ); } }; if ( !s.async ) { // if we're in sync mode we fire the callback callback(); } else if ( xhr.readyState === 4 ) { // (IE6 & IE7) if it's in cache and has been // retrieved directly we need to fire the callback setTimeout( callback, 0 ); } else { handle = ++xhrId; if ( xhrOnUnloadAbort ) { // Create the active xhrs callbacks list if needed // and attach the unload handler if ( !xhrCallbacks ) { xhrCallbacks = {}; jQuery( window ).unload( xhrOnUnloadAbort ); } // Add to list of active xhrs callbacks xhrCallbacks[ handle ] = callback; } xhr.onreadystatechange = callback; } }, abort: function() { if ( callback ) { callback(0,1); } } }; } }); } var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), rrun = /queueHooks$/, animationPrefilters = [ defaultPrefilter ], tweeners = { "*": [function( prop, value ) { var end, unit, prevScale, tween = this.createTween( prop, value ), parts = rfxnum.exec( value ), target = tween.cur(), start = +target || 0, scale = 1; if ( parts ) { end = +parts[2]; unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); // We need to compute starting value if ( unit !== "px" && start ) { // Iteratively approximate from a nonzero starting point // Prefer the current property, because this process will be trivial if it uses the same units // Fallback to end or a simple constant start = jQuery.css( tween.elem, prop, true ) || end || 1; do { // If previous iteration zeroed out, double until we get *something* // Use a string for doubling factor so we don't accidentally see scale as unchanged below prevScale = scale = scale || ".5"; // Adjust and apply start = start / scale; jQuery.style( tween.elem, prop, start + unit ); // Update scale, tolerating zeroes from tween.cur() scale = tween.cur() / target; // Stop looping if we've hit the mark or scale is unchanged } while ( scale !== 1 && scale !== prevScale ); } tween.unit = unit; tween.start = start; // If a +=/-= token was provided, we're doing a relative animation tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; } return tween; }] }; // Animations created synchronously will run synchronously function createFxNow() { setTimeout(function() { fxNow = undefined; }, 0 ); return ( fxNow = jQuery.now() ); } function createTweens( animation, props ) { jQuery.each( props, function( prop, value ) { var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( collection[ index ].call( animation, prop, value ) ) { // we're done with this property return; } } }); } function Animation( elem, properties, options ) { var result, index = 0, tweenerIndex = 0, length = animationPrefilters.length, deferred = jQuery.Deferred().always( function() { // don't match elem in the :animated selector delete tick.elem; }), tick = function() { var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), percent = 1 - ( remaining / animation.duration || 0 ), index = 0, length = animation.tweens.length; for ( ; index < length ; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ]); if ( percent < 1 && length ) { return remaining; } else { deferred.resolveWith( elem, [ animation ] ); return false; } }, animation = deferred.promise({ elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {} }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end, easing ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // if we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; for ( ; index < length ; index++ ) { animation.tweens[ index ].run( 1 ); } // resolve when we played the last frame // otherwise, reject if ( gotoEnd ) { deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } }), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length ; index++ ) { result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { return result; } } createTweens( animation, props ); if ( jQuery.isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } jQuery.fx.timer( jQuery.extend( tick, { anim: animation, queue: animation.opts.queue, elem: elem }) ); // attach callbacks from options return animation.progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = jQuery.camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( jQuery.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // not quite $.extend, this wont overwrite keys already present. // also - reusing 'index' from above because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } jQuery.Animation = jQuery.extend( Animation, { tweener: function( props, callback ) { if ( jQuery.isFunction( props ) ) { callback = props; props = [ "*" ]; } else { props = props.split(" "); } var prop, index = 0, length = props.length; for ( ; index < length ; index++ ) { prop = props[ index ]; tweeners[ prop ] = tweeners[ prop ] || []; tweeners[ prop ].unshift( callback ); } }, prefilter: function( callback, prepend ) { if ( prepend ) { animationPrefilters.unshift( callback ); } else { animationPrefilters.push( callback ); } } }); function defaultPrefilter( elem, props, opts ) { var index, prop, value, length, dataShow, tween, hooks, oldfire, anim = this, style = elem.style, orig = {}, handled = [], hidden = elem.nodeType && isHidden( elem ); // handle queue: false promises if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always(function() { // doing this makes sure that the complete handler will be called // before this completes anim.always(function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } }); }); } // height/width overflow pass if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { // Make sure that nothing sneaks out // Record all 3 overflow attributes because IE does not // change the overflow attribute when overflowX and // overflowY are set to the same value opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Set display property to inline-block for height/width // animations on inline elements that are having width/height animated if ( jQuery.css( elem, "display" ) === "inline" && jQuery.css( elem, "float" ) === "none" ) { // inline-level elements accept inline-block; // block-level elements need to be inline with layout if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { style.display = "inline-block"; } else { style.zoom = 1; } } } if ( opts.overflow ) { style.overflow = "hidden"; if ( !jQuery.support.shrinkWrapBlocks ) { anim.done(function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; }); } } // show/hide pass for ( index in props ) { value = props[ index ]; if ( rfxtypes.exec( value ) ) { delete props[ index ]; if ( value === ( hidden ? "hide" : "show" ) ) { continue; } handled.push( index ); } } length = handled.length; if ( length ) { dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); if ( hidden ) { jQuery( elem ).show(); } else { anim.done(function() { jQuery( elem ).hide(); }); } anim.done(function() { var prop; jQuery.removeData( elem, "fxshow", true ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } }); for ( index = 0 ; index < length ; index++ ) { prop = handled[ index ]; tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = tween.start; if ( hidden ) { tween.end = tween.start; tween.start = prop === "width" || prop === "height" ? 1 : 0; } } } } } function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || "swing"; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; if ( tween.elem[ tween.prop ] != null && (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { return tween.elem[ tween.prop ]; } // passing any value as a 4th parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails // so, simple values such as "10px" are parsed to Float. // complex values such as "rotate(1rad)" are returned as is. result = jQuery.css( tween.elem, tween.prop, false, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // use step hook for back compat - use cssHook if its there - use .style if its // available and use plain properties where available if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; // Remove in 2.0 - this supports IE8's panic based approach // to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" || // special check for .toggle( handler, handler, ... ) ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; }); jQuery.fn.extend({ fadeTo: function( speed, to, easing, callback ) { // show any hidden elements after setting opacity to 0 return this.filter( isHidden ).css( "opacity", 0 ).show() // animate to the value specified .end().animate({ opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations resolve immediately if ( empty ) { anim.stop( true ); } }; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue && type !== false ) { this.queue( type || "fx", [] ); } return this.each(function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = jQuery._data( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // start the next in the queue if the last step wasn't forced // timers currently will call their complete callbacks, which will dequeue // but only if they were gotoEnd if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } }); } }); // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, attrs = { height: type }, i = 0; // if we include width, step value is 1 to do all cssExpand values, // if we don't include width, step value is 2 to skip over Left and Right for( ; i < 4 ; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } // Generate shortcuts for custom animations jQuery.each({ slideDown: genFx("show"), slideUp: genFx("hide"), slideToggle: genFx("toggle"), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; }); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || jQuery.isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing }; opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; // normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( jQuery.isFunction( opt.old ) ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p*Math.PI ) / 2; } }; jQuery.timers = []; jQuery.fx = Tween.prototype.init; jQuery.fx.tick = function() { var timer, timers = jQuery.timers, i = 0; for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Checks the timer has not already been removed if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } }; jQuery.fx.timer = function( timer ) { if ( timer() && jQuery.timers.push( timer ) && !timerId ) { timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); } }; jQuery.fx.interval = 13; jQuery.fx.stop = function() { clearInterval( timerId ); timerId = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Back Compat <1.8 extension point jQuery.fx.step = {}; if ( jQuery.expr && jQuery.expr.filters ) { jQuery.expr.filters.animated = function( elem ) { return jQuery.grep(jQuery.timers, function( fn ) { return elem === fn.elem; }).length; }; } var rroot = /^(?:body|html)$/i; jQuery.fn.offset = function( options ) { if ( arguments.length ) { return options === undefined ? this : this.each(function( i ) { jQuery.offset.setOffset( this, options, i ); }); } var box, docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, top, left, elem = this[ 0 ], doc = elem && elem.ownerDocument; if ( !doc ) { return; } if ( (body = doc.body) === elem ) { return jQuery.offset.bodyOffset( elem ); } docElem = doc.documentElement; // Make sure we're not dealing with a disconnected DOM node if ( !jQuery.contains( docElem, elem ) ) { return { top: 0, left: 0 }; } box = elem.getBoundingClientRect(); win = getWindow( doc ); clientTop = docElem.clientTop || body.clientTop || 0; clientLeft = docElem.clientLeft || body.clientLeft || 0; scrollTop = win.pageYOffset || docElem.scrollTop; scrollLeft = win.pageXOffset || docElem.scrollLeft; top = box.top + scrollTop - clientTop; left = box.left + scrollLeft - clientLeft; return { top: top, left: left }; }; jQuery.offset = { bodyOffset: function( body ) { var top = body.offsetTop, left = body.offsetLeft; if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { top += parseFloat( jQuery.css(body, "marginTop") ) || 0; left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; } return { top: top, left: left }; }, setOffset: function( elem, options, i ) { var position = jQuery.css( elem, "position" ); // set position first, in-case top/left are set even on static elem if ( position === "static" ) { elem.style.position = "relative"; } var curElem = jQuery( elem ), curOffset = curElem.offset(), curCSSTop = jQuery.css( elem, "top" ), curCSSLeft = jQuery.css( elem, "left" ), calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, props = {}, curPosition = {}, curTop, curLeft; // need to be able to calculate position if either top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); curTop = curPosition.top; curLeft = curPosition.left; } else { curTop = parseFloat( curCSSTop ) || 0; curLeft = parseFloat( curCSSLeft ) || 0; } if ( jQuery.isFunction( options ) ) { options = options.call( elem, i, curOffset ); } if ( options.top != null ) { props.top = ( options.top - curOffset.top ) + curTop; } if ( options.left != null ) { props.left = ( options.left - curOffset.left ) + curLeft; } if ( "using" in options ) { options.using.call( elem, props ); } else { curElem.css( props ); } } }; jQuery.fn.extend({ position: function() { if ( !this[0] ) { return; } var elem = this[0], // Get *real* offsetParent offsetParent = this.offsetParent(), // Get correct offsets offset = this.offset(), parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); // Subtract element margins // note: when an element has margin: auto the offsetLeft and marginLeft // are the same in Safari causing offset.left to incorrectly be 0 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; // Add offsetParent borders parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; // Subtract the two offsets return { top: offset.top - parentOffset.top, left: offset.left - parentOffset.left }; }, offsetParent: function() { return this.map(function() { var offsetParent = this.offsetParent || document.body; while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { offsetParent = offsetParent.offsetParent; } return offsetParent || document.body; }); } }); // Create scrollLeft and scrollTop methods jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { var top = /Y/.test( prop ); jQuery.fn[ method ] = function( val ) { return jQuery.access( this, function( elem, method, val ) { var win = getWindow( elem ); if ( val === undefined ) { return win ? (prop in win) ? win[ prop ] : win.document.documentElement[ method ] : elem[ method ]; } if ( win ) { win.scrollTo( !top ? val : jQuery( win ).scrollLeft(), top ? val : jQuery( win ).scrollTop() ); } else { elem[ method ] = val; } }, method, val, arguments.length, null ); }; }); function getWindow( elem ) { return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 ? elem.defaultView || elem.parentWindow : false; } // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { // margin is only for outerHeight, outerWidth jQuery.fn[ funcName ] = function( margin, value ) { var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); return jQuery.access( this, function( elem, type, value ) { var doc; if ( jQuery.isWindow( elem ) ) { // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there // isn't a whole lot we can do. See pull request at this URL for discussion: // https://github.com/jquery/jquery/pull/764 return elem.document.documentElement[ "client" + name ]; } // Get document width or height if ( elem.nodeType === 9 ) { doc = elem.documentElement; // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. return Math.max( elem.body[ "scroll" + name ], doc[ "scroll" + name ], elem.body[ "offset" + name ], doc[ "offset" + name ], doc[ "client" + name ] ); } return value === undefined ? // Get width or height on the element, requesting but not forcing parseFloat jQuery.css( elem, type, value, extra ) : // Set width or height on the element jQuery.style( elem, type, value, extra ); }, type, chainable ? margin : undefined, chainable ); }; }); }); // Expose jQuery to the global object window.jQuery = window.$ = jQuery; // Expose jQuery as an AMD module, but only for AMD loaders that // understand the issues with loading multiple versions of jQuery // in a page that all might call define(). The loader will indicate // they have special allowances for multiple jQuery versions by // specifying define.amd.jQuery = true. Register as a named module, // since jQuery can be concatenated with other files that may use define, // but not use a proper concatenation script that understands anonymous // AMD modules. A named AMD is safest and most robust way to register. // Lowercase jquery is used because AMD module names are derived from // file names, and jQuery is normally delivered in a lowercase file name. // Do this after creating the global so that if an AMD module wants to call // noConflict to hide this version of jQuery, it will work. if ( typeof define === "function" && define.amd && define.amd.jQuery ) { define( "jquery", [], function () { return jQuery; } ); } })( window ); ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/killer.html ================================================ Killer Option
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/noanim.html ================================================ No Animation
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/notification_html.js ================================================ // notification body's can be any html string or just string var notification_html = []; notification_html[0] = '
        There are 6 new tasks waiting for you. Don\'t forget! About 3 hours ago
        ', notification_html[1] = '
        Mail server was updated. See changelog About 2 hours ago
        ', notification_html[2] = '
        Your latest post was liked by Audrey Mall 35 minutes ago
        ', notification_html[3] = '
        Eugene ordered 2 copies of OEM license 14 minutes ago
        '; ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/progressbar.html ================================================ Using with progress bar
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/themeBootstrap.html ================================================ Bootstrap Theme
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/themeCss.html ================================================ CSS Theme
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/usingMaxVisible.html ================================================  MaxVisible Option

        maxVisible: 3

        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/usingWithAnimate.css.html ================================================ Using with Animate.css
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/usingWithButtons.html ================================================ Using with Buttons
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/usingWithButtons2.html ================================================ Notification Types
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/usingWithModal.html ================================================ Notification Types
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/demo/usingWithOldOptions.html ================================================ Using noty v2 with Old Options
        Old options not supported anymore. (until: v2.2.0)
        ================================================ FILE: docs/v2/vendor/noty-2.4.1/js/noty/jquery.noty.js ================================================ /*! @package noty - jQuery Notification Plugin @version version: 2.4.1 @contributors https://github.com/needim/noty/v2/graphs/contributors @documentation Examples and Documentation - http://needim.github.com/noty/v2/ @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php */ if (typeof Object.create !== 'function') { Object.create = function (o) { function F() { } F.prototype = o; return new F(); }; } var NotyObject = { init: function (options) { // Mix in the passed in options with the default options this.options = $.extend({}, $.noty.defaults, options); this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout]; if ($.noty.themes[this.options.theme]) { this.options.theme = $.noty.themes[this.options.theme]; if (this.options.theme.template) this.options.template = this.options.theme.template; if (this.options.theme.animation) this.options.animation = this.options.theme.animation; } else { this.options.themeClassName = this.options.theme; } this.options = $.extend({}, this.options, this.options.layout.options); if (this.options.id) { if ($.noty.store[this.options.id]) { return $.noty.store[this.options.id]; } } else { this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000)); } // Build the noty dom initial structure this._build(); // return this so we can chain/use the bridge with less code. return this; }, // end init _build: function () { // Generating noty bar var $bar = $('
        ').attr('id', this.options.id); $bar.append(this.options.template).find('.noty_text').html(this.options.text); this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar; if (this.options.themeClassName) this.$bar.addClass(this.options.themeClassName).addClass('noty_container_type_' + this.options.type); // Set buttons if available if (this.options.buttons) { var $buttons; // Try find container for buttons in presented template, and create it if not found if (this.$bar.find('.noty_buttons').length > 0) { $buttons = this.$bar.find('.noty_buttons'); } else { $buttons = $('
        ').addClass('noty_buttons'); (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons); } var self = this; $.each(this.options.buttons, function (i, button) { var $button = $('
        \n\n\n', tblLgn = headers.length; for (var i = 0; i < tblLgn; ++i) { tb += headers[i]; } tb += '\n\n\n'; for (i = 0; i < cells.length; ++i) { tb += '\n'; for (var ii = 0; ii < tblLgn; ++ii) { tb += cells[i][ii]; } tb += '\n'; } tb += '\n
        \n'; return tb; } text = globals.converter._dispatch('tables.before', text, options, globals); text = text.replace(tableRgx, function (rawTable) { var i, tableLines = rawTable.split('\n'); // strip wrong first and last column if wrapped tables are used for (i = 0; i < tableLines.length; ++i) { if (/^ {0,3}\|/.test(tableLines[i])) { tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); } if (/\|[ \t]*$/.test(tableLines[i])) { tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); } } var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), rawCells = [], headers = [], styles = [], cells = []; tableLines.shift(); tableLines.shift(); for (i = 0; i < tableLines.length; ++i) { if (tableLines[i].trim() === '') { continue; } rawCells.push( tableLines[i] .split('|') .map(function (s) { return s.trim(); }) ); } if (rawHeaders.length < rawStyles.length) { return rawTable; } for (i = 0; i < rawStyles.length; ++i) { styles.push(parseStyles(rawStyles[i])); } for (i = 0; i < rawHeaders.length; ++i) { if (showdown.helper.isUndefined(styles[i])) { styles[i] = ''; } headers.push(parseHeaders(rawHeaders[i], styles[i])); } for (i = 0; i < rawCells.length; ++i) { var row = []; for (var ii = 0; ii < headers.length; ++ii) { if (showdown.helper.isUndefined(rawCells[i][ii])) { } row.push(parseCells(rawCells[i][ii], styles[ii])); } cells.push(row); } return buildTable(headers, cells); }); text = globals.converter._dispatch('tables.after', text, options, globals); return text; }); /** * Swap back in all the special characters we've hidden. */ showdown.subParser('unescapeSpecialChars', function (text) { 'use strict'; text = text.replace(/~E(\d+)E/g, function (wholeMatch, m1) { var charCodeToReplace = parseInt(m1); return String.fromCharCode(charCodeToReplace); }); return text; }); var root = this; // CommonJS/nodeJS Loader if (typeof module !== 'undefined' && module.exports) { module.exports = showdown; // AMD Loader } else if (typeof define === 'function' && define.amd) { define(function () { 'use strict'; return showdown; }); // Regular Browser loader } else { root.showdown = showdown; } }).call(this); //# sourceMappingURL=showdown.js.map ================================================ FILE: index.d.ts ================================================ declare module 'noty' { export = Noty; } declare class Noty { constructor(options?: Noty.Options); /** * Show a NOTY */ show: () => void; /** * Close a NOTY */ close: () => void; /** * Notification text updater. Important: .noty_body class is required for setText API method */ setText: (text: string, overrideConstructorOption?: true) => void; /** * Notification type updater */ setType: (type: Noty.Type, overrideConstructorOption?: true) => void; /** * Notification theme updater */ setTheme: (theme: Noty.Theme, overrideConstructorOption?: true) => void; /** * false (clears timeout) or integer (clears timer, starts for given value) */ setTimeout: (option: false | number) => void; // /** * Clears the timeout */ stop: () => void; /** * Restarts the timeout */ resume: () => void; /** * Register event handlers for Noty outside of constructior options * Important: You need to call on() methods before the show() method */ on: (eventName: Noty.Event, callback: Function) => void; /** * Without queue name: Closes all notifications * With queue name: Closes all notifications for the named queue */ static closeAll: (queueName?: string) => void; /** * Without queue name: Sets the maxVisible notification count for global queue * With parameter: Sets the maxVisible notification count for the named queue */ static setMaxVisible: (max: number, queueName?: string) => void; /** * Change default values for new instances of NOTY */ static overrideDefaults: (obj: { [i: string]: any }) => Noty; static button: (text: string, classNames: string, cb: Function, attributes?: any) => Noty.Button; } declare namespace Noty { type Type = 'alert' | 'success' | 'warning' | 'error' | 'info' | 'information'; type Theme = string; type Layout = 'top' | 'topLeft' | 'topCenter' | 'topRight' | 'center' | 'centerLeft' | 'centerRight' | 'bottom' | 'bottomLeft' | 'bottomCenter' | 'bottomRight'; type Event = 'beforeShow' | 'onShow' | 'afterShow' | 'onClose' | 'afterClose' | 'onHover' | 'onTemplate' | 'onClick'; interface Button { new(text: string, classNames: string, cb: Function, attributes: any) : Noty.Button } interface Options { type?: Noty.Type; layout?: Noty.Layout; theme?: Noty.Theme; text?: string; timeout?: false | number; progressBar?: boolean; closeWith?: ('click' | 'button')[]; animation?: { open?: string | null | Function, close?: string | null | Function }; id?: false | string; force?: boolean; killer?: boolean | string; queue?: string; container?: false | string; buttons?: Noty.Button[], callbacks?: { beforeShow?: () => void, onShow?: () => void, afterShow?: () => void, onClose?: () => void, afterClose?: () => void, onHover?: () => void, onTemplate?: () => void, onClick?: () => void }; sounds?: { sources?: string[], volume?: number, conditions?: string[] }; docTitle?: { conditions?: string[] }; modal?: boolean, } } ================================================ FILE: lib/noty.css ================================================ .noty_layout_mixin, #noty_layout__top, #noty_layout__topLeft, #noty_layout__topCenter, #noty_layout__topRight, #noty_layout__bottom, #noty_layout__bottomLeft, #noty_layout__bottomCenter, #noty_layout__bottomRight, #noty_layout__center, #noty_layout__centerLeft, #noty_layout__centerRight { position: fixed; margin: 0; padding: 0; z-index: 9999999; -webkit-transform: translateZ(0) scale(1, 1); transform: translateZ(0) scale(1, 1); -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-font-smoothing: subpixel-antialiased; filter: blur(0); -webkit-filter: blur(0); max-width: 90%; } #noty_layout__top { top: 0; left: 5%; width: 90%; } #noty_layout__topLeft { top: 20px; left: 20px; width: 325px; } #noty_layout__topCenter { top: 5%; left: 50%; width: 325px; -webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); } #noty_layout__topRight { top: 20px; right: 20px; width: 325px; } #noty_layout__bottom { bottom: 0; left: 5%; width: 90%; } #noty_layout__bottomLeft { bottom: 20px; left: 20px; width: 325px; } #noty_layout__bottomCenter { bottom: 5%; left: 50%; width: 325px; -webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); } #noty_layout__bottomRight { bottom: 20px; right: 20px; width: 325px; } #noty_layout__center { top: 50%; left: 50%; width: 325px; -webkit-transform: translate(-webkit-calc(-50% - .5px), -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1, 1); } #noty_layout__centerLeft { top: 50%; left: 20px; width: 325px; -webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); } #noty_layout__centerRight { top: 50%; right: 20px; width: 325px; -webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); } .noty_progressbar { display: none; } .noty_has_timeout.noty_has_progressbar .noty_progressbar { display: block; position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background-color: #646464; opacity: 0.2; filter: alpha(opacity=10); } .noty_bar { -webkit-backface-visibility: hidden; -webkit-transform: translate(0, 0) translateZ(0) scale(1, 1); -ms-transform: translate(0, 0) scale(1, 1); transform: translate(0, 0) scale(1, 1); -webkit-font-smoothing: subpixel-antialiased; overflow: hidden; } .noty_effects_open { opacity: 0; -webkit-transform: translate(50%); -ms-transform: translate(50%); transform: translate(50%); -webkit-animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); -webkit-animation-fill-mode: forwards; animation-fill-mode: forwards; } .noty_effects_close { -webkit-animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); -webkit-animation-fill-mode: forwards; animation-fill-mode: forwards; } .noty_fix_effects_height { -webkit-animation: noty_anim_height 75ms ease-out; animation: noty_anim_height 75ms ease-out; } .noty_close_with_click { cursor: pointer; } .noty_close_button { position: absolute; top: 2px; right: 2px; font-weight: bold; width: 20px; height: 20px; text-align: center; line-height: 20px; background-color: rgba(0, 0, 0, 0.05); border-radius: 2px; cursor: pointer; -webkit-transition: all .2s ease-out; transition: all .2s ease-out; } .noty_close_button:hover { background-color: rgba(0, 0, 0, 0.1); } .noty_modal { position: fixed; width: 100%; height: 100%; background-color: #000; z-index: 10000; opacity: .3; left: 0; top: 0; } .noty_modal.noty_modal_open { opacity: 0; -webkit-animation: noty_modal_in .3s ease-out; animation: noty_modal_in .3s ease-out; } .noty_modal.noty_modal_close { -webkit-animation: noty_modal_out .3s ease-out; animation: noty_modal_out .3s ease-out; -webkit-animation-fill-mode: forwards; animation-fill-mode: forwards; } @-webkit-keyframes noty_modal_in { 100% { opacity: .3; } } @keyframes noty_modal_in { 100% { opacity: .3; } } @-webkit-keyframes noty_modal_out { 100% { opacity: 0; } } @keyframes noty_modal_out { 100% { opacity: 0; } } @keyframes noty_modal_out { 100% { opacity: 0; } } @-webkit-keyframes noty_anim_in { 100% { -webkit-transform: translate(0); transform: translate(0); opacity: 1; } } @keyframes noty_anim_in { 100% { -webkit-transform: translate(0); transform: translate(0); opacity: 1; } } @-webkit-keyframes noty_anim_out { 100% { -webkit-transform: translate(50%); transform: translate(50%); opacity: 0; } } @keyframes noty_anim_out { 100% { -webkit-transform: translate(50%); transform: translate(50%); opacity: 0; } } @-webkit-keyframes noty_anim_height { 100% { height: 0; } } @keyframes noty_anim_height { 100% { height: 0; } } /*# sourceMappingURL=noty.css.map*/ ================================================ FILE: lib/noty.js ================================================ /* @package NOTY - Dependency-free notification library @version version: 3.2.0-beta @contributors https://github.com/needim/noty/graphs/contributors @documentation Examples and Documentation - https://ned.im/noty @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("Noty", [], factory); else if(typeof exports === 'object') exports["Noty"] = factory(); else root["Noty"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 6); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.css = exports.deepExtend = exports.animationEndEvents = undefined; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.inArray = inArray; exports.stopPropagation = stopPropagation; exports.generateID = generateID; exports.outerHeight = outerHeight; exports.addListener = addListener; exports.hasClass = hasClass; exports.addClass = addClass; exports.removeClass = removeClass; exports.remove = remove; exports.classList = classList; exports.visibilityChangeFlow = visibilityChangeFlow; exports.createAudioElements = createAudioElements; var _api = __webpack_require__(1); var API = _interopRequireWildcard(_api); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } var animationEndEvents = exports.animationEndEvents = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend'; function inArray(needle, haystack, argStrict) { var key = void 0; var strict = !!argStrict; if (strict) { for (key in haystack) { if (haystack.hasOwnProperty(key) && haystack[key] === needle) { return true; } } } else { for (key in haystack) { if (haystack.hasOwnProperty(key) && haystack[key] === needle) { return true; } } } return false; } function stopPropagation(evt) { evt = evt || window.event; if (typeof evt.stopPropagation !== 'undefined') { evt.stopPropagation(); } else { evt.cancelBubble = true; } } var deepExtend = exports.deepExtend = function deepExtend(out) { out = out || {}; for (var i = 1; i < arguments.length; i++) { var obj = arguments[i]; if (!obj) continue; for (var key in obj) { if (obj.hasOwnProperty(key)) { if (Array.isArray(obj[key])) { out[key] = obj[key]; } else if (_typeof(obj[key]) === 'object' && obj[key] !== null) { out[key] = deepExtend(out[key], obj[key]); } else { out[key] = obj[key]; } } } } return out; }; function generateID() { var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var id = 'noty_' + prefix + '_'; id += 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0; var v = c === 'x' ? r : r & 0x3 | 0x8; return v.toString(16); }); return id; } function outerHeight(el) { var height = el.offsetHeight; var style = window.getComputedStyle(el); height += parseInt(style.marginTop) + parseInt(style.marginBottom); return height; } var css = exports.css = function () { var cssPrefixes = ['Webkit', 'O', 'Moz', 'ms']; var cssProps = {}; function camelCase(string) { return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function (match, letter) { return letter.toUpperCase(); }); } function getVendorProp(name) { var style = document.body.style; if (name in style) return name; var i = cssPrefixes.length; var capName = name.charAt(0).toUpperCase() + name.slice(1); var vendorName = void 0; while (i--) { vendorName = cssPrefixes[i] + capName; if (vendorName in style) return vendorName; } return name; } function getStyleProp(name) { name = camelCase(name); return cssProps[name] || (cssProps[name] = getVendorProp(name)); } function applyCss(element, prop, value) { prop = getStyleProp(prop); element.style[prop] = value; } return function (element, properties) { var args = arguments; var prop = void 0; var value = void 0; if (args.length === 2) { for (prop in properties) { if (properties.hasOwnProperty(prop)) { value = properties[prop]; if (value !== undefined && properties.hasOwnProperty(prop)) { applyCss(element, prop, value); } } } } else { applyCss(element, args[1], args[2]); } }; }(); function addListener(el, events, cb) { var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; events = events.split(' '); for (var i = 0; i < events.length; i++) { if (document.addEventListener) { el.addEventListener(events[i], cb, useCapture); } else if (document.attachEvent) { el.attachEvent('on' + events[i], cb); } } } function hasClass(element, name) { var list = typeof element === 'string' ? element : classList(element); return list.indexOf(' ' + name + ' ') >= 0; } function addClass(element, name) { var oldList = classList(element); var newList = oldList + name; if (hasClass(oldList, name)) return; // Trim the opening space. element.className = newList.substring(1); } function removeClass(element, name) { var oldList = classList(element); var newList = void 0; if (!hasClass(element, name)) return; // Replace the class name. newList = oldList.replace(' ' + name + ' ', ' '); // Trim the opening and closing spaces. element.className = newList.substring(1, newList.length - 1); } function remove(element) { if (element.parentNode) { element.parentNode.removeChild(element); } } function classList(element) { return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' '); } function visibilityChangeFlow() { var hidden = void 0; var visibilityChange = void 0; if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support hidden = 'hidden'; visibilityChange = 'visibilitychange'; } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden'; visibilityChange = 'msvisibilitychange'; } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden'; visibilityChange = 'webkitvisibilitychange'; } function onVisibilityChange() { API.PageHidden = document[hidden]; handleVisibilityChange(); } function onBlur() { API.PageHidden = true; handleVisibilityChange(); } function onFocus() { API.PageHidden = false; handleVisibilityChange(); } function handleVisibilityChange() { if (API.PageHidden) stopAll();else resumeAll(); } function stopAll() { setTimeout(function () { Object.keys(API.Store).forEach(function (id) { if (API.Store.hasOwnProperty(id)) { if (API.Store[id].options.visibilityControl) { API.Store[id].stop(); } } }); }, 100); } function resumeAll() { setTimeout(function () { Object.keys(API.Store).forEach(function (id) { if (API.Store.hasOwnProperty(id)) { if (API.Store[id].options.visibilityControl) { API.Store[id].resume(); } } }); API.queueRenderAll(); }, 100); } if (visibilityChange) { addListener(document, visibilityChange, onVisibilityChange); } addListener(window, 'blur', onBlur); addListener(window, 'focus', onFocus); } function createAudioElements(ref) { if (ref.hasSound) { var audioElement = document.createElement('audio'); ref.options.sounds.sources.forEach(function (s) { var source = document.createElement('source'); source.src = s; source.type = 'audio/' + getExtension(s); audioElement.appendChild(source); }); if (ref.barDom) { ref.barDom.appendChild(audioElement); } else { document.querySelector('body').appendChild(audioElement); } audioElement.volume = ref.options.sounds.volume; if (!ref.soundPlayed) { audioElement.play(); ref.soundPlayed = true; } audioElement.onended = function () { remove(audioElement); }; } } function getExtension(fileName) { return fileName.match(/\.([^.]+)$/)[1]; } /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Defaults = exports.Store = exports.Queues = exports.DefaultMaxVisible = exports.docTitle = exports.DocModalCount = exports.PageHidden = undefined; exports.getQueueCounts = getQueueCounts; exports.addToQueue = addToQueue; exports.removeFromQueue = removeFromQueue; exports.queueRender = queueRender; exports.queueRenderAll = queueRenderAll; exports.ghostFix = ghostFix; exports.build = build; exports.hasButtons = hasButtons; exports.handleModal = handleModal; exports.handleModalClose = handleModalClose; exports.queueClose = queueClose; exports.dequeueClose = dequeueClose; exports.fire = fire; exports.openFlow = openFlow; exports.closeFlow = closeFlow; var _utils = __webpack_require__(0); var Utils = _interopRequireWildcard(_utils); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } var PageHidden = exports.PageHidden = false; var DocModalCount = exports.DocModalCount = 0; var DocTitleProps = { originalTitle: null, count: 0, changed: false, timer: -1 }; var docTitle = exports.docTitle = { increment: function increment() { DocTitleProps.count++; docTitle._update(); }, decrement: function decrement() { DocTitleProps.count--; if (DocTitleProps.count <= 0) { docTitle._clear(); return; } docTitle._update(); }, _update: function _update() { var title = document.title; if (!DocTitleProps.changed) { DocTitleProps.originalTitle = title; document.title = '(' + DocTitleProps.count + ') ' + title; DocTitleProps.changed = true; } else { document.title = '(' + DocTitleProps.count + ') ' + DocTitleProps.originalTitle; } }, _clear: function _clear() { if (DocTitleProps.changed) { DocTitleProps.count = 0; document.title = DocTitleProps.originalTitle; DocTitleProps.changed = false; } } }; var DefaultMaxVisible = exports.DefaultMaxVisible = 5; var Queues = exports.Queues = { global: { maxVisible: DefaultMaxVisible, queue: [] } }; var Store = exports.Store = {}; var Defaults = exports.Defaults = { type: 'alert', layout: 'topRight', theme: 'mint', text: '', timeout: false, progressBar: true, closeWith: ['click'], animation: { open: 'noty_effects_open', close: 'noty_effects_close' }, id: false, force: false, killer: false, queue: 'global', container: false, buttons: [], callbacks: { beforeShow: null, onShow: null, afterShow: null, onClose: null, afterClose: null, onClick: null, onHover: null, onTemplate: null }, sounds: { sources: [], volume: 1, conditions: [] }, titleCount: { conditions: [] }, modal: false, visibilityControl: false /** * @param {string} queueName * @return {object} */ };function getQueueCounts() { var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'global'; var count = 0; var max = DefaultMaxVisible; if (Queues.hasOwnProperty(queueName)) { max = Queues[queueName].maxVisible; Object.keys(Store).forEach(function (i) { if (Store[i].options.queue === queueName && !Store[i].closed) count++; }); } return { current: count, maxVisible: max }; } /** * @param {Noty} ref * @return {void} */ function addToQueue(ref) { if (!Queues.hasOwnProperty(ref.options.queue)) { Queues[ref.options.queue] = { maxVisible: DefaultMaxVisible, queue: [] }; } Queues[ref.options.queue].queue.push(ref); } /** * @param {Noty} ref * @return {void} */ function removeFromQueue(ref) { if (Queues.hasOwnProperty(ref.options.queue)) { var queue = []; Object.keys(Queues[ref.options.queue].queue).forEach(function (i) { if (Queues[ref.options.queue].queue[i].id !== ref.id) { queue.push(Queues[ref.options.queue].queue[i]); } }); Queues[ref.options.queue].queue = queue; } } /** * @param {string} queueName * @return {void} */ function queueRender() { var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'global'; if (Queues.hasOwnProperty(queueName)) { var noty = Queues[queueName].queue.shift(); if (noty) noty.show(); } } /** * @return {void} */ function queueRenderAll() { Object.keys(Queues).forEach(function (queueName) { queueRender(queueName); }); } /** * @param {Noty} ref * @return {void} */ function ghostFix(ref) { var ghostID = Utils.generateID('ghost'); var ghost = document.createElement('div'); ghost.setAttribute('id', ghostID); Utils.css(ghost, { height: Utils.outerHeight(ref.barDom) + 'px' }); ref.barDom.insertAdjacentHTML('afterend', ghost.outerHTML); Utils.remove(ref.barDom); ghost = document.getElementById(ghostID); Utils.addClass(ghost, 'noty_fix_effects_height'); Utils.addListener(ghost, Utils.animationEndEvents, function () { Utils.remove(ghost); }); } /** * @param {Noty} ref * @return {void} */ function build(ref) { findOrCreateContainer(ref); var markup = '
        ' + ref.options.text + '
        ' + buildButtons(ref) + '
        '; ref.barDom = document.createElement('div'); ref.barDom.setAttribute('id', ref.id); Utils.addClass(ref.barDom, 'noty_bar noty_type__' + ref.options.type + ' noty_theme__' + ref.options.theme); ref.barDom.innerHTML = markup; fire(ref, 'onTemplate'); } /** * @param {Noty} ref * @return {boolean} */ function hasButtons(ref) { return !!(ref.options.buttons && Object.keys(ref.options.buttons).length); } /** * @param {Noty} ref * @return {string} */ function buildButtons(ref) { if (hasButtons(ref)) { var buttons = document.createElement('div'); Utils.addClass(buttons, 'noty_buttons'); Object.keys(ref.options.buttons).forEach(function (key) { buttons.appendChild(ref.options.buttons[key].dom); }); ref.options.buttons.forEach(function (btn) { buttons.appendChild(btn.dom); }); return buttons.outerHTML; } return ''; } /** * @param {Noty} ref * @return {void} */ function handleModal(ref) { if (ref.options.modal) { if (DocModalCount === 0) { createModal(ref); } exports.DocModalCount = DocModalCount += 1; } } /** * @param {Noty} ref * @return {void} */ function handleModalClose(ref) { if (ref.options.modal && DocModalCount > 0) { exports.DocModalCount = DocModalCount -= 1; if (DocModalCount <= 0) { var modal = document.querySelector('.noty_modal'); if (modal) { Utils.removeClass(modal, 'noty_modal_open'); Utils.addClass(modal, 'noty_modal_close'); Utils.addListener(modal, Utils.animationEndEvents, function () { Utils.remove(modal); }); } } } } /** * @return {void} */ function createModal() { var body = document.querySelector('body'); var modal = document.createElement('div'); Utils.addClass(modal, 'noty_modal'); body.insertBefore(modal, body.firstChild); Utils.addClass(modal, 'noty_modal_open'); Utils.addListener(modal, Utils.animationEndEvents, function () { Utils.removeClass(modal, 'noty_modal_open'); }); } /** * @param {Noty} ref * @return {void} */ function findOrCreateContainer(ref) { if (ref.options.container) { ref.layoutDom = document.querySelector(ref.options.container); return; } var layoutID = 'noty_layout__' + ref.options.layout; ref.layoutDom = document.querySelector('div#' + layoutID); if (!ref.layoutDom) { ref.layoutDom = document.createElement('div'); ref.layoutDom.setAttribute('id', layoutID); ref.layoutDom.setAttribute('role', 'alert'); ref.layoutDom.setAttribute('aria-live', 'polite'); Utils.addClass(ref.layoutDom, 'noty_layout'); document.querySelector('body').appendChild(ref.layoutDom); } } /** * @param {Noty} ref * @return {void} */ function queueClose(ref) { if (ref.options.timeout) { if (ref.options.progressBar && ref.progressDom) { Utils.css(ref.progressDom, { transition: 'width ' + ref.options.timeout + 'ms linear', width: '0%' }); } clearTimeout(ref.closeTimer); ref.closeTimer = setTimeout(function () { ref.close(); }, ref.options.timeout); } } /** * @param {Noty} ref * @return {void} */ function dequeueClose(ref) { if (ref.options.timeout && ref.closeTimer) { clearTimeout(ref.closeTimer); ref.closeTimer = -1; if (ref.options.progressBar && ref.progressDom) { Utils.css(ref.progressDom, { transition: 'width 0ms linear', width: '100%' }); } } } /** * @param {Noty} ref * @param {string} eventName * @return {void} */ function fire(ref, eventName) { if (ref.listeners.hasOwnProperty(eventName)) { ref.listeners[eventName].forEach(function (cb) { if (typeof cb === 'function') { cb.apply(ref); } }); } } /** * @param {Noty} ref * @return {void} */ function openFlow(ref) { fire(ref, 'afterShow'); queueClose(ref); Utils.addListener(ref.barDom, 'mouseenter', function () { dequeueClose(ref); }); Utils.addListener(ref.barDom, 'mouseleave', function () { queueClose(ref); }); } /** * @param {Noty} ref * @return {void} */ function closeFlow(ref) { delete Store[ref.id]; ref.closing = false; fire(ref, 'afterClose'); Utils.remove(ref.barDom); if (ref.layoutDom.querySelectorAll('.noty_bar').length === 0 && !ref.options.container) { Utils.remove(ref.layoutDom); } if (Utils.inArray('docVisible', ref.options.titleCount.conditions) || Utils.inArray('docHidden', ref.options.titleCount.conditions)) { docTitle.decrement(); } queueRender(ref.options.queue); } /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NotyButton = undefined; var _utils = __webpack_require__(0); var Utils = _interopRequireWildcard(_utils); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NotyButton = exports.NotyButton = function NotyButton(html, classes, cb) { var _this = this; var attributes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; _classCallCheck(this, NotyButton); this.dom = document.createElement('button'); this.dom.innerHTML = html; this.id = attributes.id = attributes.id || Utils.generateID('button'); this.cb = cb; Object.keys(attributes).forEach(function (propertyName) { _this.dom.setAttribute(propertyName, attributes[propertyName]); }); Utils.addClass(this.dom, classes || 'noty_btn'); return this; }; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Push = exports.Push = function () { function Push() { var workerPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '/service-worker.js'; _classCallCheck(this, Push); this.subData = {}; this.workerPath = workerPath; this.listeners = { onPermissionGranted: [], onPermissionDenied: [], onSubscriptionSuccess: [], onSubscriptionCancel: [], onWorkerError: [], onWorkerSuccess: [], onWorkerNotSupported: [] }; return this; } /** * @param {string} eventName * @param {function} cb * @return {Push} */ _createClass(Push, [{ key: 'on', value: function on(eventName) { var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) { this.listeners[eventName].push(cb); } return this; } }, { key: 'fire', value: function fire(eventName) { var _this = this; var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; if (this.listeners.hasOwnProperty(eventName)) { this.listeners[eventName].forEach(function (cb) { if (typeof cb === 'function') { cb.apply(_this, params); } }); } } }, { key: 'create', value: function create() { console.log('NOT IMPLEMENTED YET'); } /** * @return {boolean} */ }, { key: 'isSupported', value: function isSupported() { var result = false; try { result = window.Notification || window.webkitNotifications || navigator.mozNotification || window.external && window.external.msIsSiteMode() !== undefined; } catch (e) {} return result; } /** * @return {string} */ }, { key: 'getPermissionStatus', value: function getPermissionStatus() { var perm = 'default'; if (window.Notification && window.Notification.permissionLevel) { perm = window.Notification.permissionLevel; } else if (window.webkitNotifications && window.webkitNotifications.checkPermission) { switch (window.webkitNotifications.checkPermission()) { case 1: perm = 'default'; break; case 0: perm = 'granted'; break; default: perm = 'denied'; } } else if (window.Notification && window.Notification.permission) { perm = window.Notification.permission; } else if (navigator.mozNotification) { perm = 'granted'; } else if (window.external && window.external.msIsSiteMode() !== undefined) { perm = window.external.msIsSiteMode() ? 'granted' : 'default'; } return perm.toString().toLowerCase(); } /** * @return {string} */ }, { key: 'getEndpoint', value: function getEndpoint(subscription) { var endpoint = subscription.endpoint; var subscriptionId = subscription.subscriptionId; // fix for Chrome < 45 if (subscriptionId && endpoint.indexOf(subscriptionId) === -1) { endpoint += '/' + subscriptionId; } return endpoint; } /** * @return {boolean} */ }, { key: 'isSWRegistered', value: function isSWRegistered() { try { return navigator.serviceWorker.controller.state === 'activated'; } catch (e) { return false; } } /** * @return {void} */ }, { key: 'unregisterWorker', value: function unregisterWorker() { var self = this; if ('serviceWorker' in navigator) { navigator.serviceWorker.getRegistrations().then(function (registrations) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = registrations[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var registration = _step.value; registration.unregister(); self.fire('onSubscriptionCancel'); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } }); } } /** * @return {void} */ }, { key: 'requestSubscription', value: function requestSubscription() { var _this2 = this; var userVisibleOnly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; var self = this; var current = this.getPermissionStatus(); var cb = function cb(result) { if (result === 'granted') { _this2.fire('onPermissionGranted'); if ('serviceWorker' in navigator) { navigator.serviceWorker.register(_this2.workerPath).then(function () { navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) { self.fire('onWorkerSuccess'); serviceWorkerRegistration.pushManager.subscribe({ userVisibleOnly: userVisibleOnly }).then(function (subscription) { var key = subscription.getKey('p256dh'); var token = subscription.getKey('auth'); self.subData = { endpoint: self.getEndpoint(subscription), p256dh: key ? window.btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null, auth: token ? window.btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null }; self.fire('onSubscriptionSuccess', [self.subData]); }).catch(function (err) { self.fire('onWorkerError', [err]); }); }); }); } else { self.fire('onWorkerNotSupported'); } } else if (result === 'denied') { _this2.fire('onPermissionDenied'); _this2.unregisterWorker(); } }; if (current === 'default') { if (window.Notification && window.Notification.requestPermission) { window.Notification.requestPermission(cb); } else if (window.webkitNotifications && window.webkitNotifications.checkPermission) { window.webkitNotifications.requestPermission(cb); } } else { cb(current); } } }]); return Push; }(); /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process, global) {var require;/*! * @overview es6-promise - a tiny implementation of Promises/A+. * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) * @license Licensed under MIT license * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE * @version 4.1.1 */ (function (global, factory) { true ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.ES6Promise = factory()); }(this, (function () { 'use strict'; function objectOrFunction(x) { var type = typeof x; return x !== null && (type === 'object' || type === 'function'); } function isFunction(x) { return typeof x === 'function'; } var _isArray = undefined; if (Array.isArray) { _isArray = Array.isArray; } else { _isArray = function (x) { return Object.prototype.toString.call(x) === '[object Array]'; }; } var isArray = _isArray; var len = 0; var vertxNext = undefined; var customSchedulerFn = undefined; var asap = function asap(callback, arg) { queue[len] = callback; queue[len + 1] = arg; len += 2; if (len === 2) { // If len is 2, that means that we need to schedule an async flush. // If additional callbacks are queued before the queue is flushed, they // will be processed by this flush that we are scheduling. if (customSchedulerFn) { customSchedulerFn(flush); } else { scheduleFlush(); } } }; function setScheduler(scheduleFn) { customSchedulerFn = scheduleFn; } function setAsap(asapFn) { asap = asapFn; } var browserWindow = typeof window !== 'undefined' ? window : undefined; var browserGlobal = browserWindow || {}; var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]'; // test for web worker but not in IE10 var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; // node function useNextTick() { // node version 0.10.x displays a deprecation warning when nextTick is used recursively // see https://github.com/cujojs/when/issues/410 for details return function () { return process.nextTick(flush); }; } // vertx function useVertxTimer() { if (typeof vertxNext !== 'undefined') { return function () { vertxNext(flush); }; } return useSetTimeout(); } function useMutationObserver() { var iterations = 0; var observer = new BrowserMutationObserver(flush); var node = document.createTextNode(''); observer.observe(node, { characterData: true }); return function () { node.data = iterations = ++iterations % 2; }; } // web worker function useMessageChannel() { var channel = new MessageChannel(); channel.port1.onmessage = flush; return function () { return channel.port2.postMessage(0); }; } function useSetTimeout() { // Store setTimeout reference so es6-promise will be unaffected by // other code modifying setTimeout (like sinon.useFakeTimers()) var globalSetTimeout = setTimeout; return function () { return globalSetTimeout(flush, 1); }; } var queue = new Array(1000); function flush() { for (var i = 0; i < len; i += 2) { var callback = queue[i]; var arg = queue[i + 1]; callback(arg); queue[i] = undefined; queue[i + 1] = undefined; } len = 0; } function attemptVertx() { try { var r = require; var vertx = __webpack_require__(9); vertxNext = vertx.runOnLoop || vertx.runOnContext; return useVertxTimer(); } catch (e) { return useSetTimeout(); } } var scheduleFlush = undefined; // Decide what async method to use to triggering processing of queued callbacks: if (isNode) { scheduleFlush = useNextTick(); } else if (BrowserMutationObserver) { scheduleFlush = useMutationObserver(); } else if (isWorker) { scheduleFlush = useMessageChannel(); } else if (browserWindow === undefined && "function" === 'function') { scheduleFlush = attemptVertx(); } else { scheduleFlush = useSetTimeout(); } function then(onFulfillment, onRejection) { var _arguments = arguments; var parent = this; var child = new this.constructor(noop); if (child[PROMISE_ID] === undefined) { makePromise(child); } var _state = parent._state; if (_state) { (function () { var callback = _arguments[_state - 1]; asap(function () { return invokeCallback(_state, child, callback, parent._result); }); })(); } else { subscribe(parent, child, onFulfillment, onRejection); } return child; } /** `Promise.resolve` returns a promise that will become resolved with the passed `value`. It is shorthand for the following: ```javascript let promise = new Promise(function(resolve, reject){ resolve(1); }); promise.then(function(value){ // value === 1 }); ``` Instead of writing the above, your code now simply becomes the following: ```javascript let promise = Promise.resolve(1); promise.then(function(value){ // value === 1 }); ``` @method resolve @static @param {Any} value value that the returned promise will be resolved with Useful for tooling. @return {Promise} a promise that will become fulfilled with the given `value` */ function resolve$1(object) { /*jshint validthis:true */ var Constructor = this; if (object && typeof object === 'object' && object.constructor === Constructor) { return object; } var promise = new Constructor(noop); resolve(promise, object); return promise; } var PROMISE_ID = Math.random().toString(36).substring(16); function noop() {} var PENDING = void 0; var FULFILLED = 1; var REJECTED = 2; var GET_THEN_ERROR = new ErrorObject(); function selfFulfillment() { return new TypeError("You cannot resolve a promise with itself"); } function cannotReturnOwn() { return new TypeError('A promises callback cannot return that same promise.'); } function getThen(promise) { try { return promise.then; } catch (error) { GET_THEN_ERROR.error = error; return GET_THEN_ERROR; } } function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) { try { then$$1.call(value, fulfillmentHandler, rejectionHandler); } catch (e) { return e; } } function handleForeignThenable(promise, thenable, then$$1) { asap(function (promise) { var sealed = false; var error = tryThen(then$$1, thenable, function (value) { if (sealed) { return; } sealed = true; if (thenable !== value) { resolve(promise, value); } else { fulfill(promise, value); } }, function (reason) { if (sealed) { return; } sealed = true; reject(promise, reason); }, 'Settle: ' + (promise._label || ' unknown promise')); if (!sealed && error) { sealed = true; reject(promise, error); } }, promise); } function handleOwnThenable(promise, thenable) { if (thenable._state === FULFILLED) { fulfill(promise, thenable._result); } else if (thenable._state === REJECTED) { reject(promise, thenable._result); } else { subscribe(thenable, undefined, function (value) { return resolve(promise, value); }, function (reason) { return reject(promise, reason); }); } } function handleMaybeThenable(promise, maybeThenable, then$$1) { if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) { handleOwnThenable(promise, maybeThenable); } else { if (then$$1 === GET_THEN_ERROR) { reject(promise, GET_THEN_ERROR.error); GET_THEN_ERROR.error = null; } else if (then$$1 === undefined) { fulfill(promise, maybeThenable); } else if (isFunction(then$$1)) { handleForeignThenable(promise, maybeThenable, then$$1); } else { fulfill(promise, maybeThenable); } } } function resolve(promise, value) { if (promise === value) { reject(promise, selfFulfillment()); } else if (objectOrFunction(value)) { handleMaybeThenable(promise, value, getThen(value)); } else { fulfill(promise, value); } } function publishRejection(promise) { if (promise._onerror) { promise._onerror(promise._result); } publish(promise); } function fulfill(promise, value) { if (promise._state !== PENDING) { return; } promise._result = value; promise._state = FULFILLED; if (promise._subscribers.length !== 0) { asap(publish, promise); } } function reject(promise, reason) { if (promise._state !== PENDING) { return; } promise._state = REJECTED; promise._result = reason; asap(publishRejection, promise); } function subscribe(parent, child, onFulfillment, onRejection) { var _subscribers = parent._subscribers; var length = _subscribers.length; parent._onerror = null; _subscribers[length] = child; _subscribers[length + FULFILLED] = onFulfillment; _subscribers[length + REJECTED] = onRejection; if (length === 0 && parent._state) { asap(publish, parent); } } function publish(promise) { var subscribers = promise._subscribers; var settled = promise._state; if (subscribers.length === 0) { return; } var child = undefined, callback = undefined, detail = promise._result; for (var i = 0; i < subscribers.length; i += 3) { child = subscribers[i]; callback = subscribers[i + settled]; if (child) { invokeCallback(settled, child, callback, detail); } else { callback(detail); } } promise._subscribers.length = 0; } function ErrorObject() { this.error = null; } var TRY_CATCH_ERROR = new ErrorObject(); function tryCatch(callback, detail) { try { return callback(detail); } catch (e) { TRY_CATCH_ERROR.error = e; return TRY_CATCH_ERROR; } } function invokeCallback(settled, promise, callback, detail) { var hasCallback = isFunction(callback), value = undefined, error = undefined, succeeded = undefined, failed = undefined; if (hasCallback) { value = tryCatch(callback, detail); if (value === TRY_CATCH_ERROR) { failed = true; error = value.error; value.error = null; } else { succeeded = true; } if (promise === value) { reject(promise, cannotReturnOwn()); return; } } else { value = detail; succeeded = true; } if (promise._state !== PENDING) { // noop } else if (hasCallback && succeeded) { resolve(promise, value); } else if (failed) { reject(promise, error); } else if (settled === FULFILLED) { fulfill(promise, value); } else if (settled === REJECTED) { reject(promise, value); } } function initializePromise(promise, resolver) { try { resolver(function resolvePromise(value) { resolve(promise, value); }, function rejectPromise(reason) { reject(promise, reason); }); } catch (e) { reject(promise, e); } } var id = 0; function nextId() { return id++; } function makePromise(promise) { promise[PROMISE_ID] = id++; promise._state = undefined; promise._result = undefined; promise._subscribers = []; } function Enumerator$1(Constructor, input) { this._instanceConstructor = Constructor; this.promise = new Constructor(noop); if (!this.promise[PROMISE_ID]) { makePromise(this.promise); } if (isArray(input)) { this.length = input.length; this._remaining = input.length; this._result = new Array(this.length); if (this.length === 0) { fulfill(this.promise, this._result); } else { this.length = this.length || 0; this._enumerate(input); if (this._remaining === 0) { fulfill(this.promise, this._result); } } } else { reject(this.promise, validationError()); } } function validationError() { return new Error('Array Methods must be provided an Array'); } Enumerator$1.prototype._enumerate = function (input) { for (var i = 0; this._state === PENDING && i < input.length; i++) { this._eachEntry(input[i], i); } }; Enumerator$1.prototype._eachEntry = function (entry, i) { var c = this._instanceConstructor; var resolve$$1 = c.resolve; if (resolve$$1 === resolve$1) { var _then = getThen(entry); if (_then === then && entry._state !== PENDING) { this._settledAt(entry._state, i, entry._result); } else if (typeof _then !== 'function') { this._remaining--; this._result[i] = entry; } else if (c === Promise$2) { var promise = new c(noop); handleMaybeThenable(promise, entry, _then); this._willSettleAt(promise, i); } else { this._willSettleAt(new c(function (resolve$$1) { return resolve$$1(entry); }), i); } } else { this._willSettleAt(resolve$$1(entry), i); } }; Enumerator$1.prototype._settledAt = function (state, i, value) { var promise = this.promise; if (promise._state === PENDING) { this._remaining--; if (state === REJECTED) { reject(promise, value); } else { this._result[i] = value; } } if (this._remaining === 0) { fulfill(promise, this._result); } }; Enumerator$1.prototype._willSettleAt = function (promise, i) { var enumerator = this; subscribe(promise, undefined, function (value) { return enumerator._settledAt(FULFILLED, i, value); }, function (reason) { return enumerator._settledAt(REJECTED, i, reason); }); }; /** `Promise.all` accepts an array of promises, and returns a new promise which is fulfilled with an array of fulfillment values for the passed promises, or rejected with the reason of the first passed promise to be rejected. It casts all elements of the passed iterable to promises as it runs this algorithm. Example: ```javascript let promise1 = resolve(1); let promise2 = resolve(2); let promise3 = resolve(3); let promises = [ promise1, promise2, promise3 ]; Promise.all(promises).then(function(array){ // The array here would be [ 1, 2, 3 ]; }); ``` If any of the `promises` given to `all` are rejected, the first promise that is rejected will be given as an argument to the returned promises's rejection handler. For example: Example: ```javascript let promise1 = resolve(1); let promise2 = reject(new Error("2")); let promise3 = reject(new Error("3")); let promises = [ promise1, promise2, promise3 ]; Promise.all(promises).then(function(array){ // Code here never runs because there are rejected promises! }, function(error) { // error.message === "2" }); ``` @method all @static @param {Array} entries array of promises @param {String} label optional string for labeling the promise. Useful for tooling. @return {Promise} promise that is fulfilled when all `promises` have been fulfilled, or rejected if any of them become rejected. @static */ function all$1(entries) { return new Enumerator$1(this, entries).promise; } /** `Promise.race` returns a new promise which is settled in the same way as the first passed promise to settle. Example: ```javascript let promise1 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve('promise 1'); }, 200); }); let promise2 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve('promise 2'); }, 100); }); Promise.race([promise1, promise2]).then(function(result){ // result === 'promise 2' because it was resolved before promise1 // was resolved. }); ``` `Promise.race` is deterministic in that only the state of the first settled promise matters. For example, even if other promises given to the `promises` array argument are resolved, but the first settled promise has become rejected before the other promises became fulfilled, the returned promise will become rejected: ```javascript let promise1 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve('promise 1'); }, 200); }); let promise2 = new Promise(function(resolve, reject){ setTimeout(function(){ reject(new Error('promise 2')); }, 100); }); Promise.race([promise1, promise2]).then(function(result){ // Code here never runs }, function(reason){ // reason.message === 'promise 2' because promise 2 became rejected before // promise 1 became fulfilled }); ``` An example real-world use case is implementing timeouts: ```javascript Promise.race([ajax('foo.json'), timeout(5000)]) ``` @method race @static @param {Array} promises array of promises to observe Useful for tooling. @return {Promise} a promise which settles in the same way as the first passed promise to settle. */ function race$1(entries) { /*jshint validthis:true */ var Constructor = this; if (!isArray(entries)) { return new Constructor(function (_, reject) { return reject(new TypeError('You must pass an array to race.')); }); } else { return new Constructor(function (resolve, reject) { var length = entries.length; for (var i = 0; i < length; i++) { Constructor.resolve(entries[i]).then(resolve, reject); } }); } } /** `Promise.reject` returns a promise rejected with the passed `reason`. It is shorthand for the following: ```javascript let promise = new Promise(function(resolve, reject){ reject(new Error('WHOOPS')); }); promise.then(function(value){ // Code here doesn't run because the promise is rejected! }, function(reason){ // reason.message === 'WHOOPS' }); ``` Instead of writing the above, your code now simply becomes the following: ```javascript let promise = Promise.reject(new Error('WHOOPS')); promise.then(function(value){ // Code here doesn't run because the promise is rejected! }, function(reason){ // reason.message === 'WHOOPS' }); ``` @method reject @static @param {Any} reason value that the returned promise will be rejected with. Useful for tooling. @return {Promise} a promise rejected with the given `reason`. */ function reject$1(reason) { /*jshint validthis:true */ var Constructor = this; var promise = new Constructor(noop); reject(promise, reason); return promise; } function needsResolver() { throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); } function needsNew() { throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); } /** Promise objects represent the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its `then` method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled. Terminology ----------- - `promise` is an object or function with a `then` method whose behavior conforms to this specification. - `thenable` is an object or function that defines a `then` method. - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). - `exception` is a value that is thrown using the throw statement. - `reason` is a value that indicates why a promise was rejected. - `settled` the final resting state of a promise, fulfilled or rejected. A promise can be in one of three states: pending, fulfilled, or rejected. Promises that are fulfilled have a fulfillment value and are in the fulfilled state. Promises that are rejected have a rejection reason and are in the rejected state. A fulfillment value is never a thenable. Promises can also be said to *resolve* a value. If this value is also a promise, then the original promise's settled state will match the value's settled state. So a promise that *resolves* a promise that rejects will itself reject, and a promise that *resolves* a promise that fulfills will itself fulfill. Basic Usage: ------------ ```js let promise = new Promise(function(resolve, reject) { // on success resolve(value); // on failure reject(reason); }); promise.then(function(value) { // on fulfillment }, function(reason) { // on rejection }); ``` Advanced Usage: --------------- Promises shine when abstracting away asynchronous interactions such as `XMLHttpRequest`s. ```js function getJSON(url) { return new Promise(function(resolve, reject){ let xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.onreadystatechange = handler; xhr.responseType = 'json'; xhr.setRequestHeader('Accept', 'application/json'); xhr.send(); function handler() { if (this.readyState === this.DONE) { if (this.status === 200) { resolve(this.response); } else { reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); } } }; }); } getJSON('/posts.json').then(function(json) { // on fulfillment }, function(reason) { // on rejection }); ``` Unlike callbacks, promises are great composable primitives. ```js Promise.all([ getJSON('/posts'), getJSON('/comments') ]).then(function(values){ values[0] // => postsJSON values[1] // => commentsJSON return values; }); ``` @class Promise @param {function} resolver Useful for tooling. @constructor */ function Promise$2(resolver) { this[PROMISE_ID] = nextId(); this._result = this._state = undefined; this._subscribers = []; if (noop !== resolver) { typeof resolver !== 'function' && needsResolver(); this instanceof Promise$2 ? initializePromise(this, resolver) : needsNew(); } } Promise$2.all = all$1; Promise$2.race = race$1; Promise$2.resolve = resolve$1; Promise$2.reject = reject$1; Promise$2._setScheduler = setScheduler; Promise$2._setAsap = setAsap; Promise$2._asap = asap; Promise$2.prototype = { constructor: Promise$2, /** The primary way of interacting with a promise is through its `then` method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled. ```js findUser().then(function(user){ // user is available }, function(reason){ // user is unavailable, and you are given the reason why }); ``` Chaining -------- The return value of `then` is itself a promise. This second, 'downstream' promise is resolved with the return value of the first promise's fulfillment or rejection handler, or rejected if the handler throws an exception. ```js findUser().then(function (user) { return user.name; }, function (reason) { return 'default name'; }).then(function (userName) { // If `findUser` fulfilled, `userName` will be the user's name, otherwise it // will be `'default name'` }); findUser().then(function (user) { throw new Error('Found user, but still unhappy'); }, function (reason) { throw new Error('`findUser` rejected and we're unhappy'); }).then(function (value) { // never reached }, function (reason) { // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. }); ``` If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. ```js findUser().then(function (user) { throw new PedagogicalException('Upstream error'); }).then(function (value) { // never reached }).then(function (value) { // never reached }, function (reason) { // The `PedgagocialException` is propagated all the way down to here }); ``` Assimilation ------------ Sometimes the value you want to propagate to a downstream promise can only be retrieved asynchronously. This can be achieved by returning a promise in the fulfillment or rejection handler. The downstream promise will then be pending until the returned promise is settled. This is called *assimilation*. ```js findUser().then(function (user) { return findCommentsByAuthor(user); }).then(function (comments) { // The user's comments are now available }); ``` If the assimliated promise rejects, then the downstream promise will also reject. ```js findUser().then(function (user) { return findCommentsByAuthor(user); }).then(function (comments) { // If `findCommentsByAuthor` fulfills, we'll have the value here }, function (reason) { // If `findCommentsByAuthor` rejects, we'll have the reason here }); ``` Simple Example -------------- Synchronous Example ```javascript let result; try { result = findResult(); // success } catch(reason) { // failure } ``` Errback Example ```js findResult(function(result, err){ if (err) { // failure } else { // success } }); ``` Promise Example; ```javascript findResult().then(function(result){ // success }, function(reason){ // failure }); ``` Advanced Example -------------- Synchronous Example ```javascript let author, books; try { author = findAuthor(); books = findBooksByAuthor(author); // success } catch(reason) { // failure } ``` Errback Example ```js function foundBooks(books) { } function failure(reason) { } findAuthor(function(author, err){ if (err) { failure(err); // failure } else { try { findBoooksByAuthor(author, function(books, err) { if (err) { failure(err); } else { try { foundBooks(books); } catch(reason) { failure(reason); } } }); } catch(error) { failure(err); } // success } }); ``` Promise Example; ```javascript findAuthor(). then(findBooksByAuthor). then(function(books){ // found books }).catch(function(reason){ // something went wrong }); ``` @method then @param {Function} onFulfilled @param {Function} onRejected Useful for tooling. @return {Promise} */ then: then, /** `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same as the catch block of a try/catch statement. ```js function findAuthor(){ throw new Error('couldn't find that author'); } // synchronous try { findAuthor(); } catch(reason) { // something went wrong } // async with promises findAuthor().catch(function(reason){ // something went wrong }); ``` @method catch @param {Function} onRejection Useful for tooling. @return {Promise} */ 'catch': function _catch(onRejection) { return this.then(null, onRejection); } }; /*global self*/ function polyfill$1() { var local = undefined; if (typeof global !== 'undefined') { local = global; } else if (typeof self !== 'undefined') { local = self; } else { try { local = Function('return this')(); } catch (e) { throw new Error('polyfill failed because global object is unavailable in this environment'); } } var P = local.Promise; if (P) { var promiseToString = null; try { promiseToString = Object.prototype.toString.call(P.resolve()); } catch (e) { // silently ignored } if (promiseToString === '[object Promise]' && !P.cast) { return; } } local.Promise = Promise$2; } // Strange compat.. Promise$2.polyfill = polyfill$1; Promise$2.Promise = Promise$2; return Promise$2; }))); //# sourceMappingURL=es6-promise.map /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7), __webpack_require__(8))) /***/ }), /* 5 */ /***/ (function(module, exports) { // removed by extract-text-webpack-plugin /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global VERSION */ __webpack_require__(5); var _es6Promise = __webpack_require__(4); var _es6Promise2 = _interopRequireDefault(_es6Promise); var _utils = __webpack_require__(0); var Utils = _interopRequireWildcard(_utils); var _api = __webpack_require__(1); var API = _interopRequireWildcard(_api); var _button = __webpack_require__(2); var _push = __webpack_require__(3); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Noty = function () { /** * @param {object} options * @return {Noty} */ function Noty() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, Noty); this.options = Utils.deepExtend({}, API.Defaults, options); if (API.Store[this.options.id]) { return API.Store[this.options.id]; } this.id = this.options.id || Utils.generateID('bar'); this.closeTimer = -1; this.barDom = null; this.layoutDom = null; this.progressDom = null; this.showing = false; this.shown = false; this.closed = false; this.closing = false; this.killable = this.options.timeout || this.options.closeWith.length > 0; this.hasSound = this.options.sounds.sources.length > 0; this.soundPlayed = false; this.listeners = { beforeShow: [], onShow: [], afterShow: [], onClose: [], afterClose: [], onClick: [], onHover: [], onTemplate: [] }; this.promises = { show: null, close: null }; this.on('beforeShow', this.options.callbacks.beforeShow); this.on('onShow', this.options.callbacks.onShow); this.on('afterShow', this.options.callbacks.afterShow); this.on('onClose', this.options.callbacks.onClose); this.on('afterClose', this.options.callbacks.afterClose); this.on('onClick', this.options.callbacks.onClick); this.on('onHover', this.options.callbacks.onHover); this.on('onTemplate', this.options.callbacks.onTemplate); return this; } /** * @param {string} eventName * @param {function} cb * @return {Noty} */ _createClass(Noty, [{ key: 'on', value: function on(eventName) { var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) { this.listeners[eventName].push(cb); } return this; } /** * @return {Noty} */ }, { key: 'show', value: function show() { var _this = this; if (this.showing || this.shown) { return this; // preventing multiple show } if (this.options.killer === true) { Noty.closeAll(); } else if (typeof this.options.killer === 'string') { Noty.closeAll(this.options.killer); } var queueCounts = API.getQueueCounts(this.options.queue); if (queueCounts.current >= queueCounts.maxVisible || API.PageHidden && this.options.visibilityControl) { API.addToQueue(this); if (API.PageHidden && this.hasSound && Utils.inArray('docHidden', this.options.sounds.conditions)) { Utils.createAudioElements(this); } if (API.PageHidden && Utils.inArray('docHidden', this.options.titleCount.conditions)) { API.docTitle.increment(); } return this; } API.Store[this.id] = this; API.fire(this, 'beforeShow'); this.showing = true; if (this.closing) { this.showing = false; return this; } API.build(this); API.handleModal(this); if (this.options.force) { this.layoutDom.insertBefore(this.barDom, this.layoutDom.firstChild); } else { this.layoutDom.appendChild(this.barDom); } if (this.hasSound && !this.soundPlayed && Utils.inArray('docVisible', this.options.sounds.conditions)) { Utils.createAudioElements(this); } if (Utils.inArray('docVisible', this.options.titleCount.conditions)) { API.docTitle.increment(); } this.shown = true; this.closed = false; // bind button events if any if (API.hasButtons(this)) { Object.keys(this.options.buttons).forEach(function (key) { var btn = _this.barDom.querySelector('#' + _this.options.buttons[key].id); Utils.addListener(btn, 'click', function (e) { Utils.stopPropagation(e); _this.options.buttons[key].cb(_this); }); }); } this.progressDom = this.barDom.querySelector('.noty_progressbar'); if (Utils.inArray('click', this.options.closeWith)) { Utils.addClass(this.barDom, 'noty_close_with_click'); Utils.addListener(this.barDom, 'click', function (e) { Utils.stopPropagation(e); API.fire(_this, 'onClick'); _this.close(); }, false); } Utils.addListener(this.barDom, 'mouseenter', function () { API.fire(_this, 'onHover'); }, false); if (this.options.timeout) Utils.addClass(this.barDom, 'noty_has_timeout'); if (this.options.progressBar) { Utils.addClass(this.barDom, 'noty_has_progressbar'); } if (Utils.inArray('button', this.options.closeWith)) { Utils.addClass(this.barDom, 'noty_close_with_button'); var closeButton = document.createElement('div'); Utils.addClass(closeButton, 'noty_close_button'); closeButton.innerHTML = '×'; this.barDom.appendChild(closeButton); Utils.addListener(closeButton, 'click', function (e) { Utils.stopPropagation(e); _this.close(); }, false); } API.fire(this, 'onShow'); if (this.options.animation.open === null) { this.promises.show = new _es6Promise2.default(function (resolve) { resolve(); }); } else if (typeof this.options.animation.open === 'function') { this.promises.show = new _es6Promise2.default(this.options.animation.open.bind(this)); } else { Utils.addClass(this.barDom, this.options.animation.open); this.promises.show = new _es6Promise2.default(function (resolve) { Utils.addListener(_this.barDom, Utils.animationEndEvents, function () { Utils.removeClass(_this.barDom, _this.options.animation.open); resolve(); }); }); } this.promises.show.then(function () { var _t = _this; setTimeout(function () { API.openFlow(_t); }, 100); }); return this; } /** * @return {Noty} */ }, { key: 'stop', value: function stop() { API.dequeueClose(this); return this; } /** * @return {Noty} */ }, { key: 'resume', value: function resume() { API.queueClose(this); return this; } /** * @param {int|boolean} ms * @return {Noty} */ }, { key: 'setTimeout', value: function (_setTimeout) { function setTimeout(_x) { return _setTimeout.apply(this, arguments); } setTimeout.toString = function () { return _setTimeout.toString(); }; return setTimeout; }(function (ms) { this.stop(); this.options.timeout = ms; if (this.barDom) { if (this.options.timeout) { Utils.addClass(this.barDom, 'noty_has_timeout'); } else { Utils.removeClass(this.barDom, 'noty_has_timeout'); } var _t = this; setTimeout(function () { // ugly fix for progressbar display bug _t.resume(); }, 100); } return this; }) /** * @param {string} html * @param {boolean} optionsOverride * @return {Noty} */ }, { key: 'setText', value: function setText(html) { var optionsOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (this.barDom) { this.barDom.querySelector('.noty_body').innerHTML = html; } if (optionsOverride) this.options.text = html; return this; } /** * @param {string} type * @param {boolean} optionsOverride * @return {Noty} */ }, { key: 'setType', value: function setType(type) { var _this2 = this; var optionsOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (this.barDom) { var classList = Utils.classList(this.barDom).split(' '); classList.forEach(function (c) { if (c.substring(0, 11) === 'noty_type__') { Utils.removeClass(_this2.barDom, c); } }); Utils.addClass(this.barDom, 'noty_type__' + type); } if (optionsOverride) this.options.type = type; return this; } /** * @param {string} theme * @param {boolean} optionsOverride * @return {Noty} */ }, { key: 'setTheme', value: function setTheme(theme) { var _this3 = this; var optionsOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (this.barDom) { var classList = Utils.classList(this.barDom).split(' '); classList.forEach(function (c) { if (c.substring(0, 12) === 'noty_theme__') { Utils.removeClass(_this3.barDom, c); } }); Utils.addClass(this.barDom, 'noty_theme__' + theme); } if (optionsOverride) this.options.theme = theme; return this; } /** * @return {Noty} */ }, { key: 'close', value: function close() { var _this4 = this; if (this.closed) return this; if (!this.shown) { // it's in the queue API.removeFromQueue(this); return this; } API.fire(this, 'onClose'); this.closing = true; if (this.options.animation.close === null || this.options.animation.close === false) { this.promises.close = new _es6Promise2.default(function (resolve) { resolve(); }); } else if (typeof this.options.animation.close === 'function') { this.promises.close = new _es6Promise2.default(this.options.animation.close.bind(this)); } else { Utils.addClass(this.barDom, this.options.animation.close); this.promises.close = new _es6Promise2.default(function (resolve) { Utils.addListener(_this4.barDom, Utils.animationEndEvents, function () { if (_this4.options.force) { Utils.remove(_this4.barDom); } else { API.ghostFix(_this4); } resolve(); }); }); } this.promises.close.then(function () { API.closeFlow(_this4); API.handleModalClose(_this4); }); this.closed = true; return this; } // API functions /** * @param {boolean|string} queueName * @return {Noty} */ }], [{ key: 'closeAll', value: function closeAll() { var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; Object.keys(API.Store).forEach(function (id) { if (queueName) { if (API.Store[id].options.queue === queueName && API.Store[id].killable) { API.Store[id].close(); } } else if (API.Store[id].killable) { API.Store[id].close(); } }); return this; } /** * @param {string} queueName * @return {Noty} */ }, { key: 'clearQueue', value: function clearQueue() { var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'global'; if (API.Queues.hasOwnProperty(queueName)) { API.Queues[queueName].queue = []; } return this; } /** * @return {API.Queues} */ }, { key: 'overrideDefaults', /** * @param {Object} obj * @return {Noty} */ value: function overrideDefaults(obj) { API.Defaults = Utils.deepExtend({}, API.Defaults, obj); return this; } /** * @param {int} amount * @param {string} queueName * @return {Noty} */ }, { key: 'setMaxVisible', value: function setMaxVisible() { var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : API.DefaultMaxVisible; var queueName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'global'; if (!API.Queues.hasOwnProperty(queueName)) { API.Queues[queueName] = { maxVisible: amount, queue: [] }; } API.Queues[queueName].maxVisible = amount; return this; } /** * @param {string} innerHtml * @param {String} classes * @param {Function} cb * @param {Object} attributes * @return {NotyButton} */ }, { key: 'button', value: function button(innerHtml) { var classes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var cb = arguments[2]; var attributes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; return new _button.NotyButton(innerHtml, classes, cb, attributes); } /** * @return {string} */ }, { key: 'version', value: function version() { return "3.2.0-beta"; } /** * @param {String} workerPath * @return {Push} */ }, { key: 'Push', value: function Push(workerPath) { return new _push.Push(workerPath); } }, { key: 'Queues', get: function get() { return API.Queues; } /** * @return {API.PageHidden} */ }, { key: 'PageHidden', get: function get() { return API.PageHidden; } }]); return Noty; }(); // Document visibility change controller exports.default = Noty; if (typeof window !== 'undefined') { Utils.visibilityChangeFlow(); } module.exports = exports['default']; /***/ }), /* 7 */ /***/ (function(module, exports) { // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; /***/ }), /* 8 */ /***/ (function(module, exports) { var g; // This works in non-strict mode g = (function() { return this; })(); try { // This works if eval is allowed (see CSP) g = g || Function("return this")() || (1,eval)("this"); } catch(e) { // This works if the window reference is available if(typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /* 9 */ /***/ (function(module, exports) { /* (ignored) */ /***/ }) /******/ ]); }); //# sourceMappingURL=noty.js.map ================================================ FILE: lib/themes/bootstrap-v3.css ================================================ .noty_theme__bootstrap-v3.noty_bar { margin: 4px 0; overflow: hidden; position: relative; border: 1px solid transparent; border-radius: 4px; } .noty_theme__bootstrap-v3.noty_bar .noty_body { padding: 15px; } .noty_theme__bootstrap-v3.noty_bar .noty_buttons { padding: 10px; } .noty_theme__bootstrap-v3.noty_bar .noty_close_button { font-size: 21px; font-weight: 700; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .2; background: transparent; } .noty_theme__bootstrap-v3.noty_bar .noty_close_button:hover { background: transparent; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .5; } .noty_theme__bootstrap-v3.noty_type__alert, .noty_theme__bootstrap-v3.noty_type__notification { background-color: #fff; color: inherit; } .noty_theme__bootstrap-v3.noty_type__warning { background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc; } .noty_theme__bootstrap-v3.noty_type__error { background-color: #f2dede; color: #a94442; border-color: #ebccd1; } .noty_theme__bootstrap-v3.noty_type__info, .noty_theme__bootstrap-v3.noty_type__information { background-color: #d9edf7; color: #31708f; border-color: #bce8f1; } .noty_theme__bootstrap-v3.noty_type__success { background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; } ================================================ FILE: lib/themes/bootstrap-v4.css ================================================ .noty_theme__bootstrap-v4.noty_bar { margin: 4px 0; overflow: hidden; position: relative; border: 1px solid transparent; border-radius: .25rem; } .noty_theme__bootstrap-v4.noty_bar .noty_body { padding: .75rem 1.25rem; } .noty_theme__bootstrap-v4.noty_bar .noty_buttons { padding: 10px; } .noty_theme__bootstrap-v4.noty_bar .noty_close_button { font-size: 1.5rem; font-weight: 700; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .5; background: transparent; } .noty_theme__bootstrap-v4.noty_bar .noty_close_button:hover { background: transparent; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .75; } .noty_theme__bootstrap-v4.noty_type__alert, .noty_theme__bootstrap-v4.noty_type__notification { background-color: #fff; color: inherit; } .noty_theme__bootstrap-v4.noty_type__warning { background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc; } .noty_theme__bootstrap-v4.noty_type__error { background-color: #f2dede; color: #a94442; border-color: #ebccd1; } .noty_theme__bootstrap-v4.noty_type__info, .noty_theme__bootstrap-v4.noty_type__information { background-color: #d9edf7; color: #31708f; border-color: #bce8f1; } .noty_theme__bootstrap-v4.noty_type__success { background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; } ================================================ FILE: lib/themes/light.css ================================================ .noty_theme__light.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; } .noty_theme__light.noty_bar .noty_body { padding: 10px; } .noty_theme__light.noty_bar .noty_buttons { border-top: 1px solid #e7e7e7; padding: 5px 10px; } .noty_theme__light.noty_type__alert, .noty_theme__light.noty_type__notification { background-color: #fff; border: 1px solid #dedede; color: #444; } .noty_theme__light.noty_type__warning { background-color: #FFEAA8; border: 1px solid #FFC237; color: #826200; } .noty_theme__light.noty_type__warning .noty_buttons { border-color: #dfaa30; } .noty_theme__light.noty_type__error { background-color: #ED7000; border: 1px solid #e25353; color: #FFF; } .noty_theme__light.noty_type__error .noty_buttons { border-color: darkred; } .noty_theme__light.noty_type__info, .noty_theme__light.noty_type__information { background-color: #78C5E7; border: 1px solid #3badd6; color: #FFF; } .noty_theme__light.noty_type__info .noty_buttons, .noty_theme__light.noty_type__information .noty_buttons { border-color: #0B90C4; } .noty_theme__light.noty_type__success { background-color: #57C880; border: 1px solid #7cdd77; color: darkgreen; } .noty_theme__light.noty_type__success .noty_buttons { border-color: #50C24E; } ================================================ FILE: lib/themes/metroui.css ================================================ .noty_theme__metroui.noty_bar { margin: 4px 0; overflow: hidden; position: relative; box-shadow: rgba(0, 0, 0, 0.298039) 0 0 5px 0; } .noty_theme__metroui.noty_bar .noty_progressbar { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background-color: #000; opacity: 0.2; filter: alpha(opacity=20); } .noty_theme__metroui.noty_bar .noty_body { padding: 1.25em; font-size: 14px; } .noty_theme__metroui.noty_bar .noty_buttons { padding: 0 10px .5em 10px; } .noty_theme__metroui.noty_type__alert, .noty_theme__metroui.noty_type__notification { background-color: #fff; color: #1d1d1d; } .noty_theme__metroui.noty_type__warning { background-color: #FA6800; color: #fff; } .noty_theme__metroui.noty_type__error { background-color: #CE352C; color: #FFF; } .noty_theme__metroui.noty_type__info, .noty_theme__metroui.noty_type__information { background-color: #1BA1E2; color: #FFF; } .noty_theme__metroui.noty_type__success { background-color: #60A917; color: #fff; } ================================================ FILE: lib/themes/mint.css ================================================ .noty_theme__mint.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; } .noty_theme__mint.noty_bar .noty_body { padding: 10px; font-size: 14px; } .noty_theme__mint.noty_bar .noty_buttons { padding: 10px; } .noty_theme__mint.noty_type__alert, .noty_theme__mint.noty_type__notification { background-color: #fff; border-bottom: 1px solid #D1D1D1; color: #2F2F2F; } .noty_theme__mint.noty_type__warning { background-color: #FFAE42; border-bottom: 1px solid #E89F3C; color: #fff; } .noty_theme__mint.noty_type__error { background-color: #DE636F; border-bottom: 1px solid #CA5A65; color: #fff; } .noty_theme__mint.noty_type__info, .noty_theme__mint.noty_type__information { background-color: #7F7EFF; border-bottom: 1px solid #7473E8; color: #fff; } .noty_theme__mint.noty_type__success { background-color: #AFC765; border-bottom: 1px solid #A0B55C; color: #fff; } ================================================ FILE: lib/themes/nest.css ================================================ .noty_theme__nest.noty_bar { margin: 0 0 15px 0; overflow: hidden; border-radius: 2px; position: relative; box-shadow: rgba(0, 0, 0, 0.098039) 5px 4px 10px 0; } .noty_theme__nest.noty_bar .noty_body { padding: 10px; font-size: 14px; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); } .noty_theme__nest.noty_bar .noty_buttons { padding: 10px; } .noty_layout .noty_theme__nest.noty_bar { z-index: 5; } .noty_layout .noty_theme__nest.noty_bar:nth-child(2) { position: absolute; top: 0; margin-top: 4px; margin-right: -4px; margin-left: 4px; z-index: 4; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(3) { position: absolute; top: 0; margin-top: 8px; margin-right: -8px; margin-left: 8px; z-index: 3; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(4) { position: absolute; top: 0; margin-top: 12px; margin-right: -12px; margin-left: 12px; z-index: 2; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(5) { position: absolute; top: 0; margin-top: 16px; margin-right: -16px; margin-left: 16px; z-index: 1; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(n+6) { position: absolute; top: 0; margin-top: 20px; margin-right: -20px; margin-left: 20px; z-index: -1; width: 100%; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(2), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(2) { margin-top: 4px; margin-left: -4px; margin-right: 4px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(3), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(3) { margin-top: 8px; margin-left: -8px; margin-right: 8px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(4), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(4) { margin-top: 12px; margin-left: -12px; margin-right: 12px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(5), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(5) { margin-top: 16px; margin-left: -16px; margin-right: 16px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(n+6), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(n+6) { margin-top: 20px; margin-left: -20px; margin-right: 20px; } .noty_theme__nest.noty_type__alert, .noty_theme__nest.noty_type__notification { background-color: #073B4C; color: #fff; } .noty_theme__nest.noty_type__alert .noty_progressbar, .noty_theme__nest.noty_type__notification .noty_progressbar { background-color: #fff; } .noty_theme__nest.noty_type__warning { background-color: #FFD166; color: #fff; } .noty_theme__nest.noty_type__error { background-color: #EF476F; color: #fff; } .noty_theme__nest.noty_type__error .noty_progressbar { opacity: .4; } .noty_theme__nest.noty_type__info, .noty_theme__nest.noty_type__information { background-color: #118AB2; color: #fff; } .noty_theme__nest.noty_type__info .noty_progressbar, .noty_theme__nest.noty_type__information .noty_progressbar { opacity: .6; } .noty_theme__nest.noty_type__success { background-color: #06D6A0; color: #fff; } ================================================ FILE: lib/themes/relax.css ================================================ .noty_theme__relax.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; } .noty_theme__relax.noty_bar .noty_body { padding: 10px; } .noty_theme__relax.noty_bar .noty_buttons { border-top: 1px solid #e7e7e7; padding: 5px 10px; } .noty_theme__relax.noty_type__alert, .noty_theme__relax.noty_type__notification { background-color: #fff; border: 1px solid #dedede; color: #444; } .noty_theme__relax.noty_type__warning { background-color: #FFEAA8; border: 1px solid #FFC237; color: #826200; } .noty_theme__relax.noty_type__warning .noty_buttons { border-color: #dfaa30; } .noty_theme__relax.noty_type__error { background-color: #FF8181; border: 1px solid #e25353; color: #FFF; } .noty_theme__relax.noty_type__error .noty_buttons { border-color: darkred; } .noty_theme__relax.noty_type__info, .noty_theme__relax.noty_type__information { background-color: #78C5E7; border: 1px solid #3badd6; color: #FFF; } .noty_theme__relax.noty_type__info .noty_buttons, .noty_theme__relax.noty_type__information .noty_buttons { border-color: #0B90C4; } .noty_theme__relax.noty_type__success { background-color: #BCF5BC; border: 1px solid #7cdd77; color: darkgreen; } .noty_theme__relax.noty_type__success .noty_buttons { border-color: #50C24E; } ================================================ FILE: lib/themes/semanticui.css ================================================ .noty_theme__semanticui.noty_bar { margin: 4px 0; overflow: hidden; position: relative; border: 1px solid transparent; font-size: 1em; border-radius: .28571429rem; box-shadow: 0 0 0 1px rgba(34, 36, 38, 0.22) inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_bar .noty_body { padding: 1em 1.5em; line-height: 1.4285em; } .noty_theme__semanticui.noty_bar .noty_buttons { padding: 10px; } .noty_theme__semanticui.noty_type__alert, .noty_theme__semanticui.noty_type__notification { background-color: #f8f8f9; color: rgba(0, 0, 0, 0.87); } .noty_theme__semanticui.noty_type__warning { background-color: #fffaf3; color: #573a08; box-shadow: 0 0 0 1px #c9ba9b inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_type__error { background-color: #fff6f6; color: #9f3a38; box-shadow: 0 0 0 1px #e0b4b4 inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_type__info, .noty_theme__semanticui.noty_type__information { background-color: #f8ffff; color: #276f86; box-shadow: 0 0 0 1px #a9d5de inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_type__success { background-color: #fcfff5; color: #2c662d; box-shadow: 0 0 0 1px #a3c293 inset, 0 0 0 0 transparent; } ================================================ FILE: lib/themes/sunset.css ================================================ .noty_theme__sunset.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; } .noty_theme__sunset.noty_bar .noty_body { padding: 10px; font-size: 14px; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); } .noty_theme__sunset.noty_bar .noty_buttons { padding: 10px; } .noty_theme__sunset.noty_type__alert, .noty_theme__sunset.noty_type__notification { background-color: #073B4C; color: #fff; } .noty_theme__sunset.noty_type__alert .noty_progressbar, .noty_theme__sunset.noty_type__notification .noty_progressbar { background-color: #fff; } .noty_theme__sunset.noty_type__warning { background-color: #FFD166; color: #fff; } .noty_theme__sunset.noty_type__error { background-color: #EF476F; color: #fff; } .noty_theme__sunset.noty_type__error .noty_progressbar { opacity: .4; } .noty_theme__sunset.noty_type__info, .noty_theme__sunset.noty_type__information { background-color: #118AB2; color: #fff; } .noty_theme__sunset.noty_type__info .noty_progressbar, .noty_theme__sunset.noty_type__information .noty_progressbar { opacity: .6; } .noty_theme__sunset.noty_type__success { background-color: #06D6A0; color: #fff; } ================================================ FILE: manifest.json.template ================================================ { "name": "NOTY", "short_name": "NOTY", "start_url": "./demo/push.html", "display": "standalone", "gcm_sender_id": "<-your-sender-id>" } ================================================ FILE: package.json ================================================ { "name": "noty", "version": "3.2.0-beta", "title": "Noty - Dependency-free notification library", "description": "Noty is a dependency-free notification library that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)", "homepage": "https://ned.im/noty", "main": "lib/noty.js", "types": "index.d.ts", "keywords": [ "noty", "notification", "alert", "confirm", "confirmation", "success", "error", "warning", "information" ], "files": [ "lib", "src", "index.d.ts" ], "bugs": { "url": "https://github.com/needim/noty/issues" }, "repository": { "type": "git", "url": "git://github.com/needim/noty.git" }, "author": { "name": "Nedim Arabacı", "url": "http://ned.im" }, "license": "MIT", "scripts": { "build": "grunt themes && webpack --env dev && webpack --env build && grunt banner", "dev": "grunt themes && webpack --progress --colors --watch --env dev", "format": "prettier-standard 'src/**/*.js'", "test": "npm run format && standard && grunt test", "browserstack": "node_modules/.bin/browserstack-runner", "precommit-msg": "echo 'Pre-commit checks...' && exit 0", "serve-docs": "docsify start ./docs" }, "pre-commit": [ "precommit-msg", "test" ], "standard": { "ignore": [ "demo/**/*", "docs/**/*", "lib/**", "test/**" ], "parser": "babel-eslint" }, "devDependencies": { "autoprefixer": "^6.3.6", "babel-core": "6.24.1", "babel-eslint": "7.2.2", "babel-loader": "6.4.1", "babel-plugin-add-module-exports": "0.2.1", "babel-preset-es2015": "6.24.1", "browser-sync": "^2.19.0", "browser-sync-webpack-plugin": "^1.2.0", "browserstack-runner": "^0.5.2", "css-loader": "^0.26.0", "docsify-cli": "^4.1.9", "es6-promise": "^4.1.0", "eslint": "^4.3.0", "eslint-loader": "1.9.0", "extract-text-webpack-plugin": "2.1.0", "grunt": "^1.0.1", "grunt-banner": "^0.6.0", "grunt-contrib-connect": "^1.0.2", "grunt-contrib-qunit": "^2.0.0", "grunt-curl": "^2.2.1", "grunt-exec": "^2.0.0", "grunt-sass": "^2.0.0", "load-grunt-tasks": "^3.5.2", "node-sass": "^4.1.0", "postcss-loader": "^1.0.0", "pre-commit": "^1.2.2", "prettier-standard": "^3.0.1", "sass-loader": "^4.0.1", "standard": "^10.0.2", "standard-loader": "^6.0.1", "style-loader": "^0.13.1", "web-push": "^3.2.2", "webpack": "2.4.1", "yargs": "7.0.2" } } ================================================ FILE: postcss.config.js ================================================ module.exports = { plugins: [ require('autoprefixer')({ browsers: ['last 8 versions'] }) ] } ================================================ FILE: service-worker.js.template ================================================ self.addEventListener('install', event => { self.skipWaiting() console.log('worker installed', event) }) self.addEventListener('activate', event => { console.log('worker activated', event) }) self.addEventListener('push', event => { console.log('push fired', event) const data = event.data.json() const options = { body: data.body, icon: data.icon ? data.icon : '', image: data.image ? data.image : '', data: { url: data.url } } if (data.actions) options.actions = data.actions event.waitUntil( Promise.all([ self.registration.showNotification(data.title, options) ]) ) }) self.addEventListener('notificationclick', event => { console.log('notificationclick fired', event) // INFO: You can customize this callback for your needs // currently we are closing notification on click event.notification.close() if (event.action) { console.log('action clicked', event.action) } // then if url is provided open a new window var clickResponsePromise = Promise.resolve() if (event.notification.data && event.notification.data.url) { clickResponsePromise = clients.openWindow(event.notification.data.url) } event.waitUntil( Promise.all([ clickResponsePromise ]) ) }) ================================================ FILE: src/api.js ================================================ import * as Utils from 'utils' export let PageHidden = false export let DocModalCount = 0 const DocTitleProps = { originalTitle: null, count: 0, changed: false, timer: -1 } export const docTitle = { increment: () => { DocTitleProps.count++ docTitle._update() }, decrement: () => { DocTitleProps.count-- if (DocTitleProps.count <= 0) { docTitle._clear() return } docTitle._update() }, _update: () => { let title = document.title if (!DocTitleProps.changed) { DocTitleProps.originalTitle = title document.title = `(${DocTitleProps.count}) ${title}` DocTitleProps.changed = true } else { document.title = `(${DocTitleProps.count}) ${DocTitleProps.originalTitle}` } }, _clear: () => { if (DocTitleProps.changed) { DocTitleProps.count = 0 document.title = DocTitleProps.originalTitle DocTitleProps.changed = false } } } export const DefaultMaxVisible = 5 export const Queues = { global: { maxVisible: DefaultMaxVisible, queue: [] } } export const Store = {} export let Defaults = { type: 'alert', layout: 'topRight', theme: 'mint', text: '', timeout: false, progressBar: true, closeWith: ['click'], animation: { open: 'noty_effects_open', close: 'noty_effects_close' }, id: false, force: false, killer: false, queue: 'global', container: false, buttons: [], callbacks: { beforeShow: null, onShow: null, afterShow: null, onClose: null, afterClose: null, onClick: null, onHover: null, onTemplate: null }, sounds: { sources: [], volume: 1, conditions: [] }, titleCount: { conditions: [] }, modal: false, visibilityControl: false } /** * @param {string} queueName * @return {object} */ export function getQueueCounts (queueName = 'global') { let count = 0 let max = DefaultMaxVisible if (Queues.hasOwnProperty(queueName)) { max = Queues[queueName].maxVisible Object.keys(Store).forEach(i => { if (Store[i].options.queue === queueName && !Store[i].closed) count++ }) } return { current: count, maxVisible: max } } /** * @param {Noty} ref * @return {void} */ export function addToQueue (ref) { if (!Queues.hasOwnProperty(ref.options.queue)) { Queues[ref.options.queue] = {maxVisible: DefaultMaxVisible, queue: []} } Queues[ref.options.queue].queue.push(ref) } /** * @param {Noty} ref * @return {void} */ export function removeFromQueue (ref) { if (Queues.hasOwnProperty(ref.options.queue)) { const queue = [] Object.keys(Queues[ref.options.queue].queue).forEach(i => { if (Queues[ref.options.queue].queue[i].id !== ref.id) { queue.push(Queues[ref.options.queue].queue[i]) } }) Queues[ref.options.queue].queue = queue } } /** * @param {string} queueName * @return {void} */ export function queueRender (queueName = 'global') { if (Queues.hasOwnProperty(queueName)) { const noty = Queues[queueName].queue.shift() if (noty) noty.show() } } /** * @return {void} */ export function queueRenderAll () { Object.keys(Queues).forEach(queueName => { queueRender(queueName) }) } /** * @param {Noty} ref * @return {void} */ export function ghostFix (ref) { const ghostID = Utils.generateID('ghost') let ghost = document.createElement('div') ghost.setAttribute('id', ghostID) Utils.css(ghost, { height: Utils.outerHeight(ref.barDom) + 'px' }) ref.barDom.insertAdjacentHTML('afterend', ghost.outerHTML) Utils.remove(ref.barDom) ghost = document.getElementById(ghostID) Utils.addClass(ghost, 'noty_fix_effects_height') Utils.addListener(ghost, Utils.animationEndEvents, () => { Utils.remove(ghost) }) } /** * @param {Noty} ref * @return {void} */ export function build (ref) { findOrCreateContainer(ref) const markup = `
        ${ref.options.text}
        ${buildButtons(ref)}
        ` ref.barDom = document.createElement('div') ref.barDom.setAttribute('id', ref.id) Utils.addClass( ref.barDom, `noty_bar noty_type__${ref.options.type} noty_theme__${ref.options.theme}` ) ref.barDom.innerHTML = markup fire(ref, 'onTemplate') } /** * @param {Noty} ref * @return {boolean} */ export function hasButtons (ref) { return !!(ref.options.buttons && Object.keys(ref.options.buttons).length) } /** * @param {Noty} ref * @return {string} */ function buildButtons (ref) { if (hasButtons(ref)) { let buttons = document.createElement('div') Utils.addClass(buttons, 'noty_buttons') Object.keys(ref.options.buttons).forEach(key => { buttons.appendChild(ref.options.buttons[key].dom) }) ref.options.buttons.forEach(btn => { buttons.appendChild(btn.dom) }) return buttons.outerHTML } return '' } /** * @param {Noty} ref * @return {void} */ export function handleModal (ref) { if (ref.options.modal) { if (DocModalCount === 0) { createModal(ref) } DocModalCount++ } } /** * @param {Noty} ref * @return {void} */ export function handleModalClose (ref) { if (ref.options.modal && DocModalCount > 0) { DocModalCount-- if (DocModalCount <= 0) { const modal = document.querySelector('.noty_modal') if (modal) { Utils.removeClass(modal, 'noty_modal_open') Utils.addClass(modal, 'noty_modal_close') Utils.addListener(modal, Utils.animationEndEvents, () => { Utils.remove(modal) }) } } } } /** * @return {void} */ function createModal () { const body = document.querySelector('body') const modal = document.createElement('div') Utils.addClass(modal, 'noty_modal') body.insertBefore(modal, body.firstChild) Utils.addClass(modal, 'noty_modal_open') Utils.addListener(modal, Utils.animationEndEvents, () => { Utils.removeClass(modal, 'noty_modal_open') }) } /** * @param {Noty} ref * @return {void} */ function findOrCreateContainer (ref) { if (ref.options.container) { ref.layoutDom = document.querySelector(ref.options.container) return } const layoutID = `noty_layout__${ref.options.layout}` ref.layoutDom = document.querySelector(`div#${layoutID}`) if (!ref.layoutDom) { ref.layoutDom = document.createElement('div') ref.layoutDom.setAttribute('id', layoutID) ref.layoutDom.setAttribute('role', 'alert') ref.layoutDom.setAttribute('aria-live', 'polite') Utils.addClass(ref.layoutDom, 'noty_layout') document.querySelector('body').appendChild(ref.layoutDom) } } /** * @param {Noty} ref * @return {void} */ export function queueClose (ref) { if (ref.options.timeout) { if (ref.options.progressBar && ref.progressDom) { Utils.css(ref.progressDom, { transition: `width ${ref.options.timeout}ms linear`, width: '0%' }) } clearTimeout(ref.closeTimer) ref.closeTimer = setTimeout( () => { ref.close() }, ref.options.timeout ) } } /** * @param {Noty} ref * @return {void} */ export function dequeueClose (ref) { if (ref.options.timeout && ref.closeTimer) { clearTimeout(ref.closeTimer) ref.closeTimer = -1 if (ref.options.progressBar && ref.progressDom) { Utils.css(ref.progressDom, { transition: 'width 0ms linear', width: '100%' }) } } } /** * @param {Noty} ref * @param {string} eventName * @return {void} */ export function fire (ref, eventName) { if (ref.listeners.hasOwnProperty(eventName)) { ref.listeners[eventName].forEach(cb => { if (typeof cb === 'function') { cb.apply(ref) } }) } } /** * @param {Noty} ref * @return {void} */ export function openFlow (ref) { fire(ref, 'afterShow') queueClose(ref) Utils.addListener(ref.barDom, 'mouseenter', () => { dequeueClose(ref) }) Utils.addListener(ref.barDom, 'mouseleave', () => { queueClose(ref) }) } /** * @param {Noty} ref * @return {void} */ export function closeFlow (ref) { delete Store[ref.id] ref.closing = false fire(ref, 'afterClose') Utils.remove(ref.barDom) if ( ref.layoutDom.querySelectorAll('.noty_bar').length === 0 && !ref.options.container ) { Utils.remove(ref.layoutDom) } if ( Utils.inArray('docVisible', ref.options.titleCount.conditions) || Utils.inArray('docHidden', ref.options.titleCount.conditions) ) { docTitle.decrement() } queueRender(ref.options.queue) } ================================================ FILE: src/button.js ================================================ import * as Utils from 'utils' export class NotyButton { constructor (html, classes, cb, attributes = {}) { this.dom = document.createElement('button') this.dom.innerHTML = html this.id = (attributes.id = attributes.id || Utils.generateID('button')) this.cb = cb Object.keys(attributes).forEach(propertyName => { this.dom.setAttribute(propertyName, attributes[propertyName]) }) Utils.addClass(this.dom, classes || 'noty_btn') return this } } ================================================ FILE: src/index.js ================================================ /* global VERSION */ import 'noty.scss' import Promise from 'es6-promise' import * as Utils from 'utils' import * as API from 'api' import { NotyButton } from 'button' import { Push } from 'push' export default class Noty { /** * @param {object} options * @return {Noty} */ constructor (options = {}) { this.options = Utils.deepExtend({}, API.Defaults, options) if (API.Store[this.options.id]) { return API.Store[this.options.id] } this.id = this.options.id || Utils.generateID('bar') this.closeTimer = -1 this.barDom = null this.layoutDom = null this.progressDom = null this.showing = false this.shown = false this.closed = false this.closing = false this.killable = this.options.timeout || this.options.closeWith.length > 0 this.hasSound = this.options.sounds.sources.length > 0 this.soundPlayed = false this.listeners = { beforeShow: [], onShow: [], afterShow: [], onClose: [], afterClose: [], onClick: [], onHover: [], onTemplate: [] } this.promises = { show: null, close: null } this.on('beforeShow', this.options.callbacks.beforeShow) this.on('onShow', this.options.callbacks.onShow) this.on('afterShow', this.options.callbacks.afterShow) this.on('onClose', this.options.callbacks.onClose) this.on('afterClose', this.options.callbacks.afterClose) this.on('onClick', this.options.callbacks.onClick) this.on('onHover', this.options.callbacks.onHover) this.on('onTemplate', this.options.callbacks.onTemplate) return this } /** * @param {string} eventName * @param {function} cb * @return {Noty} */ on (eventName, cb = () => {}) { if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) { this.listeners[eventName].push(cb) } return this } /** * @return {Noty} */ show () { if (this.showing || this.shown) { return this // preventing multiple show } if (this.options.killer === true) { Noty.closeAll() } else if (typeof this.options.killer === 'string') { Noty.closeAll(this.options.killer) } let queueCounts = API.getQueueCounts(this.options.queue) if ( queueCounts.current >= queueCounts.maxVisible || (API.PageHidden && this.options.visibilityControl) ) { API.addToQueue(this) if ( API.PageHidden && this.hasSound && Utils.inArray('docHidden', this.options.sounds.conditions) ) { Utils.createAudioElements(this) } if ( API.PageHidden && Utils.inArray('docHidden', this.options.titleCount.conditions) ) { API.docTitle.increment() } return this } API.Store[this.id] = this API.fire(this, 'beforeShow') this.showing = true if (this.closing) { this.showing = false return this } API.build(this) API.handleModal(this) if (this.options.force) { this.layoutDom.insertBefore(this.barDom, this.layoutDom.firstChild) } else { this.layoutDom.appendChild(this.barDom) } if ( this.hasSound && !this.soundPlayed && Utils.inArray('docVisible', this.options.sounds.conditions) ) { Utils.createAudioElements(this) } if (Utils.inArray('docVisible', this.options.titleCount.conditions)) { API.docTitle.increment() } this.shown = true this.closed = false // bind button events if any if (API.hasButtons(this)) { Object.keys(this.options.buttons).forEach(key => { const btn = this.barDom.querySelector( `#${this.options.buttons[key].id}` ) Utils.addListener(btn, 'click', e => { Utils.stopPropagation(e) this.options.buttons[key].cb(this) }) }) } this.progressDom = this.barDom.querySelector('.noty_progressbar') if (Utils.inArray('click', this.options.closeWith)) { Utils.addClass(this.barDom, 'noty_close_with_click') Utils.addListener( this.barDom, 'click', e => { Utils.stopPropagation(e) API.fire(this, 'onClick') this.close() }, false ) } Utils.addListener( this.barDom, 'mouseenter', () => { API.fire(this, 'onHover') }, false ) if (this.options.timeout) Utils.addClass(this.barDom, 'noty_has_timeout') if (this.options.progressBar) { Utils.addClass(this.barDom, 'noty_has_progressbar') } if (Utils.inArray('button', this.options.closeWith)) { Utils.addClass(this.barDom, 'noty_close_with_button') const closeButton = document.createElement('div') Utils.addClass(closeButton, 'noty_close_button') closeButton.innerHTML = '×' this.barDom.appendChild(closeButton) Utils.addListener( closeButton, 'click', e => { Utils.stopPropagation(e) this.close() }, false ) } API.fire(this, 'onShow') if (this.options.animation.open === null) { this.promises.show = new Promise(resolve => { resolve() }) } else if (typeof this.options.animation.open === 'function') { this.promises.show = new Promise(this.options.animation.open.bind(this)) } else { Utils.addClass(this.barDom, this.options.animation.open) this.promises.show = new Promise(resolve => { Utils.addListener(this.barDom, Utils.animationEndEvents, () => { Utils.removeClass(this.barDom, this.options.animation.open) resolve() }) }) } this.promises.show.then(() => { const _t = this setTimeout( () => { API.openFlow(_t) }, 100 ) }) return this } /** * @return {Noty} */ stop () { API.dequeueClose(this) return this } /** * @return {Noty} */ resume () { API.queueClose(this) return this } /** * @param {int|boolean} ms * @return {Noty} */ setTimeout (ms) { this.stop() this.options.timeout = ms if (this.barDom) { if (this.options.timeout) { Utils.addClass(this.barDom, 'noty_has_timeout') } else { Utils.removeClass(this.barDom, 'noty_has_timeout') } const _t = this setTimeout( function () { // ugly fix for progressbar display bug _t.resume() }, 100 ) } return this } /** * @param {string} html * @param {boolean} optionsOverride * @return {Noty} */ setText (html, optionsOverride = false) { if (this.barDom) { this.barDom.querySelector('.noty_body').innerHTML = html } if (optionsOverride) this.options.text = html return this } /** * @param {string} type * @param {boolean} optionsOverride * @return {Noty} */ setType (type, optionsOverride = false) { if (this.barDom) { let classList = Utils.classList(this.barDom).split(' ') classList.forEach(c => { if (c.substring(0, 11) === 'noty_type__') { Utils.removeClass(this.barDom, c) } }) Utils.addClass(this.barDom, `noty_type__${type}`) } if (optionsOverride) this.options.type = type return this } /** * @param {string} theme * @param {boolean} optionsOverride * @return {Noty} */ setTheme (theme, optionsOverride = false) { if (this.barDom) { let classList = Utils.classList(this.barDom).split(' ') classList.forEach(c => { if (c.substring(0, 12) === 'noty_theme__') { Utils.removeClass(this.barDom, c) } }) Utils.addClass(this.barDom, `noty_theme__${theme}`) } if (optionsOverride) this.options.theme = theme return this } /** * @return {Noty} */ close () { if (this.closed) return this if (!this.shown) { // it's in the queue API.removeFromQueue(this) return this } API.fire(this, 'onClose') this.closing = true if (this.options.animation.close === null || this.options.animation.close === false) { this.promises.close = new Promise(resolve => { resolve() }) } else if (typeof this.options.animation.close === 'function') { this.promises.close = new Promise( this.options.animation.close.bind(this) ) } else { Utils.addClass(this.barDom, this.options.animation.close) this.promises.close = new Promise(resolve => { Utils.addListener(this.barDom, Utils.animationEndEvents, () => { if (this.options.force) { Utils.remove(this.barDom) } else { API.ghostFix(this) } resolve() }) }) } this.promises.close.then(() => { API.closeFlow(this) API.handleModalClose(this) }) this.closed = true return this } // API functions /** * @param {boolean|string} queueName * @return {Noty} */ static closeAll (queueName = false) { Object.keys(API.Store).forEach(id => { if (queueName) { if ( API.Store[id].options.queue === queueName && API.Store[id].killable ) { API.Store[id].close() } } else if (API.Store[id].killable) { API.Store[id].close() } }) return this } /** * @param {string} queueName * @return {Noty} */ static clearQueue (queueName = 'global') { if (API.Queues.hasOwnProperty(queueName)) { API.Queues[queueName].queue = [] } return this } /** * @return {API.Queues} */ static get Queues () { return API.Queues } /** * @return {API.PageHidden} */ static get PageHidden () { return API.PageHidden } /** * @param {Object} obj * @return {Noty} */ static overrideDefaults (obj) { API.Defaults = Utils.deepExtend({}, API.Defaults, obj) return this } /** * @param {int} amount * @param {string} queueName * @return {Noty} */ static setMaxVisible (amount = API.DefaultMaxVisible, queueName = 'global') { if (!API.Queues.hasOwnProperty(queueName)) { API.Queues[queueName] = {maxVisible: amount, queue: []} } API.Queues[queueName].maxVisible = amount return this } /** * @param {string} innerHtml * @param {String} classes * @param {Function} cb * @param {Object} attributes * @return {NotyButton} */ static button (innerHtml, classes = null, cb, attributes = {}) { return new NotyButton(innerHtml, classes, cb, attributes) } /** * @return {string} */ static version () { return VERSION } /** * @param {String} workerPath * @return {Push} */ static Push (workerPath) { return new Push(workerPath) } } // Document visibility change controller if (typeof window !== 'undefined') { Utils.visibilityChangeFlow() } ================================================ FILE: src/noty.scss ================================================ $noty-primary-color: #333 !default; $noty-default-width: 325px !default; $noty-corner-space: 20px !default; .noty_layout_mixin { position: fixed; margin: 0; padding: 0; z-index: 9999999; transform: translateZ(0) scale(1.0, 1.0); backface-visibility: hidden; -webkit-font-smoothing: subpixel-antialiased; filter: blur(0); -webkit-filter: blur(0); max-width: 90%; } #noty_layout__top { @extend .noty_layout_mixin; top: 0; left: 5%; width: 90%; } #noty_layout__topLeft { @extend .noty_layout_mixin; top: $noty-corner-space; left: $noty-corner-space; width: $noty-default-width; } #noty_layout__topCenter { @extend .noty_layout_mixin; top: 5%; left: 50%; width: $noty-default-width; transform: translate(calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0); } #noty_layout__topRight { @extend .noty_layout_mixin; top: $noty-corner-space; right: $noty-corner-space; width: $noty-default-width; } #noty_layout__bottom { @extend .noty_layout_mixin; bottom: 0; left: 5%; width: 90%; } #noty_layout__bottomLeft { @extend .noty_layout_mixin; bottom: $noty-corner-space; left: $noty-corner-space; width: $noty-default-width; } #noty_layout__bottomCenter { @extend .noty_layout_mixin; bottom: 5%; left: 50%; width: $noty-default-width; transform: translate(calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0); } #noty_layout__bottomRight { @extend .noty_layout_mixin; bottom: $noty-corner-space; right: $noty-corner-space; width: $noty-default-width; } #noty_layout__center { @extend .noty_layout_mixin; top: 50%; left: 50%; width: $noty-default-width; transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0); } #noty_layout__centerLeft { @extend .noty_layout_mixin; top: 50%; left: $noty-corner-space; width: $noty-default-width; transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0); } #noty_layout__centerRight { @extend .noty_layout_mixin; top: 50%; right: $noty-corner-space; width: $noty-default-width; transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); } .noty_progressbar { display: none; } .noty_has_timeout.noty_has_progressbar .noty_progressbar { display: block; position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background-color: #646464; opacity: 0.2; filter: alpha(opacity=10) } .noty_bar { -webkit-backface-visibility: hidden; -webkit-transform: translate(0, 0) translateZ(0) scale(1.0, 1.0); transform: translate(0, 0) scale(1.0, 1.0); -webkit-font-smoothing: subpixel-antialiased; overflow: hidden; } .noty_effects_open { opacity: 0; transform: translate(50%); animation: noty_anim_in .5s cubic-bezier(0.68, -0.55, 0.265, 1.55); animation-fill-mode: forwards; } .noty_effects_close { animation: noty_anim_out .5s cubic-bezier(0.68, -0.55, 0.265, 1.55); animation-fill-mode: forwards; } .noty_fix_effects_height { animation: noty_anim_height 75ms ease-out; } .noty_close_with_click { cursor: pointer; } .noty_close_button { position: absolute; top: 2px; right: 2px; font-weight: bold; width: 20px; height: 20px; text-align: center; line-height: 20px; background-color: rgba(0, 0, 0, .05); border-radius: 2px; cursor: pointer; transition: all .2s ease-out; } .noty_close_button:hover { background-color: rgba(0, 0, 0, .1); } .noty_modal { position: fixed; width: 100%; height: 100%; background-color: #000; z-index: 10000; opacity: .3; left: 0; top: 0; } .noty_modal.noty_modal_open { opacity: 0; animation: noty_modal_in .3s ease-out; } .noty_modal.noty_modal_close { animation: noty_modal_out .3s ease-out; animation-fill-mode: forwards; } @keyframes noty_modal_in { 100% { opacity: .3; } } @keyframes noty_modal_out { 100% { opacity: 0; } } @keyframes noty_anim_in { 100% { transform: translate(0); opacity: 1; } } @keyframes noty_anim_out { 100% { transform: translate(50%); opacity: 0; } } @keyframes noty_anim_height { 100% { height: 0; } } ================================================ FILE: src/push.js ================================================ export class Push { constructor (workerPath = '/service-worker.js') { this.subData = {} this.workerPath = workerPath this.listeners = { onPermissionGranted: [], onPermissionDenied: [], onSubscriptionSuccess: [], onSubscriptionCancel: [], onWorkerError: [], onWorkerSuccess: [], onWorkerNotSupported: [] } return this } /** * @param {string} eventName * @param {function} cb * @return {Push} */ on (eventName, cb = () => {}) { if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) { this.listeners[eventName].push(cb) } return this } fire (eventName, params = []) { if (this.listeners.hasOwnProperty(eventName)) { this.listeners[eventName].forEach(cb => { if (typeof cb === 'function') { cb.apply(this, params) } }) } } create () { console.log('NOT IMPLEMENTED YET') } /** * @return {boolean} */ isSupported () { let result = false try { result = window.Notification || window.webkitNotifications || navigator.mozNotification || (window.external && window.external.msIsSiteMode() !== undefined) } catch (e) {} return result } /** * @return {string} */ getPermissionStatus () { let perm = 'default' if (window.Notification && window.Notification.permissionLevel) { perm = window.Notification.permissionLevel } else if ( window.webkitNotifications && window.webkitNotifications.checkPermission ) { switch (window.webkitNotifications.checkPermission()) { case 1: perm = 'default' break case 0: perm = 'granted' break default: perm = 'denied' } } else if (window.Notification && window.Notification.permission) { perm = window.Notification.permission } else if (navigator.mozNotification) { perm = 'granted' } else if ( window.external && window.external.msIsSiteMode() !== undefined ) { perm = window.external.msIsSiteMode() ? 'granted' : 'default' } return perm.toString().toLowerCase() } /** * @return {string} */ getEndpoint (subscription) { let endpoint = subscription.endpoint const subscriptionId = subscription.subscriptionId // fix for Chrome < 45 if (subscriptionId && endpoint.indexOf(subscriptionId) === -1) { endpoint += '/' + subscriptionId } return endpoint } /** * @return {boolean} */ isSWRegistered () { try { return navigator.serviceWorker.controller.state === 'activated' } catch (e) { return false } } /** * @return {void} */ unregisterWorker () { const self = this if ('serviceWorker' in navigator) { navigator.serviceWorker.getRegistrations().then(function (registrations) { for (let registration of registrations) { registration.unregister() self.fire('onSubscriptionCancel') } }) } } /** * @return {void} */ requestSubscription (userVisibleOnly = true) { const self = this const current = this.getPermissionStatus() const cb = result => { if (result === 'granted') { this.fire('onPermissionGranted') if ('serviceWorker' in navigator) { navigator.serviceWorker.register(this.workerPath).then(function () { navigator.serviceWorker.ready.then( function (serviceWorkerRegistration) { self.fire('onWorkerSuccess') serviceWorkerRegistration.pushManager .subscribe({ userVisibleOnly: userVisibleOnly }) .then(function (subscription) { const key = subscription.getKey('p256dh') const token = subscription.getKey('auth') self.subData = { endpoint: self.getEndpoint(subscription), p256dh: key ? window.btoa( String.fromCharCode.apply(null, new Uint8Array(key)) ) : null, auth: token ? window.btoa( String.fromCharCode.apply( null, new Uint8Array(token) ) ) : null } self.fire('onSubscriptionSuccess', [self.subData]) }) .catch(function (err) { self.fire('onWorkerError', [err]) }) } ) }) } else { self.fire('onWorkerNotSupported') } } else if (result === 'denied') { this.fire('onPermissionDenied') this.unregisterWorker() } } if (current === 'default') { if (window.Notification && window.Notification.requestPermission) { window.Notification.requestPermission(cb) } else if ( window.webkitNotifications && window.webkitNotifications.checkPermission ) { window.webkitNotifications.requestPermission(cb) } } else { cb(current) } } } ================================================ FILE: src/themes/bootstrap-v3.scss ================================================ .noty_theme__bootstrap-v3.noty_bar { margin: 4px 0; overflow: hidden; position: relative; border: 1px solid transparent; border-radius: 4px; .noty_body { padding: 15px; } .noty_buttons { padding: 10px; } .noty_close_button { font-size: 21px; font-weight: 700; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .2; background: transparent; } .noty_close_button:hover { background: transparent; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .5; } } .noty_theme__bootstrap-v3.noty_type__alert, .noty_theme__bootstrap-v3.noty_type__notification { background-color: #fff; color: inherit; } .noty_theme__bootstrap-v3.noty_type__warning { background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc; } .noty_theme__bootstrap-v3.noty_type__error { background-color: #f2dede; color: #a94442; border-color: #ebccd1; } .noty_theme__bootstrap-v3.noty_type__info, .noty_theme__bootstrap-v3.noty_type__information { background-color: #d9edf7; color: #31708f; border-color: #bce8f1; } .noty_theme__bootstrap-v3.noty_type__success { background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; } ================================================ FILE: src/themes/bootstrap-v4.scss ================================================ .noty_theme__bootstrap-v4.noty_bar { margin: 4px 0; overflow: hidden; position: relative; border: 1px solid transparent; border-radius: .25rem; .noty_body { padding: .75rem 1.25rem; } .noty_buttons { padding: 10px; } .noty_close_button { font-size: 1.5rem; font-weight: 700; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .5; background: transparent; } .noty_close_button:hover { background: transparent; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .75; } } .noty_theme__bootstrap-v4.noty_type__alert, .noty_theme__bootstrap-v4.noty_type__notification { background-color: #fff; color: inherit; } .noty_theme__bootstrap-v4.noty_type__warning { background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc; } .noty_theme__bootstrap-v4.noty_type__error { background-color: #f2dede; color: #a94442; border-color: #ebccd1; } .noty_theme__bootstrap-v4.noty_type__info, .noty_theme__bootstrap-v4.noty_type__information { background-color: #d9edf7; color: #31708f; border-color: #bce8f1; } .noty_theme__bootstrap-v4.noty_type__success { background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; } ================================================ FILE: src/themes/light.scss ================================================ .noty_theme__light.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; .noty_body { padding: 10px; } .noty_buttons { border-top: 1px solid #e7e7e7; padding: 5px 10px; } } .noty_theme__light.noty_type__alert, .noty_theme__light.noty_type__notification { background-color: #fff; border: 1px solid #dedede; color: #444; } .noty_theme__light.noty_type__warning { background-color: #FFEAA8; border: 1px solid #FFC237; color: #826200; .noty_buttons { border-color: #dfaa30; } } .noty_theme__light.noty_type__error { background-color: #ED7000; border: 1px solid #e25353; color: #FFF; .noty_buttons { border-color: darkred; } } .noty_theme__light.noty_type__info, .noty_theme__light.noty_type__information { background-color: #78C5E7; border: 1px solid #3badd6; color: #FFF; .noty_buttons { border-color: #0B90C4; } } .noty_theme__light.noty_type__success { background-color: #57C880; border: 1px solid #7cdd77; color: darkgreen; .noty_buttons { border-color: #50C24E; } } ================================================ FILE: src/themes/metroui.scss ================================================ .noty_theme__metroui.noty_bar { margin: 4px 0; overflow: hidden; position: relative; box-shadow: rgba(0, 0, 0, 0.298039) 0 0 5px 0; .noty_progressbar { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background-color: #000; opacity: 0.2; filter: alpha(opacity=20) } .noty_body { padding: 1.25em; font-size: 14px; } .noty_buttons { padding: 0 10px .5em 10px; } } .noty_theme__metroui.noty_type__alert, .noty_theme__metroui.noty_type__notification { background-color: #fff; color: #1d1d1d; } .noty_theme__metroui.noty_type__warning { background-color: #FA6800; color: #fff; } .noty_theme__metroui.noty_type__error { background-color: #CE352C; color: #FFF; } .noty_theme__metroui.noty_type__info, .noty_theme__metroui.noty_type__information { background-color: #1BA1E2; color: #FFF; } .noty_theme__metroui.noty_type__success { background-color: #60A917; color: #fff; } ================================================ FILE: src/themes/mint.scss ================================================ .noty_theme__mint.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; .noty_body { padding: 10px; font-size: 14px; } .noty_buttons { padding: 10px; } } .noty_theme__mint.noty_type__alert, .noty_theme__mint.noty_type__notification { background-color: #fff; border-bottom: 1px solid #D1D1D1; color: #2F2F2F; } .noty_theme__mint.noty_type__warning { background-color: #FFAE42; border-bottom: 1px solid #E89F3C; color: #fff; } .noty_theme__mint.noty_type__error { background-color: #DE636F; border-bottom: 1px solid #CA5A65; color: #fff; } .noty_theme__mint.noty_type__info, .noty_theme__mint.noty_type__information { background-color: #7F7EFF; border-bottom: 1px solid #7473E8; color: #fff; } .noty_theme__mint.noty_type__success { background-color: #AFC765; border-bottom: 1px solid #A0B55C; color: #fff; } ================================================ FILE: src/themes/nest.scss ================================================ .noty_theme__nest.noty_bar { margin: 0 0 15px 0; overflow: hidden; border-radius: 2px; position: relative; box-shadow: rgba(0, 0, 0, 0.098039) 5px 4px 10px 0; .noty_body { padding: 10px; font-size: 14px; text-shadow: 1px 1px 1px rgba(0, 0, 0, .1); } .noty_buttons { padding: 10px; } } .noty_layout .noty_theme__nest.noty_bar { z-index: 5; } .noty_layout .noty_theme__nest.noty_bar:nth-child(2) { position: absolute; top: 0; margin-top: 4px; margin-right: -4px; margin-left: 4px; z-index: 4; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(3) { position: absolute; top: 0; margin-top: 8px; margin-right: -8px; margin-left: 8px; z-index: 3; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(4) { position: absolute; top: 0; margin-top: 12px; margin-right: -12px; margin-left: 12px; z-index: 2; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(5) { position: absolute; top: 0; margin-top: 16px; margin-right: -16px; margin-left: 16px; z-index: 1; width: 100%; } .noty_layout .noty_theme__nest.noty_bar:nth-child(n+6) { position: absolute; top: 0; margin-top: 20px; margin-right: -20px; margin-left: 20px; z-index: -1; width: 100%; } // left corner stacks #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(2), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(2) { margin-top: 4px; margin-left: -4px; margin-right: 4px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(3), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(3) { margin-top: 8px; margin-left: -8px; margin-right: 8px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(4), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(4) { margin-top: 12px; margin-left: -12px; margin-right: 12px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(5), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(5) { margin-top: 16px; margin-left: -16px; margin-right: 16px; } #noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(n+6), #noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(n+6) { margin-top: 20px; margin-left: -20px; margin-right: 20px; } .noty_theme__nest.noty_type__alert, .noty_theme__nest.noty_type__notification { background-color: #073B4C; color: #fff; .noty_progressbar { background-color: #fff; } } .noty_theme__nest.noty_type__warning { background-color: #FFD166; color: #fff; } .noty_theme__nest.noty_type__error { background-color: #EF476F; color: #fff; .noty_progressbar { opacity: .4; } } .noty_theme__nest.noty_type__info, .noty_theme__nest.noty_type__information { background-color: #118AB2; color: #fff; .noty_progressbar { opacity: .6; } } .noty_theme__nest.noty_type__success { background-color: #06D6A0; color: #fff; } ================================================ FILE: src/themes/relax.scss ================================================ .noty_theme__relax.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; .noty_body { padding: 10px; } .noty_buttons { border-top: 1px solid #e7e7e7; padding: 5px 10px; } } .noty_theme__relax.noty_type__alert, .noty_theme__relax.noty_type__notification { background-color: #fff; border: 1px solid #dedede; color: #444; } .noty_theme__relax.noty_type__warning { background-color: #FFEAA8; border: 1px solid #FFC237; color: #826200; .noty_buttons { border-color: #dfaa30; } } .noty_theme__relax.noty_type__error { background-color: #FF8181; border: 1px solid #e25353; color: #FFF; .noty_buttons { border-color: darkred; } } .noty_theme__relax.noty_type__info, .noty_theme__relax.noty_type__information { background-color: #78C5E7; border: 1px solid #3badd6; color: #FFF; .noty_buttons { border-color: #0B90C4; } } .noty_theme__relax.noty_type__success { background-color: #BCF5BC; border: 1px solid #7cdd77; color: darkgreen; .noty_buttons { border-color: #50C24E; } } ================================================ FILE: src/themes/semanticui.scss ================================================ .noty_theme__semanticui.noty_bar { margin: 4px 0; overflow: hidden; position: relative; border: 1px solid transparent; font-size: 1em; border-radius: .28571429rem; box-shadow: 0 0 0 1px rgba(34,36,38,.22) inset, 0 0 0 0 transparent; .noty_body { padding: 1em 1.5em; line-height: 1.4285em; } .noty_buttons { padding: 10px; } } .noty_theme__semanticui.noty_type__alert, .noty_theme__semanticui.noty_type__notification { background-color: #f8f8f9; color: rgba(0,0,0,.87); } .noty_theme__semanticui.noty_type__warning { background-color: #fffaf3; color: #573a08; box-shadow: 0 0 0 1px #c9ba9b inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_type__error { background-color: #fff6f6; color: #9f3a38; box-shadow: 0 0 0 1px #e0b4b4 inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_type__info, .noty_theme__semanticui.noty_type__information { background-color: #f8ffff; color: #276f86; box-shadow: 0 0 0 1px #a9d5de inset, 0 0 0 0 transparent; } .noty_theme__semanticui.noty_type__success { background-color: #fcfff5; color: #2c662d; box-shadow: 0 0 0 1px #a3c293 inset, 0 0 0 0 transparent; } ================================================ FILE: src/themes/sunset.scss ================================================ .noty_theme__sunset.noty_bar { margin: 4px 0; overflow: hidden; border-radius: 2px; position: relative; .noty_body { padding: 10px; font-size: 14px; text-shadow: 1px 1px 1px rgba(0, 0, 0, .1); } .noty_buttons { padding: 10px; } } .noty_theme__sunset.noty_type__alert, .noty_theme__sunset.noty_type__notification { background-color: #073B4C; color: #fff; .noty_progressbar { background-color: #fff; } } .noty_theme__sunset.noty_type__warning { background-color: #FFD166; color: #fff; } .noty_theme__sunset.noty_type__error { background-color: #EF476F; color: #fff; .noty_progressbar { opacity: .4; } } .noty_theme__sunset.noty_type__info, .noty_theme__sunset.noty_type__information { background-color: #118AB2; color: #fff; .noty_progressbar { opacity: .6; } } .noty_theme__sunset.noty_type__success { background-color: #06D6A0; color: #fff; } ================================================ FILE: src/utils.js ================================================ import * as API from 'api' export const animationEndEvents = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend' export function inArray (needle, haystack, argStrict) { let key let strict = !!argStrict if (strict) { for (key in haystack) { if (haystack.hasOwnProperty(key) && haystack[key] === needle) { return true } } } else { for (key in haystack) { if (haystack.hasOwnProperty(key) && haystack[key] === needle) { return true } } } return false } export function stopPropagation (evt) { evt = evt || window.event if (typeof evt.stopPropagation !== 'undefined') { evt.stopPropagation() } else { evt.cancelBubble = true } } export const deepExtend = function (out) { out = out || {} for (let i = 1; i < arguments.length; i++) { let obj = arguments[i] if (!obj) continue for (let key in obj) { if (obj.hasOwnProperty(key)) { if (Array.isArray(obj[key])) { out[key] = obj[key] } else if (typeof obj[key] === 'object' && obj[key] !== null) { out[key] = deepExtend(out[key], obj[key]) } else { out[key] = obj[key] } } } } return out } export function generateID (prefix = '') { let id = `noty_${prefix}_` id += 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { let r = Math.random() * 16 | 0 let v = c === 'x' ? r : r & 0x3 | 0x8 return v.toString(16) }) return id } export function outerHeight (el) { let height = el.offsetHeight let style = window.getComputedStyle(el) height += parseInt(style.marginTop) + parseInt(style.marginBottom) return height } export let css = (function () { let cssPrefixes = ['Webkit', 'O', 'Moz', 'ms'] let cssProps = {} function camelCase (string) { return string .replace(/^-ms-/, 'ms-') .replace(/-([\da-z])/gi, function (match, letter) { return letter.toUpperCase() }) } function getVendorProp (name) { let style = document.body.style if (name in style) return name let i = cssPrefixes.length let capName = name.charAt(0).toUpperCase() + name.slice(1) let vendorName while (i--) { vendorName = cssPrefixes[i] + capName if (vendorName in style) return vendorName } return name } function getStyleProp (name) { name = camelCase(name) return cssProps[name] || (cssProps[name] = getVendorProp(name)) } function applyCss (element, prop, value) { prop = getStyleProp(prop) element.style[prop] = value } return function (element, properties) { let args = arguments let prop let value if (args.length === 2) { for (prop in properties) { if (properties.hasOwnProperty(prop)) { value = properties[prop] if (value !== undefined && properties.hasOwnProperty(prop)) { applyCss(element, prop, value) } } } } else { applyCss(element, args[1], args[2]) } } })() export function addListener (el, events, cb, useCapture = false) { events = events.split(' ') for (let i = 0; i < events.length; i++) { if (document.addEventListener) { el.addEventListener(events[i], cb, useCapture) } else if (document.attachEvent) { el.attachEvent('on' + events[i], cb) } } } export function hasClass (element, name) { let list = typeof element === 'string' ? element : classList(element) return list.indexOf(' ' + name + ' ') >= 0 } export function addClass (element, name) { let oldList = classList(element) let newList = oldList + name if (hasClass(oldList, name)) return // Trim the opening space. element.className = newList.substring(1) } export function removeClass (element, name) { let oldList = classList(element) let newList if (!hasClass(element, name)) return // Replace the class name. newList = oldList.replace(' ' + name + ' ', ' ') // Trim the opening and closing spaces. element.className = newList.substring(1, newList.length - 1) } export function remove (element) { if (element.parentNode) { element.parentNode.removeChild(element) } } export function classList (element) { return (' ' + ((element && element.className) || '') + ' ').replace( /\s+/gi, ' ' ) } export function visibilityChangeFlow () { let hidden let visibilityChange if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support hidden = 'hidden' visibilityChange = 'visibilitychange' } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden' visibilityChange = 'msvisibilitychange' } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden' visibilityChange = 'webkitvisibilitychange' } function onVisibilityChange () { API.PageHidden = document[hidden] handleVisibilityChange() } function onBlur () { API.PageHidden = true handleVisibilityChange() } function onFocus () { API.PageHidden = false handleVisibilityChange() } function handleVisibilityChange () { if (API.PageHidden) stopAll() else resumeAll() } function stopAll () { setTimeout( function () { Object.keys(API.Store).forEach(id => { if (API.Store.hasOwnProperty(id)) { if (API.Store[id].options.visibilityControl) { API.Store[id].stop() } } }) }, 100 ) } function resumeAll () { setTimeout( function () { Object.keys(API.Store).forEach(id => { if (API.Store.hasOwnProperty(id)) { if (API.Store[id].options.visibilityControl) { API.Store[id].resume() } } }) API.queueRenderAll() }, 100 ) } if (visibilityChange) { addListener(document, visibilityChange, onVisibilityChange) } addListener(window, 'blur', onBlur) addListener(window, 'focus', onFocus) } export function createAudioElements (ref) { if (ref.hasSound) { const audioElement = document.createElement('audio') ref.options.sounds.sources.forEach(s => { const source = document.createElement('source') source.src = s source.type = `audio/${getExtension(s)}` audioElement.appendChild(source) }) if (ref.barDom) { ref.barDom.appendChild(audioElement) } else { document.querySelector('body').appendChild(audioElement) } audioElement.volume = ref.options.sounds.volume if (!ref.soundPlayed) { audioElement.play() ref.soundPlayed = true } audioElement.onended = function () { remove(audioElement) } } } function getExtension (fileName) { return fileName.match(/\.([^.]+)$/)[1] } ================================================ FILE: test/index.html ================================================ Noty Test Suite
        ================================================ FILE: test/unit/init.test.js ================================================ $(function () { 'use strict' function fakeEvent (el, e) { if (document.createEvent) { var event = document.createEvent('HTMLEvents') event.initEvent(e, true, false) el.dispatchEvent(event) } else { el.fireEvent(e) } } Noty.overrideDefaults({ text: 'Noty Test Suite' }) QUnit.module('Initializing') QUnit.test('should be defined', function (assert) { assert.expect(1) assert.ok(Noty, 'Noty is defined') }) QUnit.test('should return a Noty object', function (assert) { assert.expect(11) var n = new Noty() assert.ok(n instanceof Noty, 'returns Noty object') assert.ok(n.options, 'has accessible properties') assert.strictEqual(n.id.length, 45, 'has auto generated ID') assert.strictEqual(n.closed, false, '.closed should be false') assert.strictEqual(n.shown, false, '.shown should be false') assert.strictEqual(n.closeTimer, -1, '.closeTimer should be -1') assert.strictEqual(n.barDom, null, '.barDom should be null') assert.strictEqual(n.layoutDom, null, '.layoutDom should be null') assert.strictEqual(n.progressDom, null, '.progressDom should be null') assert.strictEqual(n.hasSound, false, '.hasSound should be false') assert.strictEqual(n.soundPlayed, false, '.soundPlayed should be false') }) QUnit.module('Callbacks') QUnit.test('beforeShow - should not be in the dom when beforeShow fired', function (assert) { assert.expect(2) var done = assert.async() new Noty() .on('beforeShow', function () { assert.ok(true, 'beforeShow fired') assert.strictEqual($('#' + this.id).length, 0, 'noty not in the document') done() }).show().close() }) QUnit.test('onShow - should insert into dom when show method is called', function (assert) { assert.expect(2) var done = assert.async() new Noty() .on('onShow', function () { assert.strictEqual($('#' + this.id).length, 1, 'noty inserted into dom') assert.ok(true, 'onShow fired') done() }).show().close() }) QUnit.test('afterShow - should fire event', function (assert) { assert.expect(2) var done = assert.async() new Noty() .on('afterShow', function () { assert.ok(true, 'afterShow fired') assert.strictEqual($('#' + this.id).length, 1, 'noty in the dom') done() }).show() }) QUnit.test('preventing - should not fire afterShow when show was prevented', function (assert) { assert.expect(1) var done = assert.async() new Noty() .on('onShow', function () { this.close() assert.ok(true, 'onShow event fired') done() }) .on('afterShow', function () { assert.ok(false, 'afterShow event fired') }).show().close() }) QUnit.test('onClose - should fire event', function (assert) { assert.expect(2) var done = assert.async() new Noty() .on('onClose', function () { assert.ok(true, 'onClose fired') assert.strictEqual($('#' + this.id).length, 1, 'noty in the dom') done() }).show().close() }) QUnit.test('onTemplate - ', function (assert) { assert.expect(2) var done = assert.async() new Noty().on('onTemplate', function () { assert.ok(true, 'onTemplate fired') this.barDom.innerHTML = 'changed' assert.strictEqual(this.barDom.innerHTML, 'changed', 'noty.barDom can be modified') done() }).show().close() }) QUnit.test('onHover', function (assert) { assert.expect(1) var done = assert.async() new Noty() .on('onHover', function () { assert.ok(true, 'onHover fired') done() }) .on('afterShow', function () { fakeEvent($('#' + this.id)[0], 'mouseenter') }).show() }) // @todo - [needim] - modal cases // @todo - [needim] - Killer cases QUnit.module('CloseWith') QUnit.test('click', function (assert) { assert.expect(1) var done = assert.async() new Noty({closeWith: ['click']}) .on('afterShow', function () { fakeEvent($('#' + this.id)[0], 'click') }) .on('afterClose', function () { assert.ok(true, 'closed by clicking') done() }).show() }) QUnit.test('button', function (assert) { assert.expect(1) var done = assert.async() new Noty({closeWith: ['button']}) .on('afterShow', function () { fakeEvent($('#' + this.id).find('.noty_close_button')[0], 'click') }) .on('afterClose', function () { assert.ok(true, 'closed by x button') done() }).show() }) // @todo - [needim] - backdrop && modal QUnit.module('API') QUnit.test('stop() & resume()', function (assert) { assert.expect(3) var done = assert.async() new Noty({timeout: 2000}) .on('afterShow', function () { assert.ok(this.options.timeout === 2000, 'has correct timeout') var t = this setTimeout(function () { t.stop() assert.ok(t.closeTimer === -1, 'timer stopped') t.resume() setTimeout(function () { assert.ok(t.closeTimer, 'timer started') done() }, 250) }, 250) }).show() }) QUnit.test('setTimeout()', function (assert) { assert.expect(2) var done = assert.async() new Noty({timeout: 2000}) .on('afterShow', function () { this.setTimeout(3000) assert.ok(this.options.timeout === 3000, 'timeout override after show() called') done() }).show() assert.ok(new Noty().setTimeout(3000).options.timeout === 3000, 'timeout overrided before show()') }) QUnit.test('setText()', function (assert) { assert.expect(3) var done = assert.async() new Noty({text: 'Rick'}) .on('afterShow', function () { this.setText('Morty', true) assert.ok(this.options.text === 'Morty', 'text override after show() called') assert.ok($('#' + this.id).find('.noty_body').text() === 'Morty', 'text changed correctly') done() }).show() assert.ok(new Noty().setText('Morty', true).options.text === 'Morty', 'text override before show()') }) QUnit.test('setType()', function (assert) { assert.expect(4) var done = assert.async() new Noty() .on('afterShow', function () { this.setType('warning', true) var $d = $('#' + this.id) assert.equal(this.options.type, 'warning', 'type override after show() called') assert.ok($d.hasClass('noty_type__warning'), 'new type changed correctly') assert.notOk($d.hasClass('noty_type__alert'), 'old type removed correctly') done() }).show() assert.ok(new Noty().setType('warning', true).options.type === 'warning', 'type override before show()') }) QUnit.test('setTheme()', function (assert) { assert.expect(4) var done = assert.async() new Noty({theme: 'mint'}) .on('afterShow', function () { this.setTheme('relax', true) var $d = $('#' + this.id) assert.equal(this.options.theme, 'relax', 'theme override after show() called') assert.ok($d.hasClass('noty_theme__relax'), 'new theme changed correctly') assert.notOk($d.hasClass('noty_theme__mint'), 'old theme removed correctly') done() }).show() assert.ok(new Noty({theme: 'mint'}).setTheme('relax', true).options.theme === 'relax', 'theme override before show()') }) QUnit.test('close()', function (assert) { assert.expect(2) var done = assert.async() new Noty() .on('onClose', function () { assert.ok(true, 'onClose fired') }) .on('afterClose', function () { assert.ok(true, 'afterClose fired') done() }).show().close() }) QUnit.module('API Static') QUnit.test('overrideDefaults()', function (assert) { assert.expect(1) var obj = { timeout: 3000, theme: 'relax', layout: 'topCenter', progressBar: false, closeWith: ['button'], animation: { open: null, close: null }, force: true, sounds: { sources: ['audio_file.wav'], volume: .3, conditions: ['docHidden'] }, titleCount: { conditions: ['docHidden'] } } Noty.overrideDefaults(obj) var n = new Noty() assert.deepEqual(obj, { timeout: n.options.timeout, theme: n.options.theme, layout: n.options.layout, progressBar: n.options.progressBar, closeWith: n.options.closeWith, animation: n.options.animation, force: n.options.force, sounds: n.options.sounds, titleCount: n.options.titleCount }, 'override ok') }) QUnit.test('setMaxVisible()', function (assert) { assert.expect(2) var showed = 0 Noty.setMaxVisible(1) new Noty().on('beforeShow', function () { showed++ }).show() new Noty().on('beforeShow', function () { showed++ }).show() assert.equal(showed, 1, 'global queue maxVisible 1 ok') var customShowed = 0 Noty.setMaxVisible(1, 'customQueue') new Noty({queue: 'customQueue'}) .on('beforeShow', function () { customShowed++ }).show() new Noty({queue: 'customQueue'}) .on('beforeShow', function () { customShowed++ }).show() assert.equal(customShowed, 1, 'custom queue maxVisible 1 ok') }) QUnit.test('closeAll()', function (assert) { assert.expect(4) Noty.setMaxVisible(8) Noty.setMaxVisible(8, 'customQueue') var closed = 0 new Noty().on('onClose', function () { closed++ }).show() new Noty().on('onClose', function () { closed++ }).show() Noty.closeAll() var closedCustom = 0 new Noty({queue: 'customQueueClose'}).on('onClose', function () { closedCustom++ }).show() new Noty({queue: 'customQueueClose'}).on('onClose', function () { closedCustom++ }).show() var notClose = true var noClose = new Noty({queue: 'otherCustomQueueClose'}).on('onClose', function () { notClose = false }).show() var notCloseTheNonKillable = true var nonKillable = new Noty({queue: 'customQueueClose', closeWith: [], timeout: false}).on('onClose', function () { notCloseTheNonKillable = false }).show() Noty.closeAll('customQueueClose') assert.equal(closed, 2, 'closeAll closes all notifications') assert.equal(closedCustom, 2, 'closeAll closes custom queue notifications') assert.equal(notClose, true, 'closeAll should not close the other queue notifications') assert.equal(notCloseTheNonKillable, true, 'closeAll should not close the non-Killable notifications') nonKillable.close() // this needs individual close noClose.close() // this needs individual close }) QUnit.test('button()', function (assert) { assert.expect(13) var btn = Noty.button('buttonText') assert.ok(btn.dom, 'button has dom object') assert.ok(btn.dom.innerHTML === 'buttonText', 'button innerHTML is ok') assert.equal(btn.id.length, 48, 'button has a generated ID') assert.equal(btn.cb, undefined, 'button has a no cb function') assert.ok($(btn.dom).hasClass('noty_btn'), 'button has a default class (noty_btn)') assert.equal(btn.dom.attributes.length, 2, 'button has 2 default attributes (id, class)') var btnCB = function () {} var btn2 = Noty.button('buttonText', 'btn1 btn2', btnCB, {id: 'myButtonID', 'data-rick': 30}) assert.ok(btn2.dom, 'button2 has dom object') assert.ok(btn2.dom.innerHTML === 'buttonText', 'button2 innerHTML is ok') assert.equal(btn2.id, 'myButtonID', 'button2 has given ID') assert.equal(btn2.cb, btnCB, 'button2 has given cb function') assert.ok($(btn2.dom).hasClass('btn1 btn2'), 'button2 has given classes') assert.notOk($(btn2.dom).hasClass('noty_btn'), 'button2 has no default class') assert.equal(btn2.dom.attributes.length, 3, 'button2 has given attributes') }) QUnit.test('version()', function (assert) { assert.expect(1) assert.equal(typeof Noty.version(), 'string', 'returns version string') }) // @todo - [needim] - sounds // @todo - [needim] - titleCount }) ================================================ FILE: test/unit/phantom.js ================================================ /* * grunt-contrib-qunit * http://gruntjs.com/ * * Copyright (c) 2014 "Cowboy" Ben Alman, contributors * Licensed under the MIT license. */ (function () { 'use strict' // Don't re-order tests. QUnit.config.reorder = false // Run tests serially, not in parallel. QUnit.config.autorun = false // Send messages to the parent PhantomJS process via alert! Good times!! function sendMessage () { var args = [].slice.call(arguments) alert(JSON.stringify(args)) } // These methods connect QUnit to PhantomJS. QUnit.log(function (obj) { // What is this I don’t even if (obj.message === '[object Object], undefined:undefined') { return } // Parse some stuff before sending it. var actual var expected if (!obj.result) { // Dumping large objects can be very slow, and the dump isn't used for // passing tests, so only dump if the test failed. actual = QUnit.dump.parse(obj.actual) expected = QUnit.dump.parse(obj.expected) } // Send it. sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source) }) QUnit.testStart(function (obj) { sendMessage('qunit.testStart', obj.name) }) QUnit.testDone(function (obj) { sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total, obj.duration) }) QUnit.moduleStart(function (obj) { sendMessage('qunit.moduleStart', obj.name) }) QUnit.moduleDone(function (obj) { if (obj.failed === 0) { console.log('\r\u221A All tests passed in "' + obj.name + '" module') } else { console.log('\u00D7 ' + obj.failed + ' tests failed in "' + obj.name + '" module') } sendMessage('qunit.moduleDone', obj.name, obj.failed, obj.passed, obj.total) }) QUnit.begin(function () { sendMessage('qunit.begin') console.log('\n\nStarting test suite') console.log('================================================\n') }) QUnit.done(function (obj) { sendMessage('qunit.done', obj.failed, obj.passed, obj.total, obj.runtime) }) }()) ================================================ FILE: test/vendor/qunit-theme-ninja.css ================================================ /** * QUnit Ninja Theme by Jamie Hoover v1.1.0 * Modified by Nedim Arabacı * https://github.com/Krinkle/qunit-theme-ninja * * Copyright 2013 jQuery Foundation and other contributors * Released under the MIT license. * https://jquery.org/license/ */ body { background: #313131; color: #ccc; font: 12px/16px "Lucida Grande", sans-serif; margin: 0 auto; max-width: 1024px; min-width: 800px; padding: 24px; position: relative; } #qunit-header { font-size: 24px; line-height: 1; margin: 0 520px 0 0; } #qunit-header > a { color: #ccc; text-decoration: none; } #qunit-header > a:hover { color: #ccc; text-decoration: underline; } #qunit-testresult { font: 12px/12px "Menlo", monospace; margin: 20px 0; color: antiquewhite; } #qunit-testresult .module-name { font-weight: bold; } #qunit-testresult br { content: ''; } #qunit-testresult span:before { content: ' '; } #qunit-testresult span.failed { color: #c33; } #qunit-testresult span.passed { color: #6c6; } div#qunit-testrunner-toolbar { overflow: auto; margin-bottom: 30px; } div#qunit-modulefilter-dropdown { display: block; background: #545454; padding: 10px 0; margin-right: 5px; margin-left: 50px; } #qunit-modulefilter-actions label.clickable { display: block; position: relative; } li.pass { color: #8BC34A; } li.fail { color: #c33; } form#qunit-modulefilter { display: inline-block; margin-left: 60px; float: right; } #qunit-testrunner-toolbar label:first-child input { margin-left: 0; } form.qunit-filter { display: inline-block; float: right; } #qunit-testrunner-toolbar input { font: inherit; margin: 0 6px 0 24px; } #qunit-testrunner-toolbar label { display: inline-block; } #qunit-testrunner-toolbar select { position: absolute; right: 24px; top: 22px; } #qunit-modulefilter-container label { display: none; } #qunit-banner { height: 1px; margin: 24px 0; } #qunit-banner.qunit-fail { background-color: #c33; } #qunit-banner.qunit-pass { background-color: #6c6; } #qunit-tests { color: #666; font: 12px/24px "Menlo", monospace; list-style-position: inside; padding: 0; } #qunit-tests b.counts { font-weight: normal; } #qunit-tests b.counts b { font-weight: normal; } #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { display: none; } #qunit-tests li a { color: #00BCD4; padding: 0 6px; text-decoration: none; } p.qunit-source { color: #8c8c8c; font-size: 10px; } #qunit-tests li a:hover { color: #ccc; } #qunit-tests li a:hover, #qunit-tests li strong:hover { text-decoration: underline; } #qunit-tests li b.counts { color: #666; } #qunit-tests li .runtime { font-size: smaller; margin-left: 15px; } #qunit-tests li.fail span.test-message { color: #c33; } #qunit-tests li.fail strong { color: #c33; } #qunit-tests li.fail strong b.counts b.failed { color: #c33; } #qunit-tests li.pass b.passed { color: #6c6; } #qunit-tests li.pass span.test-message { color: #6c6; } #qunit-tests li.pass strong { color: #ccc; } #qunit-tests li strong { font-weight: normal; } #qunit-tests li strong:hover { cursor: pointer; } #qunit-tests ol { list-style-position: inside; padding: 0 0 0 22px; } #qunit-tests ol li table { border-collapse: collapse; } #qunit-tests ol li table td pre { background-color: #222; -webkit-border-radius: 4px; border-radius: 4px; color: #ccc; font: inherit; margin: 3px 0 3px 12px; padding: 12px 24px; white-space: pre-wrap; word-wrap: break-word; } #qunit-tests ol li table th { font-weight: normal; } #qunit-tests ol li table th, #qunit-tests ol li table td { padding: 0; vertical-align: middle; } #qunit-tests ol li table tr.test-actual { color: #c33; } #qunit-tests ol li table tr.test-diff del { color: #6c6; } #qunit-tests ol li table tr.test-diff del, #qunit-tests ol li table tr.test-diff ins { text-decoration: none; } #qunit-tests ol li table tr.test-diff ins { color: #c33; } #qunit-tests ol li table tr.test-expected { color: #FFEB3B; } #qunit-tests ol li table tr.test-source pre { padding: 12px 24px 12px 0; } #qunit-userAgent { color: #666; font: 9px/9px "Menlo", monospace; } #qunit-fixture { position: absolute; height: 768px; left: -1024px; top: -768px; width: 1024px; } .qunit-collapsed { display: none; } em.qunit-todo-label { color: #795548; margin-right: 10px; } em.qunit-todo-label:after, em.qunit-skipped-label:after { content: " -"; } em.qunit-skipped-label { margin-right: 10px; } ================================================ FILE: test/vendor/qunit.js ================================================ /*! * QUnit 2.2.0 * https://qunitjs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2017-03-11T16:19Z */ (function (global$1) { 'use strict'; global$1 = 'default' in global$1 ? global$1['default'] : global$1; var window = global$1.window; var console = global$1.console; var setTimeout = global$1.setTimeout; var clearTimeout = global$1.clearTimeout; var document = window && window.document; var navigator = window && window.navigator; var sessionStorage = function () { var x = "qunit-test-string"; try { sessionStorage.setItem(x, x); sessionStorage.removeItem(x); return sessionStorage; } catch (e) { return undefined; } }(); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; var toString = Object.prototype.toString; var hasOwn = Object.prototype.hasOwnProperty; var now = Date.now || function () { return new Date().getTime(); }; var defined = { document: window && window.document !== undefined, setTimeout: setTimeout !== undefined }; // Returns a new Array with the elements that are in a but not in b function diff(a, b) { var i, j, result = a.slice(); for (i = 0; i < result.length; i++) { for (j = 0; j < b.length; j++) { if (result[i] === b[j]) { result.splice(i, 1); i--; break; } } } return result; } /** * Determines whether an element exists in a given array or not. * * @method inArray * @param {Any} elem * @param {Array} array * @return {Boolean} */ function inArray(elem, array) { return array.indexOf(elem) !== -1; } /** * Makes a clone of an object using only Array or Object as base, * and copies over the own enumerable properties. * * @param {Object} obj * @return {Object} New object with only the own properties (recursively). */ function objectValues(obj) { var key, val, vals = is("array", obj) ? [] : {}; for (key in obj) { if (hasOwn.call(obj, key)) { val = obj[key]; vals[key] = val === Object(val) ? objectValues(val) : val; } } return vals; } function extend(a, b, undefOnly) { for (var prop in b) { if (hasOwn.call(b, prop)) { if (b[prop] === undefined) { delete a[prop]; } else if (!(undefOnly && typeof a[prop] !== "undefined")) { a[prop] = b[prop]; } } } return a; } function objectType(obj) { if (typeof obj === "undefined") { return "undefined"; } // Consider: typeof null === object if (obj === null) { return "null"; } var match = toString.call(obj).match(/^\[object\s(.*)\]$/), type = match && match[1]; switch (type) { case "Number": if (isNaN(obj)) { return "nan"; } return "number"; case "String": case "Boolean": case "Array": case "Set": case "Map": case "Date": case "RegExp": case "Function": case "Symbol": return type.toLowerCase(); } if ((typeof obj === "undefined" ? "undefined" : _typeof(obj)) === "object") { return "object"; } } // Safe object type checking function is(type, obj) { return objectType(obj) === type; } // Test for equality any JavaScript type. // Authors: Philippe Rathé , David Chan var equiv = (function () { // Value pairs queued for comparison. Used for breadth-first processing order, recursion // detection and avoiding repeated comparison (see below for details). // Elements are { a: val, b: val }. var pairs = []; var getProto = Object.getPrototypeOf || function (obj) { return obj.__proto__; }; function useStrictEquality(a, b) { // This only gets called if a and b are not strict equal, and is used to compare on // the primitive values inside object wrappers. For example: // `var i = 1;` // `var j = new Number(1);` // Neither a nor b can be null, as a !== b and they have the same type. if ((typeof a === "undefined" ? "undefined" : _typeof(a)) === "object") { a = a.valueOf(); } if ((typeof b === "undefined" ? "undefined" : _typeof(b)) === "object") { b = b.valueOf(); } return a === b; } function compareConstructors(a, b) { var protoA = getProto(a); var protoB = getProto(b); // Comparing constructors is more strict than using `instanceof` if (a.constructor === b.constructor) { return true; } // Ref #851 // If the obj prototype descends from a null constructor, treat it // as a null prototype. if (protoA && protoA.constructor === null) { protoA = null; } if (protoB && protoB.constructor === null) { protoB = null; } // Allow objects with no prototype to be equivalent to // objects with Object as their constructor. if (protoA === null && protoB === Object.prototype || protoB === null && protoA === Object.prototype) { return true; } return false; } function getRegExpFlags(regexp) { return "flags" in regexp ? regexp.flags : regexp.toString().match(/[gimuy]*$/)[0]; } function isContainer(val) { return ["object", "array", "map", "set"].indexOf(objectType(val)) !== -1; } function breadthFirstCompareChild(a, b) { // If a is a container not reference-equal to b, postpone the comparison to the // end of the pairs queue -- unless (a, b) has been seen before, in which case skip // over the pair. if (a === b) { return true; } if (!isContainer(a)) { return typeEquiv(a, b); } if (pairs.every(function (pair) { return pair.a !== a || pair.b !== b; })) { // Not yet started comparing this pair pairs.push({ a: a, b: b }); } return true; } var callbacks = { "string": useStrictEquality, "boolean": useStrictEquality, "number": useStrictEquality, "null": useStrictEquality, "undefined": useStrictEquality, "symbol": useStrictEquality, "date": useStrictEquality, "nan": function nan() { return true; }, "regexp": function regexp(a, b) { return a.source === b.source && // Include flags in the comparison getRegExpFlags(a) === getRegExpFlags(b); }, // abort (identical references / instance methods were skipped earlier) "function": function _function() { return false; }, "array": function array(a, b) { var i, len; len = a.length; if (len !== b.length) { // Safe and faster return false; } for (i = 0; i < len; i++) { // Compare non-containers; queue non-reference-equal containers if (!breadthFirstCompareChild(a[i], b[i])) { return false; } } return true; }, // Define sets a and b to be equivalent if for each element aVal in a, there // is some element bVal in b such that aVal and bVal are equivalent. Element // repetitions are not counted, so these are equivalent: // a = new Set( [ {}, [], [] ] ); // b = new Set( [ {}, {}, [] ] ); "set": function set$$1(a, b) { var innerEq, outerEq = true; if (a.size !== b.size) { // This optimization has certain quirks because of the lack of // repetition counting. For instance, adding the same // (reference-identical) element to two equivalent sets can // make them non-equivalent. return false; } a.forEach(function (aVal) { // Short-circuit if the result is already known. (Using for...of // with a break clause would be cleaner here, but it would cause // a syntax error on older Javascript implementations even if // Set is unused) if (!outerEq) { return; } innerEq = false; b.forEach(function (bVal) { var parentPairs; // Likewise, short-circuit if the result is already known if (innerEq) { return; } // Swap out the global pairs list, as the nested call to // innerEquiv will clobber its contents parentPairs = pairs; if (innerEquiv(bVal, aVal)) { innerEq = true; } // Replace the global pairs list pairs = parentPairs; }); if (!innerEq) { outerEq = false; } }); return outerEq; }, // Define maps a and b to be equivalent if for each key-value pair (aKey, aVal) // in a, there is some key-value pair (bKey, bVal) in b such that // [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not // counted, so these are equivalent: // a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] ); // b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] ); "map": function map(a, b) { var innerEq, outerEq = true; if (a.size !== b.size) { // This optimization has certain quirks because of the lack of // repetition counting. For instance, adding the same // (reference-identical) key-value pair to two equivalent maps // can make them non-equivalent. return false; } a.forEach(function (aVal, aKey) { // Short-circuit if the result is already known. (Using for...of // with a break clause would be cleaner here, but it would cause // a syntax error on older Javascript implementations even if // Map is unused) if (!outerEq) { return; } innerEq = false; b.forEach(function (bVal, bKey) { var parentPairs; // Likewise, short-circuit if the result is already known if (innerEq) { return; } // Swap out the global pairs list, as the nested call to // innerEquiv will clobber its contents parentPairs = pairs; if (innerEquiv([bVal, bKey], [aVal, aKey])) { innerEq = true; } // Replace the global pairs list pairs = parentPairs; }); if (!innerEq) { outerEq = false; } }); return outerEq; }, "object": function object(a, b) { var i, aProperties = [], bProperties = []; if (compareConstructors(a, b) === false) { return false; } // Be strict: don't ensure hasOwnProperty and go deep for (i in a) { // Collect a's properties aProperties.push(i); // Skip OOP methods that look the same if (a.constructor !== Object && typeof a.constructor !== "undefined" && typeof a[i] === "function" && typeof b[i] === "function" && a[i].toString() === b[i].toString()) { continue; } // Compare non-containers; queue non-reference-equal containers if (!breadthFirstCompareChild(a[i], b[i])) { return false; } } for (i in b) { // Collect b's properties bProperties.push(i); } // Ensures identical properties name return typeEquiv(aProperties.sort(), bProperties.sort()); } }; function typeEquiv(a, b) { var type = objectType(a); // Callbacks for containers will append to the pairs queue to achieve breadth-first // search order. The pairs queue is also used to avoid reprocessing any pair of // containers that are reference-equal to a previously visited pair (a special case // this being recursion detection). // // Because of this approach, once typeEquiv returns a false value, it should not be // called again without clearing the pair queue else it may wrongly report a visited // pair as being equivalent. return objectType(b) === type && callbacks[type](a, b); } function innerEquiv(a, b) { var i, pair; // We're done when there's nothing more to compare if (arguments.length < 2) { return true; } // Clear the global pair queue and add the top-level values being compared pairs = [{ a: a, b: b }]; for (i = 0; i < pairs.length; i++) { pair = pairs[i]; // Perform type-specific comparison on any pairs that are not strictly // equal. For container types, that comparison will postpone comparison // of any sub-container pair to the end of the pair queue. This gives // breadth-first search order. It also avoids the reprocessing of // reference-equal siblings, cousins etc, which can have a significant speed // impact when comparing a container of small objects each of which has a // reference to the same (singleton) large object. if (pair.a !== pair.b && !typeEquiv(pair.a, pair.b)) { return false; } } // ...across all consecutive argument pairs return arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1)); } return innerEquiv; })(); /** * Config object: Maintain internal state * Later exposed as QUnit.config * `config` initialized at top of scope */ var config = { // The queue of tests to run queue: [], // Block until document ready blocking: true, // By default, run previously failed tests first // very useful in combination with "Hide passed tests" checked reorder: true, // By default, modify document.title when suite is done altertitle: true, // HTML Reporter: collapse every test except the first failing test // If false, all failing tests will be expanded collapse: true, // By default, scroll to top of the page when suite is done scrolltop: true, // Depth up-to which object will be dumped maxDepth: 5, // When enabled, all tests must call expect() requireExpects: false, // Placeholder for user-configurable form-exposed URL parameters urlConfig: [], // Set of all modules. modules: [], // Stack of nested modules moduleStack: [], // The first unnamed module currentModule: { name: "", tests: [], childModules: [], testsRun: 0 }, callbacks: {}, // The storage module to use for reordering tests storage: sessionStorage }; // take a predefined QUnit.config and extend the defaults var globalConfig = window && window.QUnit && window.QUnit.config; // only extend the global config if there is no QUnit overload if (window && window.QUnit && !window.QUnit.version) { extend(config, globalConfig); } // Push a loose unnamed module to the modules collection config.modules.push(config.currentModule); // Based on jsDump by Ariel Flesler // http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html var dump = (function () { function quote(str) { return "\"" + str.toString().replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\""; } function literal(o) { return o + ""; } function join(pre, arr, post) { var s = dump.separator(), base = dump.indent(), inner = dump.indent(1); if (arr.join) { arr = arr.join("," + s + inner); } if (!arr) { return pre + post; } return [pre, inner + arr, base + post].join(s); } function array(arr, stack) { var i = arr.length, ret = new Array(i); if (dump.maxDepth && dump.depth > dump.maxDepth) { return "[object Array]"; } this.up(); while (i--) { ret[i] = this.parse(arr[i], undefined, stack); } this.down(); return join("[", ret, "]"); } function isArray(obj) { return ( //Native Arrays toString.call(obj) === "[object Array]" || // NodeList objects typeof obj.length === "number" && obj.item !== undefined && (obj.length ? obj.item(0) === obj[0] : obj.item(0) === null && obj[0] === undefined) ); } var reName = /^function (\w+)/, dump = { // The objType is used mostly internally, you can fix a (custom) type in advance parse: function parse(obj, objType, stack) { stack = stack || []; var res, parser, parserType, objIndex = stack.indexOf(obj); if (objIndex !== -1) { return "recursion(" + (objIndex - stack.length) + ")"; } objType = objType || this.typeOf(obj); parser = this.parsers[objType]; parserType = typeof parser === "undefined" ? "undefined" : _typeof(parser); if (parserType === "function") { stack.push(obj); res = parser.call(this, obj, stack); stack.pop(); return res; } return parserType === "string" ? parser : this.parsers.error; }, typeOf: function typeOf(obj) { var type; if (obj === null) { type = "null"; } else if (typeof obj === "undefined") { type = "undefined"; } else if (is("regexp", obj)) { type = "regexp"; } else if (is("date", obj)) { type = "date"; } else if (is("function", obj)) { type = "function"; } else if (obj.setInterval !== undefined && obj.document !== undefined && obj.nodeType === undefined) { type = "window"; } else if (obj.nodeType === 9) { type = "document"; } else if (obj.nodeType) { type = "node"; } else if (isArray(obj)) { type = "array"; } else if (obj.constructor === Error.prototype.constructor) { type = "error"; } else { type = typeof obj === "undefined" ? "undefined" : _typeof(obj); } return type; }, separator: function separator() { if (this.multiline) { return this.HTML ? "
        " : "\n"; } else { return this.HTML ? " " : " "; } }, // Extra can be a number, shortcut for increasing-calling-decreasing indent: function indent(extra) { if (!this.multiline) { return ""; } var chr = this.indentChar; if (this.HTML) { chr = chr.replace(/\t/g, " ").replace(/ /g, " "); } return new Array(this.depth + (extra || 0)).join(chr); }, up: function up(a) { this.depth += a || 1; }, down: function down(a) { this.depth -= a || 1; }, setParser: function setParser(name, parser) { this.parsers[name] = parser; }, // The next 3 are exposed so you can use them quote: quote, literal: literal, join: join, depth: 1, maxDepth: config.maxDepth, // This is the list of parsers, to modify them, use dump.setParser parsers: { window: "[Window]", document: "[Document]", error: function error(_error) { return "Error(\"" + _error.message + "\")"; }, unknown: "[Unknown]", "null": "null", "undefined": "undefined", "function": function _function(fn) { var ret = "function", // Functions never have name in IE name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; if (name) { ret += " " + name; } ret += "("; ret = [ret, dump.parse(fn, "functionArgs"), "){"].join(""); return join(ret, dump.parse(fn, "functionCode"), "}"); }, array: array, nodelist: array, "arguments": array, object: function object(map, stack) { var keys, key, val, i, nonEnumerableProperties, ret = []; if (dump.maxDepth && dump.depth > dump.maxDepth) { return "[object Object]"; } dump.up(); keys = []; for (key in map) { keys.push(key); } // Some properties are not always enumerable on Error objects. nonEnumerableProperties = ["message", "name"]; for (i in nonEnumerableProperties) { key = nonEnumerableProperties[i]; if (key in map && !inArray(key, keys)) { keys.push(key); } } keys.sort(); for (i = 0; i < keys.length; i++) { key = keys[i]; val = map[key]; ret.push(dump.parse(key, "key") + ": " + dump.parse(val, undefined, stack)); } dump.down(); return join("{", ret, "}"); }, node: function node(_node) { var len, i, val, open = dump.HTML ? "<" : "<", close = dump.HTML ? ">" : ">", tag = _node.nodeName.toLowerCase(), ret = open + tag, attrs = _node.attributes; if (attrs) { for (i = 0, len = attrs.length; i < len; i++) { val = attrs[i].nodeValue; // IE6 includes all attributes in .attributes, even ones not explicitly // set. Those have values like undefined, null, 0, false, "" or // "inherit". if (val && val !== "inherit") { ret += " " + attrs[i].nodeName + "=" + dump.parse(val, "attribute"); } } } ret += close; // Show content of TextNode or CDATASection if (_node.nodeType === 3 || _node.nodeType === 4) { ret += _node.nodeValue; } return ret + open + "/" + tag + close; }, // Function calls it internally, it's the arguments part of the function functionArgs: function functionArgs(fn) { var args, l = fn.length; if (!l) { return ""; } args = new Array(l); while (l--) { // 97 is 'a' args[l] = String.fromCharCode(97 + l); } return " " + args.join(", ") + " "; }, // Object calls it internally, the key part of an item in a map key: quote, // Function calls it internally, it's the content of the function functionCode: "[code]", // Node calls it internally, it's a html attribute value attribute: quote, string: quote, date: quote, regexp: literal, number: literal, "boolean": literal, symbol: function symbol(sym) { return sym.toString(); } }, // If true, entities are escaped ( <, >, \t, space and \n ) HTML: false, // Indentation unit indentChar: " ", // If true, items in a collection, are separated by a \n, else just a space. multiline: true }; return dump; })(); var LISTENERS = Object.create(null); var SUPPORTED_EVENTS = ["runStart", "suiteStart", "testStart", "assertion", "testEnd", "suiteEnd", "runEnd"]; /** * Emits an event with the specified data to all currently registered listeners. * Callbacks will fire in the order in which they are registered (FIFO). This * function is not exposed publicly; it is used by QUnit internals to emit * logging events. * * @private * @method emit * @param {String} eventName * @param {Object} data * @return {Void} */ function emit(eventName, data) { if (objectType(eventName) !== "string") { throw new TypeError("eventName must be a string when emitting an event"); } // Clone the callbacks in case one of them registers a new callback var originalCallbacks = LISTENERS[eventName]; var callbacks = originalCallbacks ? [].concat(toConsumableArray(originalCallbacks)) : []; for (var i = 0; i < callbacks.length; i++) { callbacks[i](data); } } /** * Registers a callback as a listener to the specified event. * * @public * @method on * @param {String} eventName * @param {Function} callback * @return {Void} */ function on(eventName, callback) { if (objectType(eventName) !== "string") { throw new TypeError("eventName must be a string when registering a listener"); } else if (!inArray(eventName, SUPPORTED_EVENTS)) { var events = SUPPORTED_EVENTS.join(", "); throw new Error("\"" + eventName + "\" is not a valid event; must be one of: " + events + "."); } else if (objectType(callback) !== "function") { throw new TypeError("callback must be a function when registering a listener"); } if (!LISTENERS[eventName]) { LISTENERS[eventName] = []; } // Don't register the same callback more than once if (!inArray(callback, LISTENERS[eventName])) { LISTENERS[eventName].push(callback); } } // Register logging callbacks function registerLoggingCallbacks(obj) { var i, l, key, callbackNames = ["begin", "done", "log", "testStart", "testDone", "moduleStart", "moduleDone"]; function registerLoggingCallback(key) { var loggingCallback = function loggingCallback(callback) { if (objectType(callback) !== "function") { throw new Error("QUnit logging methods require a callback function as their first parameters."); } config.callbacks[key].push(callback); }; return loggingCallback; } for (i = 0, l = callbackNames.length; i < l; i++) { key = callbackNames[i]; // Initialize key collection of logging callback if (objectType(config.callbacks[key]) === "undefined") { config.callbacks[key] = []; } obj[key] = registerLoggingCallback(key); } } function runLoggingCallbacks(key, args) { var i, l, callbacks; callbacks = config.callbacks[key]; for (i = 0, l = callbacks.length; i < l; i++) { callbacks[i](args); } } // Doesn't support IE9, it will return undefined on these browsers // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack var fileName = (sourceFromStacktrace(0) || "").replace(/(:\d+)+\)?/, "").replace(/.+\//, ""); function extractStacktrace(e, offset) { offset = offset === undefined ? 4 : offset; var stack, include, i; if (e && e.stack) { stack = e.stack.split("\n"); if (/^error$/i.test(stack[0])) { stack.shift(); } if (fileName) { include = []; for (i = offset; i < stack.length; i++) { if (stack[i].indexOf(fileName) !== -1) { break; } include.push(stack[i]); } if (include.length) { return include.join("\n"); } } return stack[offset]; } } function sourceFromStacktrace(offset) { var error = new Error(); // Support: Safari <=7 only, IE <=10 - 11 only // Not all browsers generate the `stack` property for `new Error()`, see also #636 if (!error.stack) { try { throw error; } catch (err) { error = err; } } return extractStacktrace(error, offset); } var TestReport = function () { function TestReport(name, suite, options) { classCallCheck(this, TestReport); this.name = name; this.suiteName = suite.name; this.fullName = suite.fullName.concat(name); this.runtime = 0; this.assertions = []; this.skipped = !!options.skip; this.todo = !!options.todo; this._startTime = 0; this._endTime = 0; suite.pushTest(this); } createClass(TestReport, [{ key: "start", value: function start(recordTime) { if (recordTime) { this._startTime = Date.now(); } return { name: this.name, suiteName: this.suiteName, fullName: this.fullName.slice() }; } }, { key: "end", value: function end(recordTime) { if (recordTime) { this._endTime = Date.now(); } return extend(this.start(), { runtime: this.getRuntime(), status: this.getStatus(), errors: this.getFailedAssertions(), assertions: this.getAssertions() }); } }, { key: "pushAssertion", value: function pushAssertion(assertion) { this.assertions.push(assertion); } }, { key: "getRuntime", value: function getRuntime() { return this._endTime - this._startTime; } }, { key: "getStatus", value: function getStatus() { if (this.skipped) { return "skipped"; } var testPassed = this.getFailedAssertions().length > 0 ? this.todo : !this.todo; if (!testPassed) { return "failed"; } else if (this.todo) { return "todo"; } else { return "passed"; } } }, { key: "getFailedAssertions", value: function getFailedAssertions() { return this.assertions.filter(function (assertion) { return !assertion.passed; }); } }, { key: "getAssertions", value: function getAssertions() { return this.assertions.slice(); } }]); return TestReport; }(); var unitSampler; var focused = false; var priorityCount = 0; function Test(settings) { var i, l; ++Test.count; this.expected = null; extend(this, settings); this.assertions = []; this.semaphore = 0; this.usedAsync = false; this.module = config.currentModule; this.stack = sourceFromStacktrace(3); this.steps = []; this.testReport = new TestReport(settings.testName, this.module.suiteReport, { todo: settings.todo, skip: settings.skip }); // Register unique strings for (i = 0, l = this.module.tests; i < l.length; i++) { if (this.module.tests[i].name === this.testName) { this.testName += " "; } } this.testId = generateHash(this.module.name, this.testName); this.module.tests.push({ name: this.testName, testId: this.testId }); if (settings.skip) { // Skipped tests will fully ignore any sent callback this.callback = function () {}; this.async = false; this.expected = 0; } else { this.assert = new Assert(this); } } Test.count = 0; function getNotStartedModules(startModule) { var module = startModule, modules = []; while (module && module.testsRun === 0) { modules.push(module); module = module.parentModule; } return modules; } Test.prototype = { before: function before() { var i, startModule, module = this.module, notStartedModules = getNotStartedModules(module); for (i = notStartedModules.length - 1; i >= 0; i--) { startModule = notStartedModules[i]; startModule.stats = { all: 0, bad: 0, started: now() }; emit("suiteStart", startModule.suiteReport.start(true)); runLoggingCallbacks("moduleStart", { name: startModule.name, tests: startModule.tests }); } config.current = this; if (module.testEnvironment) { delete module.testEnvironment.before; delete module.testEnvironment.beforeEach; delete module.testEnvironment.afterEach; delete module.testEnvironment.after; } this.testEnvironment = extend({}, module.testEnvironment); this.started = now(); emit("testStart", this.testReport.start(true)); runLoggingCallbacks("testStart", { name: this.testName, module: module.name, testId: this.testId, previousFailure: this.previousFailure }); if (!config.pollution) { saveGlobal(); } }, run: function run() { var promise; config.current = this; this.callbackStarted = now(); if (config.notrycatch) { runTest(this); return; } try { runTest(this); } catch (e) { this.pushFailure("Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + (e.message || e), extractStacktrace(e, 0)); // Else next test will carry the responsibility saveGlobal(); // Restart the tests if they're blocking if (config.blocking) { internalRecover(this); } } function runTest(test) { promise = test.callback.call(test.testEnvironment, test.assert); test.resolvePromise(promise); } }, after: function after() { checkPollution(); }, queueHook: function queueHook(hook, hookName, hookOwner) { var promise, test = this; return function runHook() { if (hookName === "before") { if (hookOwner.testsRun !== 0) { return; } test.preserveEnvironment = true; } if (hookName === "after" && hookOwner.testsRun !== numberOfTests(hookOwner) - 1) { return; } config.current = test; if (config.notrycatch) { callHook(); return; } try { callHook(); } catch (error) { test.pushFailure(hookName + " failed on " + test.testName + ": " + (error.message || error), extractStacktrace(error, 0)); } function callHook() { promise = hook.call(test.testEnvironment, test.assert); test.resolvePromise(promise, hookName); } }; }, // Currently only used for module level hooks, can be used to add global level ones hooks: function hooks(handler) { var hooks = []; function processHooks(test, module) { if (module.parentModule) { processHooks(test, module.parentModule); } if (module.testEnvironment && objectType(module.testEnvironment[handler]) === "function") { hooks.push(test.queueHook(module.testEnvironment[handler], handler, module)); } } // Hooks are ignored on skipped tests if (!this.skip) { processHooks(this, this.module); } return hooks; }, finish: function finish() { config.current = this; if (config.requireExpects && this.expected === null) { this.pushFailure("Expected number of assertions to be defined, but expect() was " + "not called.", this.stack); } else if (this.expected !== null && this.expected !== this.assertions.length) { this.pushFailure("Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack); } else if (this.expected === null && !this.assertions.length) { this.pushFailure("Expected at least one assertion, but none were run - call " + "expect(0) to accept zero assertions.", this.stack); } var i, module = this.module, moduleName = module.name, testName = this.testName, skipped = !!this.skip, todo = !!this.todo, bad = 0, storage = config.storage; this.runtime = now() - this.started; config.stats.all += this.assertions.length; module.stats.all += this.assertions.length; for (i = 0; i < this.assertions.length; i++) { if (!this.assertions[i].result) { bad++; config.stats.bad++; module.stats.bad++; } } notifyTestsRan(module); // Store result when possible if (storage) { if (bad) { storage.setItem("qunit-test-" + moduleName + "-" + testName, bad); } else { storage.removeItem("qunit-test-" + moduleName + "-" + testName); } } emit("testEnd", this.testReport.end(true)); runLoggingCallbacks("testDone", { name: testName, module: moduleName, skipped: skipped, todo: todo, failed: bad, passed: this.assertions.length - bad, total: this.assertions.length, runtime: skipped ? 0 : this.runtime, // HTML Reporter use assertions: this.assertions, testId: this.testId, // Source of Test source: this.stack }); if (module.testsRun === numberOfTests(module)) { emit("suiteEnd", module.suiteReport.end(true)); runLoggingCallbacks("moduleDone", { name: module.name, tests: module.tests, failed: module.stats.bad, passed: module.stats.all - module.stats.bad, total: module.stats.all, runtime: now() - module.stats.started }); } config.current = undefined; }, preserveTestEnvironment: function preserveTestEnvironment() { if (this.preserveEnvironment) { this.module.testEnvironment = this.testEnvironment; this.testEnvironment = extend({}, this.module.testEnvironment); } }, queue: function queue() { var priority, previousFailCount, test = this; if (!this.valid()) { return; } function run() { // Each of these can by async synchronize([function () { test.before(); }, test.hooks("before"), function () { test.preserveTestEnvironment(); }, test.hooks("beforeEach"), function () { test.run(); }, test.hooks("afterEach").reverse(), test.hooks("after").reverse(), function () { test.after(); }, function () { test.finish(); }]); } previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName); // Prioritize previously failed tests, detected from storage priority = config.reorder && previousFailCount; this.previousFailure = !!previousFailCount; return synchronize(run, priority, config.seed); }, pushResult: function pushResult(resultInfo) { // Destructure of resultInfo = { result, actual, expected, message, negative } var source, details = { module: this.module.name, name: this.testName, result: resultInfo.result, message: resultInfo.message, actual: resultInfo.actual, expected: resultInfo.expected, testId: this.testId, negative: resultInfo.negative || false, runtime: now() - this.started, todo: !!this.todo }; if (!resultInfo.result) { source = resultInfo.source || sourceFromStacktrace(); if (source) { details.source = source; } } this.logAssertion(details); this.assertions.push({ result: !!resultInfo.result, message: resultInfo.message }); }, pushFailure: function pushFailure(message, source, actual) { if (!(this instanceof Test)) { throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2)); } this.assert.pushResult({ result: false, message: message || "error", actual: actual || null, expected: null, source: source }); }, /** * Log assertion details using both the old QUnit.log interface and * QUnit.on( "assertion" ) interface. * * @private */ logAssertion: function logAssertion(details) { runLoggingCallbacks("log", details); var assertion = { passed: details.result, actual: details.actual, expected: details.expected, message: details.message, stack: details.source, todo: details.todo }; this.testReport.pushAssertion(assertion); emit("assertion", assertion); }, resolvePromise: function resolvePromise(promise, phase) { var then, resume, message, test = this; if (promise != null) { then = promise.then; if (objectType(then) === "function") { resume = internalStop(test); then.call(promise, function () { resume(); }, function (error) { message = "Promise rejected " + (!phase ? "during" : phase.replace(/Each$/, "")) + " \"" + test.testName + "\": " + (error && error.message || error); test.pushFailure(message, extractStacktrace(error, 0)); // Else next test will carry the responsibility saveGlobal(); // Unblock resume(); }); } } }, valid: function valid() { var filter = config.filter, regexFilter = /^(!?)\/([\w\W]*)\/(i?$)/.exec(filter), module = config.module && config.module.toLowerCase(), fullName = this.module.name + ": " + this.testName; function moduleChainNameMatch(testModule) { var testModuleName = testModule.name ? testModule.name.toLowerCase() : null; if (testModuleName === module) { return true; } else if (testModule.parentModule) { return moduleChainNameMatch(testModule.parentModule); } else { return false; } } function moduleChainIdMatch(testModule) { return inArray(testModule.moduleId, config.moduleId) || testModule.parentModule && moduleChainIdMatch(testModule.parentModule); } // Internally-generated tests are always valid if (this.callback && this.callback.validTest) { return true; } if (config.moduleId && config.moduleId.length > 0 && !moduleChainIdMatch(this.module)) { return false; } if (config.testId && config.testId.length > 0 && !inArray(this.testId, config.testId)) { return false; } if (module && !moduleChainNameMatch(this.module)) { return false; } if (!filter) { return true; } return regexFilter ? this.regexFilter(!!regexFilter[1], regexFilter[2], regexFilter[3], fullName) : this.stringFilter(filter, fullName); }, regexFilter: function regexFilter(exclude, pattern, flags, fullName) { var regex = new RegExp(pattern, flags); var match = regex.test(fullName); return match !== exclude; }, stringFilter: function stringFilter(filter, fullName) { filter = filter.toLowerCase(); fullName = fullName.toLowerCase(); var include = filter.charAt(0) !== "!"; if (!include) { filter = filter.slice(1); } // If the filter matches, we need to honour include if (fullName.indexOf(filter) !== -1) { return include; } // Otherwise, do the opposite return !include; } }; function pushFailure() { if (!config.current) { throw new Error("pushFailure() assertion outside test context, in " + sourceFromStacktrace(2)); } // Gets current test obj var currentTest = config.current; return currentTest.pushFailure.apply(currentTest, arguments); } // Based on Java's String.hashCode, a simple but not // rigorously collision resistant hashing function function generateHash(module, testName) { var hex, i = 0, hash = 0, str = module + "\x1C" + testName, len = str.length; for (; i < len; i++) { hash = (hash << 5) - hash + str.charCodeAt(i); hash |= 0; } // Convert the possibly negative integer hash code into an 8 character hex string, which isn't // strictly necessary but increases user understanding that the id is a SHA-like hash hex = (0x100000000 + hash).toString(16); if (hex.length < 8) { hex = "0000000" + hex; } return hex.slice(-8); } function synchronize(callback, priority, seed) { var last = !priority, index; if (objectType(callback) === "array") { while (callback.length) { synchronize(callback.shift()); } return; } if (priority) { config.queue.splice(priorityCount++, 0, callback); } else if (seed) { if (!unitSampler) { unitSampler = unitSamplerGenerator(seed); } // Insert into a random position after all priority items index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1)); config.queue.splice(priorityCount + index, 0, callback); } else { config.queue.push(callback); } if (internalState.autorun && !config.blocking) { process(last); } } function unitSamplerGenerator(seed) { // 32-bit xorshift, requires only a nonzero seed // http://excamera.com/sphinx/article-xorshift.html var sample = parseInt(generateHash(seed), 16) || -1; return function () { sample ^= sample << 13; sample ^= sample >>> 17; sample ^= sample << 5; // ECMAScript has no unsigned number type if (sample < 0) { sample += 0x100000000; } return sample / 0x100000000; }; } function saveGlobal() { config.pollution = []; if (config.noglobals) { for (var key in global$1) { if (hasOwn.call(global$1, key)) { // In Opera sometimes DOM element ids show up here, ignore them if (/^qunit-test-output/.test(key)) { continue; } config.pollution.push(key); } } } } function checkPollution() { var newGlobals, deletedGlobals, old = config.pollution; saveGlobal(); newGlobals = diff(config.pollution, old); if (newGlobals.length > 0) { pushFailure("Introduced global variable(s): " + newGlobals.join(", ")); } deletedGlobals = diff(old, config.pollution); if (deletedGlobals.length > 0) { pushFailure("Deleted global variable(s): " + deletedGlobals.join(", ")); } } // Will be exposed as QUnit.test function test(testName, callback) { if (focused) { return; } var newTest = new Test({ testName: testName, callback: callback }); newTest.queue(); } function todo(testName, callback) { if (focused) { return; } var newTest = new Test({ testName: testName, callback: callback, todo: true }); newTest.queue(); } // Will be exposed as QUnit.skip function skip(testName) { if (focused) { return; } var test = new Test({ testName: testName, skip: true }); test.queue(); } // Will be exposed as QUnit.only function only(testName, callback) { if (focused) { return; } config.queue.length = 0; focused = true; var newTest = new Test({ testName: testName, callback: callback }); newTest.queue(); } // Put a hold on processing and return a function that will release it. function internalStop(test) { var released = false; test.semaphore += 1; config.blocking = true; // Set a recovery timeout, if so configured. if (config.testTimeout && defined.setTimeout) { clearTimeout(config.timeout); config.timeout = setTimeout(function () { pushFailure("Test timed out", sourceFromStacktrace(2)); internalRecover(test); }, config.testTimeout); } return function resume() { if (released) { return; } released = true; test.semaphore -= 1; internalStart(test); }; } // Forcefully release all processing holds. function internalRecover(test) { test.semaphore = 0; internalStart(test); } // Release a processing hold, scheduling a resumption attempt if no holds remain. function internalStart(test) { // If semaphore is non-numeric, throw error if (isNaN(test.semaphore)) { test.semaphore = 0; pushFailure("Invalid value on test.semaphore", sourceFromStacktrace(2)); return; } // Don't start until equal number of stop-calls if (test.semaphore > 0) { return; } // Throw an Error if start is called more often than stop if (test.semaphore < 0) { test.semaphore = 0; pushFailure("Tried to restart test while already started (test's semaphore was 0 already)", sourceFromStacktrace(2)); return; } // Add a slight delay to allow more assertions etc. if (defined.setTimeout) { if (config.timeout) { clearTimeout(config.timeout); } config.timeout = setTimeout(function () { if (test.semaphore > 0) { return; } if (config.timeout) { clearTimeout(config.timeout); } begin(); }, 13); } else { begin(); } } function numberOfTests(module) { var count = module.tests.length, modules = [].concat(toConsumableArray(module.childModules)); // Do a breadth-first traversal of the child modules while (modules.length) { var nextModule = modules.shift(); count += nextModule.tests.length; modules.push.apply(modules, toConsumableArray(nextModule.childModules)); } return count; } function notifyTestsRan(module) { module.testsRun++; while (module = module.parentModule) { module.testsRun++; } } /** * Returns a function that proxies to the given method name on the globals * console object. The proxy will also detect if the console doesn't exist and * will appropriately no-op. This allows support for IE9, which doesn't have a * console if the developer tools are not open. */ function consoleProxy(method) { return function () { if (console) { console[method].apply(console, arguments); } }; } var Logger = { warn: consoleProxy("warn") }; var Assert = function () { function Assert(testContext) { classCallCheck(this, Assert); this.test = testContext; } // Assert helpers // Documents a "step", which is a string value, in a test as a passing assertion createClass(Assert, [{ key: "step", value: function step(message) { var result = !!message; this.test.steps.push(message); return this.pushResult({ result: result, message: message || "You must provide a message to assert.step" }); } // Verifies the steps in a test match a given array of string values }, { key: "verifySteps", value: function verifySteps(steps, message) { this.deepEqual(this.test.steps, steps, message); } // Specify the number of expected assertions to guarantee that failed test // (no assertions are run at all) don't slip through. }, { key: "expect", value: function expect(asserts) { if (arguments.length === 1) { this.test.expected = asserts; } else { return this.test.expected; } } // Put a hold on processing and return a function that will release it a maximum of once. }, { key: "async", value: function async(count) { var test$$1 = this.test, popped = false, acceptCallCount = count; if (typeof acceptCallCount === "undefined") { acceptCallCount = 1; } test$$1.usedAsync = true; var resume = internalStop(test$$1); return function done() { if (popped) { test$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2)); return; } acceptCallCount -= 1; if (acceptCallCount > 0) { return; } popped = true; resume(); }; } // Exports test.push() to the user API // Alias of pushResult. }, { key: "push", value: function push(result, actual, expected, message, negative) { Logger.warn("assert.push is deprecated and will be removed in QUnit 3.0." + " Please use assert.pushResult instead (http://api.qunitjs.com/pushResult/)."); var currentAssert = this instanceof Assert ? this : config.current.assert; return currentAssert.pushResult({ result: result, actual: actual, expected: expected, message: message, negative: negative }); } }, { key: "pushResult", value: function pushResult(resultInfo) { // Destructure of resultInfo = { result, actual, expected, message, negative } var assert = this, currentTest = assert instanceof Assert && assert.test || config.current; // Backwards compatibility fix. // Allows the direct use of global exported assertions and QUnit.assert.* // Although, it's use is not recommended as it can leak assertions // to other tests from async tests, because we only get a reference to the current test, // not exactly the test where assertion were intended to be called. if (!currentTest) { throw new Error("assertion outside test context, in " + sourceFromStacktrace(2)); } if (currentTest.usedAsync === true && currentTest.semaphore === 0) { currentTest.pushFailure("Assertion after the final `assert.async` was resolved", sourceFromStacktrace(2)); // Allow this assertion to continue running anyway... } if (!(assert instanceof Assert)) { assert = currentTest.assert; } return assert.test.pushResult(resultInfo); } }, { key: "ok", value: function ok(result, message) { if (!message) { message = result ? "okay" : "failed, expected argument to be truthy, was: " + dump.parse(result); } this.pushResult({ result: !!result, actual: result, expected: true, message: message }); } }, { key: "notOk", value: function notOk(result, message) { if (!message) { message = !result ? "okay" : "failed, expected argument to be falsy, was: " + dump.parse(result); } this.pushResult({ result: !result, actual: result, expected: false, message: message }); } }, { key: "equal", value: function equal(actual, expected, message) { // eslint-disable-next-line eqeqeq var result = expected == actual; this.pushResult({ result: result, actual: actual, expected: expected, message: message }); } }, { key: "notEqual", value: function notEqual(actual, expected, message) { // eslint-disable-next-line eqeqeq var result = expected != actual; this.pushResult({ result: result, actual: actual, expected: expected, message: message, negative: true }); } }, { key: "propEqual", value: function propEqual(actual, expected, message) { actual = objectValues(actual); expected = objectValues(expected); this.pushResult({ result: equiv(actual, expected), actual: actual, expected: expected, message: message }); } }, { key: "notPropEqual", value: function notPropEqual(actual, expected, message) { actual = objectValues(actual); expected = objectValues(expected); this.pushResult({ result: !equiv(actual, expected), actual: actual, expected: expected, message: message, negative: true }); } }, { key: "deepEqual", value: function deepEqual(actual, expected, message) { this.pushResult({ result: equiv(actual, expected), actual: actual, expected: expected, message: message }); } }, { key: "notDeepEqual", value: function notDeepEqual(actual, expected, message) { this.pushResult({ result: !equiv(actual, expected), actual: actual, expected: expected, message: message, negative: true }); } }, { key: "strictEqual", value: function strictEqual(actual, expected, message) { this.pushResult({ result: expected === actual, actual: actual, expected: expected, message: message }); } }, { key: "notStrictEqual", value: function notStrictEqual(actual, expected, message) { this.pushResult({ result: expected !== actual, actual: actual, expected: expected, message: message, negative: true }); } }, { key: "throws", value: function throws(block, expected, message) { var actual = void 0, result = false, currentTest = this instanceof Assert && this.test || config.current; // 'expected' is optional unless doing string comparison if (objectType(expected) === "string") { if (message == null) { message = expected; expected = null; } else { throw new Error("throws/raises does not accept a string value for the expected argument.\n" + "Use a non-string object value (e.g. regExp) instead if it's necessary."); } } currentTest.ignoreGlobalErrors = true; try { block.call(currentTest.testEnvironment); } catch (e) { actual = e; } currentTest.ignoreGlobalErrors = false; if (actual) { var expectedType = objectType(expected); // We don't want to validate thrown error if (!expected) { result = true; expected = null; // Expected is a regexp } else if (expectedType === "regexp") { result = expected.test(errorString(actual)); // Expected is a constructor, maybe an Error constructor } else if (expectedType === "function" && actual instanceof expected) { result = true; // Expected is an Error object } else if (expectedType === "object") { result = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message; // Expected is a validation function which returns true if validation passed } else if (expectedType === "function" && expected.call({}, actual) === true) { expected = null; result = true; } } currentTest.assert.pushResult({ result: result, actual: actual, expected: expected, message: message }); } }]); return Assert; }(); // Provide an alternative to assert.throws(), for environments that consider throws a reserved word // Known to us are: Closure Compiler, Narwhal // eslint-disable-next-line dot-notation Assert.prototype.raises = Assert.prototype["throws"]; /** * Converts an error into a simple string for comparisons. * * @param {Error} error * @return {String} */ function errorString(error) { var resultErrorString = error.toString(); if (resultErrorString.substring(0, 7) === "[object") { var name = error.name ? error.name.toString() : "Error"; var message = error.message ? error.message.toString() : ""; if (name && message) { return name + ": " + message; } else if (name) { return name; } else if (message) { return message; } else { return "Error"; } } else { return resultErrorString; } } /* global module, exports, define */ function exportQUnit(QUnit) { if (defined.document) { // QUnit may be defined when it is preconfigured but then only QUnit and QUnit.config may be defined. if (window.QUnit && window.QUnit.version) { throw new Error("QUnit has already been defined."); } window.QUnit = QUnit; } // For nodejs if (typeof module !== "undefined" && module && module.exports) { module.exports = QUnit; // For consistency with CommonJS environments' exports module.exports.QUnit = QUnit; } // For CommonJS with exports, but without module.exports, like Rhino if (typeof exports !== "undefined" && exports) { exports.QUnit = QUnit; } if (typeof define === "function" && define.amd) { define(function () { return QUnit; }); QUnit.config.autostart = false; } } var SuiteReport = function () { function SuiteReport(name, parentSuite) { classCallCheck(this, SuiteReport); this.name = name; this.fullName = parentSuite ? parentSuite.fullName.concat(name) : []; this.tests = []; this.childSuites = []; if (parentSuite) { parentSuite.pushChildSuite(this); } } createClass(SuiteReport, [{ key: "start", value: function start(recordTime) { if (recordTime) { this._startTime = Date.now(); } return { name: this.name, fullName: this.fullName.slice(), tests: this.tests.map(function (test) { return test.start(); }), childSuites: this.childSuites.map(function (suite) { return suite.start(); }), testCounts: { total: this.getTestCounts().total } }; } }, { key: "end", value: function end(recordTime) { if (recordTime) { this._endTime = Date.now(); } return { name: this.name, fullName: this.fullName.slice(), tests: this.tests.map(function (test) { return test.end(); }), childSuites: this.childSuites.map(function (suite) { return suite.end(); }), testCounts: this.getTestCounts(), runtime: this.getRuntime(), status: this.getStatus() }; } }, { key: "pushChildSuite", value: function pushChildSuite(suite) { this.childSuites.push(suite); } }, { key: "pushTest", value: function pushTest(test) { this.tests.push(test); } }, { key: "getRuntime", value: function getRuntime() { return this._endTime - this._startTime; } }, { key: "getTestCounts", value: function getTestCounts() { var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 }; counts = this.tests.reduce(function (counts, test) { counts[test.getStatus()]++; counts.total++; return counts; }, counts); return this.childSuites.reduce(function (counts, suite) { return suite.getTestCounts(counts); }, counts); } }, { key: "getStatus", value: function getStatus() { var _getTestCounts = this.getTestCounts(), total = _getTestCounts.total, failed = _getTestCounts.failed, skipped = _getTestCounts.skipped, todo = _getTestCounts.todo; if (failed) { return "failed"; } else { if (skipped === total) { return "skipped"; } else if (todo === total) { return "todo"; } else { return "passed"; } } } }]); return SuiteReport; }(); // Handle an unhandled exception. By convention, returns true if further // error handling should be suppressed and false otherwise. // In this case, we will only suppress further error handling if the // "ignoreGlobalErrors" configuration option is enabled. function onError(error) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if (config.current) { if (config.current.ignoreGlobalErrors) { return true; } pushFailure.apply(undefined, [error.message, error.fileName + ":" + error.lineNumber].concat(args)); } else { test("global failure", extend(function () { pushFailure.apply(undefined, [error.message, error.fileName + ":" + error.lineNumber].concat(args)); }, { validTest: true })); } return false; } var QUnit = {}; var globalSuite = new SuiteReport(); // The initial "currentModule" represents the global (or top-level) module that // is not explicitly defined by the user, therefore we add the "globalSuite" to // it since each module has a suiteReport associated with it. config.currentModule.suiteReport = globalSuite; var globalStartCalled = false; var runStarted = false; var internalState = { autorun: false }; // Figure out if we're running the tests from a server or not QUnit.isLocal = !(defined.document && window.location.protocol !== "file:"); // Expose the current QUnit version QUnit.version = "2.2.0"; extend(QUnit, { on: on, // Call on start of module test to prepend name to all tests module: function module(name, testEnvironment, executeNow) { var module, moduleFns; var currentModule = config.currentModule; if (arguments.length === 2) { if (objectType(testEnvironment) === "function") { executeNow = testEnvironment; testEnvironment = undefined; } } module = createModule(); moduleFns = { before: setHook(module, "before"), beforeEach: setHook(module, "beforeEach"), afterEach: setHook(module, "afterEach"), after: setHook(module, "after") }; if (objectType(executeNow) === "function") { config.moduleStack.push(module); setCurrentModule(module); executeNow.call(module.testEnvironment, moduleFns); config.moduleStack.pop(); module = module.parentModule || currentModule; } setCurrentModule(module); function createModule() { var parentModule = config.moduleStack.length ? config.moduleStack.slice(-1)[0] : null; var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name; var parentSuite = parentModule ? parentModule.suiteReport : globalSuite; var module = { name: moduleName, parentModule: parentModule, tests: [], moduleId: generateHash(moduleName), testsRun: 0, childModules: [], suiteReport: new SuiteReport(name, parentSuite) }; var env = {}; if (parentModule) { parentModule.childModules.push(module); extend(env, parentModule.testEnvironment); delete env.beforeEach; delete env.afterEach; } extend(env, testEnvironment); module.testEnvironment = env; config.modules.push(module); return module; } function setCurrentModule(module) { config.currentModule = module; } }, test: test, todo: todo, skip: skip, only: only, start: function start(count) { var globalStartAlreadyCalled = globalStartCalled; if (!config.current) { globalStartCalled = true; if (runStarted) { throw new Error("Called start() while test already started running"); } else if (globalStartAlreadyCalled || count > 1) { throw new Error("Called start() outside of a test context too many times"); } else if (config.autostart) { throw new Error("Called start() outside of a test context when " + "QUnit.config.autostart was true"); } else if (!config.pageLoaded) { // The page isn't completely loaded yet, so we set autostart and then // load if we're in Node or wait for the browser's load event. config.autostart = true; // Starts from Node even if .load was not previously called. We still return // early otherwise we'll wind up "beginning" twice. if (!defined.document) { QUnit.load(); } return; } } else { throw new Error("QUnit.start cannot be called inside a test context."); } scheduleBegin(); }, config: config, is: is, objectType: objectType, extend: extend, load: function load() { config.pageLoaded = true; // Initialize the configuration options extend(config, { stats: { all: 0, bad: 0 }, started: 0, updateRate: 1000, autostart: true, filter: "" }, true); if (!runStarted) { config.blocking = false; if (config.autostart) { scheduleBegin(); } } }, stack: function stack(offset) { offset = (offset || 0) + 2; return sourceFromStacktrace(offset); }, onError: onError }); QUnit.pushFailure = pushFailure; QUnit.assert = Assert.prototype; QUnit.equiv = equiv; QUnit.dump = dump; registerLoggingCallbacks(QUnit); function scheduleBegin() { runStarted = true; // Add a slight delay to allow definition of more modules and tests. if (defined.setTimeout) { setTimeout(function () { begin(); }, 13); } else { begin(); } } function begin() { var i, l, modulesLog = []; // If the test run hasn't officially begun yet if (!config.started) { // Record the time of the test run's beginning config.started = now(); // Delete the loose unnamed module if unused. if (config.modules[0].name === "" && config.modules[0].tests.length === 0) { config.modules.shift(); } // Avoid unnecessary information by not logging modules' test environments for (i = 0, l = config.modules.length; i < l; i++) { modulesLog.push({ name: config.modules[i].name, tests: config.modules[i].tests }); } // The test run is officially beginning now emit("runStart", globalSuite.start(true)); runLoggingCallbacks("begin", { totalTests: Test.count, modules: modulesLog }); } config.blocking = false; process(true); } function process(last) { function next() { process(last); } var start = now(); config.depth = (config.depth || 0) + 1; while (config.queue.length && !config.blocking) { if (!defined.setTimeout || config.updateRate <= 0 || now() - start < config.updateRate) { if (config.current) { // Reset async tracking for each phase of the Test lifecycle config.current.usedAsync = false; } config.queue.shift()(); } else { setTimeout(next, 13); break; } } config.depth--; if (last && !config.blocking && !config.queue.length && config.depth === 0) { done(); } } function done() { var runtime, passed, i, key, storage = config.storage; internalState.autorun = true; runtime = now() - config.started; passed = config.stats.all - config.stats.bad; emit("runEnd", globalSuite.end(true)); runLoggingCallbacks("done", { failed: config.stats.bad, passed: passed, total: config.stats.all, runtime: runtime }); // Clear own storage items if all tests passed if (storage && config.stats.bad === 0) { for (i = storage.length - 1; i >= 0; i--) { key = storage.key(i); if (key.indexOf("qunit-test-") === 0) { storage.removeItem(key); } } } } function setHook(module, hookName) { if (module.testEnvironment === undefined) { module.testEnvironment = {}; } return function (callback) { module.testEnvironment[hookName] = callback; }; } exportQUnit(QUnit); (function () { if (typeof window === "undefined" || typeof document === "undefined") { return; } var config = QUnit.config, hasOwn = Object.prototype.hasOwnProperty; // Stores fixture HTML for resetting later function storeFixture() { // Avoid overwriting user-defined values if (hasOwn.call(config, "fixture")) { return; } var fixture = document.getElementById("qunit-fixture"); if (fixture) { config.fixture = fixture.innerHTML; } } QUnit.begin(storeFixture); // Resets the fixture DOM element if available. function resetFixture() { if (config.fixture == null) { return; } var fixture = document.getElementById("qunit-fixture"); if (fixture) { fixture.innerHTML = config.fixture; } } QUnit.testStart(resetFixture); })(); (function () { // Only interact with URLs via window.location var location = typeof window !== "undefined" && window.location; if (!location) { return; } var urlParams = getUrlParams(); QUnit.urlParams = urlParams; // Match module/test by inclusion in an array QUnit.config.moduleId = [].concat(urlParams.moduleId || []); QUnit.config.testId = [].concat(urlParams.testId || []); // Exact case-insensitive match of the module name QUnit.config.module = urlParams.module; // Regular expression or case-insenstive substring match against "moduleName: testName" QUnit.config.filter = urlParams.filter; // Test order randomization if (urlParams.seed === true) { // Generate a random seed if the option is specified without a value QUnit.config.seed = Math.random().toString(36).slice(2); } else if (urlParams.seed) { QUnit.config.seed = urlParams.seed; } // Add URL-parameter-mapped config values with UI form rendering data QUnit.config.urlConfig.push({ id: "hidepassed", label: "Hide passed tests", tooltip: "Only show tests and assertions that fail. Stored as query-strings." }, { id: "noglobals", label: "Check for Globals", tooltip: "Enabling this will test if any test introduces new properties on the " + "global object (`window` in Browsers). Stored as query-strings." }, { id: "notrycatch", label: "No try-catch", tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " + "exceptions in IE reasonable. Stored as query-strings." }); QUnit.begin(function () { var i, option, urlConfig = QUnit.config.urlConfig; for (i = 0; i < urlConfig.length; i++) { // Options can be either strings or objects with nonempty "id" properties option = QUnit.config.urlConfig[i]; if (typeof option !== "string") { option = option.id; } if (QUnit.config[option] === undefined) { QUnit.config[option] = urlParams[option]; } } }); function getUrlParams() { var i, param, name, value; var urlParams = Object.create(null); var params = location.search.slice(1).split("&"); var length = params.length; for (i = 0; i < length; i++) { if (params[i]) { param = params[i].split("="); name = decodeQueryParam(param[0]); // Allow just a key to turn on a flag, e.g., test.html?noglobals value = param.length === 1 || decodeQueryParam(param.slice(1).join("=")); if (name in urlParams) { urlParams[name] = [].concat(urlParams[name], value); } else { urlParams[name] = value; } } } return urlParams; } function decodeQueryParam(param) { return decodeURIComponent(param.replace(/\+/g, "%20")); } })(); var stats = { passedTests: 0, failedTests: 0, skippedTests: 0, todoTests: 0 }; // Escape text for attribute or text content. function escapeText(s) { if (!s) { return ""; } s = s + ""; // Both single quotes and double quotes (for attributes) return s.replace(/['"<>&]/g, function (s) { switch (s) { case "'": return "'"; case "\"": return """; case "<": return "<"; case ">": return ">"; case "&": return "&"; } }); } (function () { // Don't load the HTML Reporter on non-browser environments if (typeof window === "undefined" || !window.document) { return; } var config = QUnit.config, document$$1 = window.document, collapseNext = false, hasOwn = Object.prototype.hasOwnProperty, unfilteredUrl = setUrl({ filter: undefined, module: undefined, moduleId: undefined, testId: undefined }), modulesList = []; function addEvent(elem, type, fn) { elem.addEventListener(type, fn, false); } function removeEvent(elem, type, fn) { elem.removeEventListener(type, fn, false); } function addEvents(elems, type, fn) { var i = elems.length; while (i--) { addEvent(elems[i], type, fn); } } function hasClass(elem, name) { return (" " + elem.className + " ").indexOf(" " + name + " ") >= 0; } function addClass(elem, name) { if (!hasClass(elem, name)) { elem.className += (elem.className ? " " : "") + name; } } function toggleClass(elem, name, force) { if (force || typeof force === "undefined" && !hasClass(elem, name)) { addClass(elem, name); } else { removeClass(elem, name); } } function removeClass(elem, name) { var set = " " + elem.className + " "; // Class name may appear multiple times while (set.indexOf(" " + name + " ") >= 0) { set = set.replace(" " + name + " ", " "); } // Trim for prettiness elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, ""); } function id(name) { return document$$1.getElementById && document$$1.getElementById(name); } function abortTests() { var abortButton = id("qunit-abort-tests-button"); if (abortButton) { abortButton.disabled = true; abortButton.innerHTML = "Aborting..."; } QUnit.config.queue.length = 0; return false; } function interceptNavigation(ev) { applyUrlParams(); if (ev && ev.preventDefault) { ev.preventDefault(); } return false; } function getUrlConfigHtml() { var i, j, val, escaped, escapedTooltip, selection = false, urlConfig = config.urlConfig, urlConfigHtml = ""; for (i = 0; i < urlConfig.length; i++) { // Options can be either strings or objects with nonempty "id" properties val = config.urlConfig[i]; if (typeof val === "string") { val = { id: val, label: val }; } escaped = escapeText(val.id); escapedTooltip = escapeText(val.tooltip); if (!val.value || typeof val.value === "string") { urlConfigHtml += ""; } else { urlConfigHtml += ""; } } return urlConfigHtml; } // Handle "click" events on toolbar checkboxes and "change" for select menus. // Updates the URL with the new state of `config.urlConfig` values. function toolbarChanged() { var updatedUrl, value, tests, field = this, params = {}; // Detect if field is a select menu or a checkbox if ("selectedIndex" in field) { value = field.options[field.selectedIndex].value || undefined; } else { value = field.checked ? field.defaultValue || true : undefined; } params[field.name] = value; updatedUrl = setUrl(params); // Check if we can apply the change without a page refresh if ("hidepassed" === field.name && "replaceState" in window.history) { QUnit.urlParams[field.name] = value; config[field.name] = value || false; tests = id("qunit-tests"); if (tests) { toggleClass(tests, "hidepass", value || false); } window.history.replaceState(null, "", updatedUrl); } else { window.location = updatedUrl; } } function setUrl(params) { var key, arrValue, i, querystring = "?", location = window.location; params = QUnit.extend(QUnit.extend({}, QUnit.urlParams), params); for (key in params) { // Skip inherited or undefined properties if (hasOwn.call(params, key) && params[key] !== undefined) { // Output a parameter for each value of this key (but usually just one) arrValue = [].concat(params[key]); for (i = 0; i < arrValue.length; i++) { querystring += encodeURIComponent(key); if (arrValue[i] !== true) { querystring += "=" + encodeURIComponent(arrValue[i]); } querystring += "&"; } } } return location.protocol + "//" + location.host + location.pathname + querystring.slice(0, -1); } function applyUrlParams() { var i, selectedModules = [], modulesList = id("qunit-modulefilter-dropdown-list").getElementsByTagName("input"), filter = id("qunit-filter-input").value; for (i = 0; i < modulesList.length; i++) { if (modulesList[i].checked) { selectedModules.push(modulesList[i].value); } } window.location = setUrl({ filter: filter === "" ? undefined : filter, moduleId: selectedModules.length === 0 ? undefined : selectedModules, // Remove module and testId filter module: undefined, testId: undefined }); } function toolbarUrlConfigContainer() { var urlConfigContainer = document$$1.createElement("span"); urlConfigContainer.innerHTML = getUrlConfigHtml(); addClass(urlConfigContainer, "qunit-url-config"); addEvents(urlConfigContainer.getElementsByTagName("input"), "change", toolbarChanged); addEvents(urlConfigContainer.getElementsByTagName("select"), "change", toolbarChanged); return urlConfigContainer; } function abortTestsButton() { var button = document$$1.createElement("button"); button.id = "qunit-abort-tests-button"; button.innerHTML = "Abort"; addEvent(button, "click", abortTests); return button; } function toolbarLooseFilter() { var filter = document$$1.createElement("form"), label = document$$1.createElement("label"), input = document$$1.createElement("input"), button = document$$1.createElement("button"); addClass(filter, "qunit-filter"); label.innerHTML = "Filter: "; input.type = "text"; input.value = config.filter || ""; input.name = "filter"; input.id = "qunit-filter-input"; button.innerHTML = "Go"; label.appendChild(input); filter.appendChild(label); filter.appendChild(document$$1.createTextNode(" ")); filter.appendChild(button); addEvent(filter, "submit", interceptNavigation); return filter; } function moduleListHtml() { var i, checked, html = ""; for (i = 0; i < config.modules.length; i++) { if (config.modules[i].name !== "") { checked = config.moduleId.indexOf(config.modules[i].moduleId) > -1; html += "
      • "; } } return html; } function toolbarModuleFilter() { var allCheckbox, commit, reset, moduleFilter = document$$1.createElement("form"), label = document$$1.createElement("label"), moduleSearch = document$$1.createElement("input"), dropDown = document$$1.createElement("div"), actions = document$$1.createElement("span"), dropDownList = document$$1.createElement("ul"), dirty = false; moduleSearch.id = "qunit-modulefilter-search"; addEvent(moduleSearch, "input", searchInput); addEvent(moduleSearch, "input", searchFocus); addEvent(moduleSearch, "focus", searchFocus); addEvent(moduleSearch, "click", searchFocus); label.id = "qunit-modulefilter-search-container"; label.innerHTML = "Module: "; label.appendChild(moduleSearch); actions.id = "qunit-modulefilter-actions"; actions.innerHTML = "" + "" + ""; allCheckbox = actions.lastChild.firstChild; commit = actions.firstChild; reset = commit.nextSibling; addEvent(commit, "click", applyUrlParams); dropDownList.id = "qunit-modulefilter-dropdown-list"; dropDownList.innerHTML = moduleListHtml(); dropDown.id = "qunit-modulefilter-dropdown"; dropDown.style.display = "none"; dropDown.appendChild(actions); dropDown.appendChild(dropDownList); addEvent(dropDown, "change", selectionChange); selectionChange(); moduleFilter.id = "qunit-modulefilter"; moduleFilter.appendChild(label); moduleFilter.appendChild(dropDown); addEvent(moduleFilter, "submit", interceptNavigation); addEvent(moduleFilter, "reset", function () { // Let the reset happen, then update styles window.setTimeout(selectionChange); }); // Enables show/hide for the dropdown function searchFocus() { if (dropDown.style.display !== "none") { return; } dropDown.style.display = "block"; addEvent(document$$1, "click", hideHandler); addEvent(document$$1, "keydown", hideHandler); // Hide on Escape keydown or outside-container click function hideHandler(e) { var inContainer = moduleFilter.contains(e.target); if (e.keyCode === 27 || !inContainer) { if (e.keyCode === 27 && inContainer) { moduleSearch.focus(); } dropDown.style.display = "none"; removeEvent(document$$1, "click", hideHandler); removeEvent(document$$1, "keydown", hideHandler); moduleSearch.value = ""; searchInput(); } } } // Processes module search box input function searchInput() { var i, item, searchText = moduleSearch.value.toLowerCase(), listItems = dropDownList.children; for (i = 0; i < listItems.length; i++) { item = listItems[i]; if (!searchText || item.textContent.toLowerCase().indexOf(searchText) > -1) { item.style.display = ""; } else { item.style.display = "none"; } } } // Processes selection changes function selectionChange(evt) { var i, item, checkbox = evt && evt.target || allCheckbox, modulesList = dropDownList.getElementsByTagName("input"), selectedNames = []; toggleClass(checkbox.parentNode, "checked", checkbox.checked); dirty = false; if (checkbox.checked && checkbox !== allCheckbox) { allCheckbox.checked = false; removeClass(allCheckbox.parentNode, "checked"); } for (i = 0; i < modulesList.length; i++) { item = modulesList[i]; if (!evt) { toggleClass(item.parentNode, "checked", item.checked); } else if (checkbox === allCheckbox && checkbox.checked) { item.checked = false; removeClass(item.parentNode, "checked"); } dirty = dirty || item.checked !== item.defaultChecked; if (item.checked) { selectedNames.push(item.parentNode.textContent); } } commit.style.display = reset.style.display = dirty ? "" : "none"; moduleSearch.placeholder = selectedNames.join(", ") || allCheckbox.parentNode.textContent; moduleSearch.title = "Type to filter list. Current selection:\n" + (selectedNames.join("\n") || allCheckbox.parentNode.textContent); } return moduleFilter; } function appendToolbar() { var toolbar = id("qunit-testrunner-toolbar"); if (toolbar) { toolbar.appendChild(toolbarUrlConfigContainer()); toolbar.appendChild(toolbarModuleFilter()); toolbar.appendChild(toolbarLooseFilter()); toolbar.appendChild(document$$1.createElement("div")).className = "clearfix"; } } function appendHeader() { var header = id("qunit-header"); if (header) { header.innerHTML = "" + header.innerHTML + " "; } } function appendBanner() { var banner = id("qunit-banner"); if (banner) { banner.className = ""; } } function appendTestResults() { var tests = id("qunit-tests"), result = id("qunit-testresult"), controls; if (result) { result.parentNode.removeChild(result); } if (tests) { tests.innerHTML = ""; result = document$$1.createElement("p"); result.id = "qunit-testresult"; result.className = "result"; tests.parentNode.insertBefore(result, tests); result.innerHTML = "
        Running...
         
        " + "
        " + "
        "; controls = id("qunit-testresult-controls"); } if (controls) { controls.appendChild(abortTestsButton()); } } function appendFilteredTest() { var testId = QUnit.config.testId; if (!testId || testId.length <= 0) { return ""; } return "
        Rerunning selected tests: " + escapeText(testId.join(", ")) + " Run all tests
        "; } function appendUserAgent() { var userAgent = id("qunit-userAgent"); if (userAgent) { userAgent.innerHTML = ""; userAgent.appendChild(document$$1.createTextNode("QUnit " + QUnit.version + "; " + navigator.userAgent)); } } function appendInterface() { var qunit = id("qunit"); if (qunit) { qunit.innerHTML = "

        " + escapeText(document$$1.title) + "

        " + "

        " + "
        " + appendFilteredTest() + "

        " + "
          "; } appendHeader(); appendBanner(); appendTestResults(); appendUserAgent(); appendToolbar(); } function appendTestsList(modules) { var i, l, x, z, test, moduleObj; for (i = 0, l = modules.length; i < l; i++) { moduleObj = modules[i]; for (x = 0, z = moduleObj.tests.length; x < z; x++) { test = moduleObj.tests[x]; appendTest(test.name, test.testId, moduleObj.name); } } } function appendTest(name, testId, moduleName) { var title, rerunTrigger, testBlock, assertList, tests = id("qunit-tests"); if (!tests) { return; } title = document$$1.createElement("strong"); title.innerHTML = getNameHtml(name, moduleName); rerunTrigger = document$$1.createElement("a"); rerunTrigger.innerHTML = "Rerun"; rerunTrigger.href = setUrl({ testId: testId }); testBlock = document$$1.createElement("li"); testBlock.appendChild(title); testBlock.appendChild(rerunTrigger); testBlock.id = "qunit-test-output-" + testId; assertList = document$$1.createElement("ol"); assertList.className = "qunit-assert-list"; testBlock.appendChild(assertList); tests.appendChild(testBlock); } // HTML Reporter initialization and load QUnit.begin(function (details) { var i, moduleObj, tests; // Sort modules by name for the picker for (i = 0; i < details.modules.length; i++) { moduleObj = details.modules[i]; if (moduleObj.name) { modulesList.push(moduleObj.name); } } modulesList.sort(function (a, b) { return a.localeCompare(b); }); // Initialize QUnit elements appendInterface(); appendTestsList(details.modules); tests = id("qunit-tests"); if (tests && config.hidepassed) { addClass(tests, "hidepass"); } }); QUnit.done(function (details) { var banner = id("qunit-banner"), tests = id("qunit-tests"), abortButton = id("qunit-abort-tests-button"), totalTests = stats.passedTests + stats.skippedTests + stats.todoTests + stats.failedTests, html = [totalTests, " tests completed in ", details.runtime, " milliseconds, with ", stats.failedTests, " failed, ", stats.skippedTests, " skipped, and ", stats.todoTests, " todo.
          ", "", details.passed, " assertions of ", details.total, " passed, ", details.failed, " failed."].join(""), test, assertLi, assertList; // Update remaing tests to aborted if (abortButton && abortButton.disabled) { html = "Tests aborted after " + details.runtime + " milliseconds."; for (var i = 0; i < tests.children.length; i++) { test = tests.children[i]; if (test.className === "" || test.className === "running") { test.className = "aborted"; assertList = test.getElementsByTagName("ol")[0]; assertLi = document$$1.createElement("li"); assertLi.className = "fail"; assertLi.innerHTML = "Test aborted."; assertList.appendChild(assertLi); } } } if (banner && (!abortButton || abortButton.disabled === false)) { banner.className = stats.failedTests ? "qunit-fail" : "qunit-pass"; } if (abortButton) { abortButton.parentNode.removeChild(abortButton); } if (tests) { id("qunit-testresult-display").innerHTML = html; } if (config.altertitle && document$$1.title) { // Show ✖ for good, ✔ for bad suite result in title // use escape sequences in case file gets loaded with non-utf-8-charset document$$1.title = [stats.failedTests ? "\u2716" : "\u2714", document$$1.title.replace(/^[\u2714\u2716] /i, "")].join(" "); } // Scroll back to top to show results if (config.scrolltop && window.scrollTo) { window.scrollTo(0, 0); } }); function getNameHtml(name, module) { var nameHtml = ""; if (module) { nameHtml = "" + escapeText(module) + ": "; } nameHtml += "" + escapeText(name) + ""; return nameHtml; } QUnit.testStart(function (details) { var running, testBlock, bad; testBlock = id("qunit-test-output-" + details.testId); if (testBlock) { testBlock.className = "running"; } else { // Report later registered tests appendTest(details.name, details.testId, details.module); } running = id("qunit-testresult-display"); if (running) { bad = QUnit.config.reorder && details.previousFailure; running.innerHTML = (bad ? "Rerunning previously failed test:
          " : "Running:
          ") + getNameHtml(details.name, details.module); } }); function stripHtml(string) { // Strip tags, html entity and whitespaces return string.replace(/<\/?[^>]+(>|$)/g, "").replace(/\"/g, "").replace(/\s+/g, ""); } QUnit.log(function (details) { var assertList, assertLi, message, expected, actual, diff, showDiff = false, testItem = id("qunit-test-output-" + details.testId); if (!testItem) { return; } message = escapeText(details.message) || (details.result ? "okay" : "failed"); message = "" + message + ""; message += "@ " + details.runtime + " ms"; // The pushFailure doesn't provide details.expected // when it calls, it's implicit to also not show expected and diff stuff // Also, we need to check details.expected existence, as it can exist and be undefined if (!details.result && hasOwn.call(details, "expected")) { if (details.negative) { expected = "NOT " + QUnit.dump.parse(details.expected); } else { expected = QUnit.dump.parse(details.expected); } actual = QUnit.dump.parse(details.actual); message += ""; if (actual !== expected) { message += ""; // Don't show diff if actual or expected are booleans if (!/^(true|false)$/.test(actual) && !/^(true|false)$/.test(expected)) { diff = QUnit.diff(expected, actual); showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length; } // Don't show diff if expected and actual are totally different if (showDiff) { message += ""; } } else if (expected.indexOf("[object Array]") !== -1 || expected.indexOf("[object Object]") !== -1) { message += ""; } else { message += ""; } if (details.source) { message += ""; } message += "
          Expected:
          " + escapeText(expected) + "
          Result:
          " + escapeText(actual) + "
          Diff:
          " + diff + "
          Message: " + "Diff suppressed as the depth of object is more than current max depth (" + QUnit.config.maxDepth + ").

          Hint: Use QUnit.dump.maxDepth to " + " run with a higher max depth or " + "Rerun without max depth.

          Message: " + "Diff suppressed as the expected and actual results have an equivalent" + " serialization
          Source:
          " + escapeText(details.source) + "
          "; // This occurs when pushFailure is set and we have an extracted stack trace } else if (!details.result && details.source) { message += "" + "" + "
          Source:
          " + escapeText(details.source) + "
          "; } assertList = testItem.getElementsByTagName("ol")[0]; assertLi = document$$1.createElement("li"); assertLi.className = details.result ? "pass" : "fail"; assertLi.innerHTML = message; assertList.appendChild(assertLi); }); QUnit.testDone(function (details) { var testTitle, time, testItem, assertList, good, bad, testCounts, skipped, sourceName, tests = id("qunit-tests"); if (!tests) { return; } testItem = id("qunit-test-output-" + details.testId); assertList = testItem.getElementsByTagName("ol")[0]; good = details.passed; bad = details.failed; // This test passed if it has no unexpected failed assertions var testPassed = details.failed > 0 ? details.todo : !details.todo; if (testPassed) { // Collapse the passing tests addClass(assertList, "qunit-collapsed"); } else if (config.collapse) { if (!collapseNext) { // Skip collapsing the first failing test collapseNext = true; } else { // Collapse remaining tests addClass(assertList, "qunit-collapsed"); } } // The testItem.firstChild is the test name testTitle = testItem.firstChild; testCounts = bad ? "" + bad + ", " + "" + good + ", " : ""; testTitle.innerHTML += " (" + testCounts + details.assertions.length + ")"; if (details.skipped) { stats.skippedTests++; testItem.className = "skipped"; skipped = document$$1.createElement("em"); skipped.className = "qunit-skipped-label"; skipped.innerHTML = "skipped"; testItem.insertBefore(skipped, testTitle); } else { addEvent(testTitle, "click", function () { toggleClass(assertList, "qunit-collapsed"); }); testItem.className = testPassed ? "pass" : "fail"; if (details.todo) { var todoLabel = document$$1.createElement("em"); todoLabel.className = "qunit-todo-label"; todoLabel.innerHTML = "todo"; testItem.insertBefore(todoLabel, testTitle); } time = document$$1.createElement("span"); time.className = "runtime"; time.innerHTML = details.runtime + " ms"; testItem.insertBefore(time, assertList); if (!testPassed) { stats.failedTests++; } else if (details.todo) { stats.todoTests++; } else { stats.passedTests++; } } // Show the source of the test when showing assertions if (details.source) { sourceName = document$$1.createElement("p"); sourceName.innerHTML = "Source: " + details.source; addClass(sourceName, "qunit-source"); if (testPassed) { addClass(sourceName, "qunit-collapsed"); } addEvent(testTitle, "click", function () { toggleClass(sourceName, "qunit-collapsed"); }); testItem.appendChild(sourceName); } }); // Avoid readyState issue with phantomjs // Ref: #818 var notPhantom = function (p) { return !(p && p.version && p.version.major > 0); }(window.phantom); if (notPhantom && document$$1.readyState === "complete") { QUnit.load(); } else { addEvent(window, "load", QUnit.load); } // Wrap window.onerror. We will call the original window.onerror to see if // the existing handler fully handles the error; if not, we will call the // QUnit.onError function. var originalWindowOnError = window.onerror; // Cover uncaught exceptions // Returning true will suppress the default browser handler, // returning false will let it run. window.onerror = function (message, fileName, lineNumber) { var ret = false; if (originalWindowOnError) { for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { args[_key - 3] = arguments[_key]; } ret = originalWindowOnError.call.apply(originalWindowOnError, [this, message, fileName, lineNumber].concat(args)); } // Treat return value as window.onerror itself does, // Only do our handling if not suppressed. if (ret !== true) { var error = { message: message, fileName: fileName, lineNumber: lineNumber }; ret = QUnit.onError(error); } return ret; }; })(); /* * This file is a modified version of google-diff-match-patch's JavaScript implementation * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js), * modifications are licensed as more fully set forth in LICENSE.txt. * * The original source of google-diff-match-patch is attributable and licensed as follows: * * Copyright 2006 Google Inc. * https://code.google.com/p/google-diff-match-patch/ * * 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 * * https://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. * * More Info: * https://code.google.com/p/google-diff-match-patch/ * * Usage: QUnit.diff(expected, actual) * */ QUnit.diff = function () { function DiffMatchPatch() {} // DIFF FUNCTIONS /** * The data structure representing a diff is an array of tuples: * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']] * which means: delete 'Hello', add 'Goodbye' and keep ' world.' */ var DIFF_DELETE = -1, DIFF_INSERT = 1, DIFF_EQUAL = 0; /** * Find the differences between two texts. Simplifies the problem by stripping * any common prefix or suffix off the texts before diffing. * @param {string} text1 Old string to be diffed. * @param {string} text2 New string to be diffed. * @param {boolean=} optChecklines Optional speedup flag. If present and false, * then don't run a line-level diff first to identify the changed areas. * Defaults to true, which does a faster, slightly less optimal diff. * @return {!Array.} Array of diff tuples. */ DiffMatchPatch.prototype.DiffMain = function (text1, text2, optChecklines) { var deadline, checklines, commonlength, commonprefix, commonsuffix, diffs; // The diff must be complete in up to 1 second. deadline = new Date().getTime() + 1000; // Check for null inputs. if (text1 === null || text2 === null) { throw new Error("Null input. (DiffMain)"); } // Check for equality (speedup). if (text1 === text2) { if (text1) { return [[DIFF_EQUAL, text1]]; } return []; } if (typeof optChecklines === "undefined") { optChecklines = true; } checklines = optChecklines; // Trim off common prefix (speedup). commonlength = this.diffCommonPrefix(text1, text2); commonprefix = text1.substring(0, commonlength); text1 = text1.substring(commonlength); text2 = text2.substring(commonlength); // Trim off common suffix (speedup). commonlength = this.diffCommonSuffix(text1, text2); commonsuffix = text1.substring(text1.length - commonlength); text1 = text1.substring(0, text1.length - commonlength); text2 = text2.substring(0, text2.length - commonlength); // Compute the diff on the middle block. diffs = this.diffCompute(text1, text2, checklines, deadline); // Restore the prefix and suffix. if (commonprefix) { diffs.unshift([DIFF_EQUAL, commonprefix]); } if (commonsuffix) { diffs.push([DIFF_EQUAL, commonsuffix]); } this.diffCleanupMerge(diffs); return diffs; }; /** * Reduce the number of edits by eliminating operationally trivial equalities. * @param {!Array.} diffs Array of diff tuples. */ DiffMatchPatch.prototype.diffCleanupEfficiency = function (diffs) { var changes, equalities, equalitiesLength, lastequality, pointer, preIns, preDel, postIns, postDel; changes = false; equalities = []; // Stack of indices where equalities are found. equalitiesLength = 0; // Keeping our own length var is faster in JS. /** @type {?string} */ lastequality = null; // Always equal to diffs[equalities[equalitiesLength - 1]][1] pointer = 0; // Index of current position. // Is there an insertion operation before the last equality. preIns = false; // Is there a deletion operation before the last equality. preDel = false; // Is there an insertion operation after the last equality. postIns = false; // Is there a deletion operation after the last equality. postDel = false; while (pointer < diffs.length) { // Equality found. if (diffs[pointer][0] === DIFF_EQUAL) { if (diffs[pointer][1].length < 4 && (postIns || postDel)) { // Candidate found. equalities[equalitiesLength++] = pointer; preIns = postIns; preDel = postDel; lastequality = diffs[pointer][1]; } else { // Not a candidate, and can never become one. equalitiesLength = 0; lastequality = null; } postIns = postDel = false; // An insertion or deletion. } else { if (diffs[pointer][0] === DIFF_DELETE) { postDel = true; } else { postIns = true; } /* * Five types to be split: * ABXYCD * AXCD * ABXC * AXCD * ABXC */ if (lastequality && (preIns && preDel && postIns && postDel || lastequality.length < 2 && preIns + preDel + postIns + postDel === 3)) { // Duplicate record. diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]); // Change second copy to insert. diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; equalitiesLength--; // Throw away the equality we just deleted; lastequality = null; if (preIns && preDel) { // No changes made which could affect previous entry, keep going. postIns = postDel = true; equalitiesLength = 0; } else { equalitiesLength--; // Throw away the previous equality. pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; postIns = postDel = false; } changes = true; } } pointer++; } if (changes) { this.diffCleanupMerge(diffs); } }; /** * Convert a diff array into a pretty HTML report. * @param {!Array.} diffs Array of diff tuples. * @param {integer} string to be beautified. * @return {string} HTML representation. */ DiffMatchPatch.prototype.diffPrettyHtml = function (diffs) { var op, data, x, html = []; for (x = 0; x < diffs.length; x++) { op = diffs[x][0]; // Operation (insert, delete, equal) data = diffs[x][1]; // Text of change. switch (op) { case DIFF_INSERT: html[x] = "" + escapeText(data) + ""; break; case DIFF_DELETE: html[x] = "" + escapeText(data) + ""; break; case DIFF_EQUAL: html[x] = "" + escapeText(data) + ""; break; } } return html.join(""); }; /** * Determine the common prefix of two strings. * @param {string} text1 First string. * @param {string} text2 Second string. * @return {number} The number of characters common to the start of each * string. */ DiffMatchPatch.prototype.diffCommonPrefix = function (text1, text2) { var pointermid, pointermax, pointermin, pointerstart; // Quick check for common null cases. if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) { return 0; } // Binary search. // Performance analysis: https://neil.fraser.name/news/2007/10/09/ pointermin = 0; pointermax = Math.min(text1.length, text2.length); pointermid = pointermax; pointerstart = 0; while (pointermin < pointermid) { if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) { pointermin = pointermid; pointerstart = pointermin; } else { pointermax = pointermid; } pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); } return pointermid; }; /** * Determine the common suffix of two strings. * @param {string} text1 First string. * @param {string} text2 Second string. * @return {number} The number of characters common to the end of each string. */ DiffMatchPatch.prototype.diffCommonSuffix = function (text1, text2) { var pointermid, pointermax, pointermin, pointerend; // Quick check for common null cases. if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) { return 0; } // Binary search. // Performance analysis: https://neil.fraser.name/news/2007/10/09/ pointermin = 0; pointermax = Math.min(text1.length, text2.length); pointermid = pointermax; pointerend = 0; while (pointermin < pointermid) { if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) { pointermin = pointermid; pointerend = pointermin; } else { pointermax = pointermid; } pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); } return pointermid; }; /** * Find the differences between two texts. Assumes that the texts do not * have any common prefix or suffix. * @param {string} text1 Old string to be diffed. * @param {string} text2 New string to be diffed. * @param {boolean} checklines Speedup flag. If false, then don't run a * line-level diff first to identify the changed areas. * If true, then run a faster, slightly less optimal diff. * @param {number} deadline Time when the diff should be complete by. * @return {!Array.} Array of diff tuples. * @private */ DiffMatchPatch.prototype.diffCompute = function (text1, text2, checklines, deadline) { var diffs, longtext, shorttext, i, hm, text1A, text2A, text1B, text2B, midCommon, diffsA, diffsB; if (!text1) { // Just add some text (speedup). return [[DIFF_INSERT, text2]]; } if (!text2) { // Just delete some text (speedup). return [[DIFF_DELETE, text1]]; } longtext = text1.length > text2.length ? text1 : text2; shorttext = text1.length > text2.length ? text2 : text1; i = longtext.indexOf(shorttext); if (i !== -1) { // Shorter text is inside the longer text (speedup). diffs = [[DIFF_INSERT, longtext.substring(0, i)], [DIFF_EQUAL, shorttext], [DIFF_INSERT, longtext.substring(i + shorttext.length)]]; // Swap insertions for deletions if diff is reversed. if (text1.length > text2.length) { diffs[0][0] = diffs[2][0] = DIFF_DELETE; } return diffs; } if (shorttext.length === 1) { // Single character string. // After the previous speedup, the character can't be an equality. return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]]; } // Check to see if the problem can be split in two. hm = this.diffHalfMatch(text1, text2); if (hm) { // A half-match was found, sort out the return data. text1A = hm[0]; text1B = hm[1]; text2A = hm[2]; text2B = hm[3]; midCommon = hm[4]; // Send both pairs off for separate processing. diffsA = this.DiffMain(text1A, text2A, checklines, deadline); diffsB = this.DiffMain(text1B, text2B, checklines, deadline); // Merge the results. return diffsA.concat([[DIFF_EQUAL, midCommon]], diffsB); } if (checklines && text1.length > 100 && text2.length > 100) { return this.diffLineMode(text1, text2, deadline); } return this.diffBisect(text1, text2, deadline); }; /** * Do the two texts share a substring which is at least half the length of the * longer text? * This speedup can produce non-minimal diffs. * @param {string} text1 First string. * @param {string} text2 Second string. * @return {Array.} Five element Array, containing the prefix of * text1, the suffix of text1, the prefix of text2, the suffix of * text2 and the common middle. Or null if there was no match. * @private */ DiffMatchPatch.prototype.diffHalfMatch = function (text1, text2) { var longtext, shorttext, dmp, text1A, text2B, text2A, text1B, midCommon, hm1, hm2, hm; longtext = text1.length > text2.length ? text1 : text2; shorttext = text1.length > text2.length ? text2 : text1; if (longtext.length < 4 || shorttext.length * 2 < longtext.length) { return null; // Pointless. } dmp = this; // 'this' becomes 'window' in a closure. /** * Does a substring of shorttext exist within longtext such that the substring * is at least half the length of longtext? * Closure, but does not reference any external variables. * @param {string} longtext Longer string. * @param {string} shorttext Shorter string. * @param {number} i Start index of quarter length substring within longtext. * @return {Array.} Five element Array, containing the prefix of * longtext, the suffix of longtext, the prefix of shorttext, the suffix * of shorttext and the common middle. Or null if there was no match. * @private */ function diffHalfMatchI(longtext, shorttext, i) { var seed, j, bestCommon, prefixLength, suffixLength, bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB; // Start with a 1/4 length substring at position i as a seed. seed = longtext.substring(i, i + Math.floor(longtext.length / 4)); j = -1; bestCommon = ""; while ((j = shorttext.indexOf(seed, j + 1)) !== -1) { prefixLength = dmp.diffCommonPrefix(longtext.substring(i), shorttext.substring(j)); suffixLength = dmp.diffCommonSuffix(longtext.substring(0, i), shorttext.substring(0, j)); if (bestCommon.length < suffixLength + prefixLength) { bestCommon = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength); bestLongtextA = longtext.substring(0, i - suffixLength); bestLongtextB = longtext.substring(i + prefixLength); bestShorttextA = shorttext.substring(0, j - suffixLength); bestShorttextB = shorttext.substring(j + prefixLength); } } if (bestCommon.length * 2 >= longtext.length) { return [bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB, bestCommon]; } else { return null; } } // First check if the second quarter is the seed for a half-match. hm1 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 4)); // Check again based on the third quarter. hm2 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 2)); if (!hm1 && !hm2) { return null; } else if (!hm2) { hm = hm1; } else if (!hm1) { hm = hm2; } else { // Both matched. Select the longest. hm = hm1[4].length > hm2[4].length ? hm1 : hm2; } // A half-match was found, sort out the return data. if (text1.length > text2.length) { text1A = hm[0]; text1B = hm[1]; text2A = hm[2]; text2B = hm[3]; } else { text2A = hm[0]; text2B = hm[1]; text1A = hm[2]; text1B = hm[3]; } midCommon = hm[4]; return [text1A, text1B, text2A, text2B, midCommon]; }; /** * Do a quick line-level diff on both strings, then rediff the parts for * greater accuracy. * This speedup can produce non-minimal diffs. * @param {string} text1 Old string to be diffed. * @param {string} text2 New string to be diffed. * @param {number} deadline Time when the diff should be complete by. * @return {!Array.} Array of diff tuples. * @private */ DiffMatchPatch.prototype.diffLineMode = function (text1, text2, deadline) { var a, diffs, linearray, pointer, countInsert, countDelete, textInsert, textDelete, j; // Scan the text on a line-by-line basis first. a = this.diffLinesToChars(text1, text2); text1 = a.chars1; text2 = a.chars2; linearray = a.lineArray; diffs = this.DiffMain(text1, text2, false, deadline); // Convert the diff back to original text. this.diffCharsToLines(diffs, linearray); // Eliminate freak matches (e.g. blank lines) this.diffCleanupSemantic(diffs); // Rediff any replacement blocks, this time character-by-character. // Add a dummy entry at the end. diffs.push([DIFF_EQUAL, ""]); pointer = 0; countDelete = 0; countInsert = 0; textDelete = ""; textInsert = ""; while (pointer < diffs.length) { switch (diffs[pointer][0]) { case DIFF_INSERT: countInsert++; textInsert += diffs[pointer][1]; break; case DIFF_DELETE: countDelete++; textDelete += diffs[pointer][1]; break; case DIFF_EQUAL: // Upon reaching an equality, check for prior redundancies. if (countDelete >= 1 && countInsert >= 1) { // Delete the offending records and add the merged ones. diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert); pointer = pointer - countDelete - countInsert; a = this.DiffMain(textDelete, textInsert, false, deadline); for (j = a.length - 1; j >= 0; j--) { diffs.splice(pointer, 0, a[j]); } pointer = pointer + a.length; } countInsert = 0; countDelete = 0; textDelete = ""; textInsert = ""; break; } pointer++; } diffs.pop(); // Remove the dummy entry at the end. return diffs; }; /** * Find the 'middle snake' of a diff, split the problem in two * and return the recursively constructed diff. * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. * @param {string} text1 Old string to be diffed. * @param {string} text2 New string to be diffed. * @param {number} deadline Time at which to bail if not yet complete. * @return {!Array.} Array of diff tuples. * @private */ DiffMatchPatch.prototype.diffBisect = function (text1, text2, deadline) { var text1Length, text2Length, maxD, vOffset, vLength, v1, v2, x, delta, front, k1start, k1end, k2start, k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2; // Cache the text lengths to prevent multiple calls. text1Length = text1.length; text2Length = text2.length; maxD = Math.ceil((text1Length + text2Length) / 2); vOffset = maxD; vLength = 2 * maxD; v1 = new Array(vLength); v2 = new Array(vLength); // Setting all elements to -1 is faster in Chrome & Firefox than mixing // integers and undefined. for (x = 0; x < vLength; x++) { v1[x] = -1; v2[x] = -1; } v1[vOffset + 1] = 0; v2[vOffset + 1] = 0; delta = text1Length - text2Length; // If the total number of characters is odd, then the front path will collide // with the reverse path. front = delta % 2 !== 0; // Offsets for start and end of k loop. // Prevents mapping of space beyond the grid. k1start = 0; k1end = 0; k2start = 0; k2end = 0; for (d = 0; d < maxD; d++) { // Bail out if deadline is reached. if (new Date().getTime() > deadline) { break; } // Walk the front path one step. for (k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { k1Offset = vOffset + k1; if (k1 === -d || k1 !== d && v1[k1Offset - 1] < v1[k1Offset + 1]) { x1 = v1[k1Offset + 1]; } else { x1 = v1[k1Offset - 1] + 1; } y1 = x1 - k1; while (x1 < text1Length && y1 < text2Length && text1.charAt(x1) === text2.charAt(y1)) { x1++; y1++; } v1[k1Offset] = x1; if (x1 > text1Length) { // Ran off the right of the graph. k1end += 2; } else if (y1 > text2Length) { // Ran off the bottom of the graph. k1start += 2; } else if (front) { k2Offset = vOffset + delta - k1; if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) { // Mirror x2 onto top-left coordinate system. x2 = text1Length - v2[k2Offset]; if (x1 >= x2) { // Overlap detected. return this.diffBisectSplit(text1, text2, x1, y1, deadline); } } } } // Walk the reverse path one step. for (k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { k2Offset = vOffset + k2; if (k2 === -d || k2 !== d && v2[k2Offset - 1] < v2[k2Offset + 1]) { x2 = v2[k2Offset + 1]; } else { x2 = v2[k2Offset - 1] + 1; } y2 = x2 - k2; while (x2 < text1Length && y2 < text2Length && text1.charAt(text1Length - x2 - 1) === text2.charAt(text2Length - y2 - 1)) { x2++; y2++; } v2[k2Offset] = x2; if (x2 > text1Length) { // Ran off the left of the graph. k2end += 2; } else if (y2 > text2Length) { // Ran off the top of the graph. k2start += 2; } else if (!front) { k1Offset = vOffset + delta - k2; if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) { x1 = v1[k1Offset]; y1 = vOffset + x1 - k1Offset; // Mirror x2 onto top-left coordinate system. x2 = text1Length - x2; if (x1 >= x2) { // Overlap detected. return this.diffBisectSplit(text1, text2, x1, y1, deadline); } } } } } // Diff took too long and hit the deadline or // number of diffs equals number of characters, no commonality at all. return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]]; }; /** * Given the location of the 'middle snake', split the diff in two parts * and recurse. * @param {string} text1 Old string to be diffed. * @param {string} text2 New string to be diffed. * @param {number} x Index of split point in text1. * @param {number} y Index of split point in text2. * @param {number} deadline Time at which to bail if not yet complete. * @return {!Array.} Array of diff tuples. * @private */ DiffMatchPatch.prototype.diffBisectSplit = function (text1, text2, x, y, deadline) { var text1a, text1b, text2a, text2b, diffs, diffsb; text1a = text1.substring(0, x); text2a = text2.substring(0, y); text1b = text1.substring(x); text2b = text2.substring(y); // Compute both diffs serially. diffs = this.DiffMain(text1a, text2a, false, deadline); diffsb = this.DiffMain(text1b, text2b, false, deadline); return diffs.concat(diffsb); }; /** * Reduce the number of edits by eliminating semantically trivial equalities. * @param {!Array.} diffs Array of diff tuples. */ DiffMatchPatch.prototype.diffCleanupSemantic = function (diffs) { var changes, equalities, equalitiesLength, lastequality, pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1, lengthDeletions1, deletion, insertion, overlapLength1, overlapLength2; changes = false; equalities = []; // Stack of indices where equalities are found. equalitiesLength = 0; // Keeping our own length var is faster in JS. /** @type {?string} */ lastequality = null; // Always equal to diffs[equalities[equalitiesLength - 1]][1] pointer = 0; // Index of current position. // Number of characters that changed prior to the equality. lengthInsertions1 = 0; lengthDeletions1 = 0; // Number of characters that changed after the equality. lengthInsertions2 = 0; lengthDeletions2 = 0; while (pointer < diffs.length) { if (diffs[pointer][0] === DIFF_EQUAL) { // Equality found. equalities[equalitiesLength++] = pointer; lengthInsertions1 = lengthInsertions2; lengthDeletions1 = lengthDeletions2; lengthInsertions2 = 0; lengthDeletions2 = 0; lastequality = diffs[pointer][1]; } else { // An insertion or deletion. if (diffs[pointer][0] === DIFF_INSERT) { lengthInsertions2 += diffs[pointer][1].length; } else { lengthDeletions2 += diffs[pointer][1].length; } // Eliminate an equality that is smaller or equal to the edits on both // sides of it. if (lastequality && lastequality.length <= Math.max(lengthInsertions1, lengthDeletions1) && lastequality.length <= Math.max(lengthInsertions2, lengthDeletions2)) { // Duplicate record. diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]); // Change second copy to insert. diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; // Throw away the equality we just deleted. equalitiesLength--; // Throw away the previous equality (it needs to be reevaluated). equalitiesLength--; pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; // Reset the counters. lengthInsertions1 = 0; lengthDeletions1 = 0; lengthInsertions2 = 0; lengthDeletions2 = 0; lastequality = null; changes = true; } } pointer++; } // Normalize the diff. if (changes) { this.diffCleanupMerge(diffs); } // Find any overlaps between deletions and insertions. // e.g: abcxxxxxxdef // -> abcxxxdef // e.g: xxxabcdefxxx // -> defxxxabc // Only extract an overlap if it is as big as the edit ahead or behind it. pointer = 1; while (pointer < diffs.length) { if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) { deletion = diffs[pointer - 1][1]; insertion = diffs[pointer][1]; overlapLength1 = this.diffCommonOverlap(deletion, insertion); overlapLength2 = this.diffCommonOverlap(insertion, deletion); if (overlapLength1 >= overlapLength2) { if (overlapLength1 >= deletion.length / 2 || overlapLength1 >= insertion.length / 2) { // Overlap found. Insert an equality and trim the surrounding edits. diffs.splice(pointer, 0, [DIFF_EQUAL, insertion.substring(0, overlapLength1)]); diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlapLength1); diffs[pointer + 1][1] = insertion.substring(overlapLength1); pointer++; } } else { if (overlapLength2 >= deletion.length / 2 || overlapLength2 >= insertion.length / 2) { // Reverse overlap found. // Insert an equality and swap and trim the surrounding edits. diffs.splice(pointer, 0, [DIFF_EQUAL, deletion.substring(0, overlapLength2)]); diffs[pointer - 1][0] = DIFF_INSERT; diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlapLength2); diffs[pointer + 1][0] = DIFF_DELETE; diffs[pointer + 1][1] = deletion.substring(overlapLength2); pointer++; } } pointer++; } pointer++; } }; /** * Determine if the suffix of one string is the prefix of another. * @param {string} text1 First string. * @param {string} text2 Second string. * @return {number} The number of characters common to the end of the first * string and the start of the second string. * @private */ DiffMatchPatch.prototype.diffCommonOverlap = function (text1, text2) { var text1Length, text2Length, textLength, best, length, pattern, found; // Cache the text lengths to prevent multiple calls. text1Length = text1.length; text2Length = text2.length; // Eliminate the null case. if (text1Length === 0 || text2Length === 0) { return 0; } // Truncate the longer string. if (text1Length > text2Length) { text1 = text1.substring(text1Length - text2Length); } else if (text1Length < text2Length) { text2 = text2.substring(0, text1Length); } textLength = Math.min(text1Length, text2Length); // Quick check for the worst case. if (text1 === text2) { return textLength; } // Start by looking for a single character match // and increase length until no match is found. // Performance analysis: https://neil.fraser.name/news/2010/11/04/ best = 0; length = 1; while (true) { pattern = text1.substring(textLength - length); found = text2.indexOf(pattern); if (found === -1) { return best; } length += found; if (found === 0 || text1.substring(textLength - length) === text2.substring(0, length)) { best = length; length++; } } }; /** * Split two texts into an array of strings. Reduce the texts to a string of * hashes where each Unicode character represents one line. * @param {string} text1 First string. * @param {string} text2 Second string. * @return {{chars1: string, chars2: string, lineArray: !Array.}} * An object containing the encoded text1, the encoded text2 and * the array of unique strings. * The zeroth element of the array of unique strings is intentionally blank. * @private */ DiffMatchPatch.prototype.diffLinesToChars = function (text1, text2) { var lineArray, lineHash, chars1, chars2; lineArray = []; // E.g. lineArray[4] === 'Hello\n' lineHash = {}; // E.g. lineHash['Hello\n'] === 4 // '\x00' is a valid character, but various debuggers don't like it. // So we'll insert a junk entry to avoid generating a null character. lineArray[0] = ""; /** * Split a text into an array of strings. Reduce the texts to a string of * hashes where each Unicode character represents one line. * Modifies linearray and linehash through being a closure. * @param {string} text String to encode. * @return {string} Encoded string. * @private */ function diffLinesToCharsMunge(text) { var chars, lineStart, lineEnd, lineArrayLength, line; chars = ""; // Walk the text, pulling out a substring for each line. // text.split('\n') would would temporarily double our memory footprint. // Modifying text would create many large strings to garbage collect. lineStart = 0; lineEnd = -1; // Keeping our own length variable is faster than looking it up. lineArrayLength = lineArray.length; while (lineEnd < text.length - 1) { lineEnd = text.indexOf("\n", lineStart); if (lineEnd === -1) { lineEnd = text.length - 1; } line = text.substring(lineStart, lineEnd + 1); lineStart = lineEnd + 1; if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : lineHash[line] !== undefined) { chars += String.fromCharCode(lineHash[line]); } else { chars += String.fromCharCode(lineArrayLength); lineHash[line] = lineArrayLength; lineArray[lineArrayLength++] = line; } } return chars; } chars1 = diffLinesToCharsMunge(text1); chars2 = diffLinesToCharsMunge(text2); return { chars1: chars1, chars2: chars2, lineArray: lineArray }; }; /** * Rehydrate the text in a diff from a string of line hashes to real lines of * text. * @param {!Array.} diffs Array of diff tuples. * @param {!Array.} lineArray Array of unique strings. * @private */ DiffMatchPatch.prototype.diffCharsToLines = function (diffs, lineArray) { var x, chars, text, y; for (x = 0; x < diffs.length; x++) { chars = diffs[x][1]; text = []; for (y = 0; y < chars.length; y++) { text[y] = lineArray[chars.charCodeAt(y)]; } diffs[x][1] = text.join(""); } }; /** * Reorder and merge like edit sections. Merge equalities. * Any edit section can move as long as it doesn't cross an equality. * @param {!Array.} diffs Array of diff tuples. */ DiffMatchPatch.prototype.diffCleanupMerge = function (diffs) { var pointer, countDelete, countInsert, textInsert, textDelete, commonlength, changes, diffPointer, position; diffs.push([DIFF_EQUAL, ""]); // Add a dummy entry at the end. pointer = 0; countDelete = 0; countInsert = 0; textDelete = ""; textInsert = ""; while (pointer < diffs.length) { switch (diffs[pointer][0]) { case DIFF_INSERT: countInsert++; textInsert += diffs[pointer][1]; pointer++; break; case DIFF_DELETE: countDelete++; textDelete += diffs[pointer][1]; pointer++; break; case DIFF_EQUAL: // Upon reaching an equality, check for prior redundancies. if (countDelete + countInsert > 1) { if (countDelete !== 0 && countInsert !== 0) { // Factor out any common prefixes. commonlength = this.diffCommonPrefix(textInsert, textDelete); if (commonlength !== 0) { if (pointer - countDelete - countInsert > 0 && diffs[pointer - countDelete - countInsert - 1][0] === DIFF_EQUAL) { diffs[pointer - countDelete - countInsert - 1][1] += textInsert.substring(0, commonlength); } else { diffs.splice(0, 0, [DIFF_EQUAL, textInsert.substring(0, commonlength)]); pointer++; } textInsert = textInsert.substring(commonlength); textDelete = textDelete.substring(commonlength); } // Factor out any common suffixies. commonlength = this.diffCommonSuffix(textInsert, textDelete); if (commonlength !== 0) { diffs[pointer][1] = textInsert.substring(textInsert.length - commonlength) + diffs[pointer][1]; textInsert = textInsert.substring(0, textInsert.length - commonlength); textDelete = textDelete.substring(0, textDelete.length - commonlength); } } // Delete the offending records and add the merged ones. if (countDelete === 0) { diffs.splice(pointer - countInsert, countDelete + countInsert, [DIFF_INSERT, textInsert]); } else if (countInsert === 0) { diffs.splice(pointer - countDelete, countDelete + countInsert, [DIFF_DELETE, textDelete]); } else { diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert, [DIFF_DELETE, textDelete], [DIFF_INSERT, textInsert]); } pointer = pointer - countDelete - countInsert + (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1; } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) { // Merge this equality with the previous one. diffs[pointer - 1][1] += diffs[pointer][1]; diffs.splice(pointer, 1); } else { pointer++; } countInsert = 0; countDelete = 0; textDelete = ""; textInsert = ""; break; } } if (diffs[diffs.length - 1][1] === "") { diffs.pop(); // Remove the dummy entry at the end. } // Second pass: look for single edits surrounded on both sides by equalities // which can be shifted sideways to eliminate an equality. // e.g: ABAC -> ABAC changes = false; pointer = 1; // Intentionally ignore the first and last element (don't need checking). while (pointer < diffs.length - 1) { if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) { diffPointer = diffs[pointer][1]; position = diffPointer.substring(diffPointer.length - diffs[pointer - 1][1].length); // This is a single edit surrounded by equalities. if (position === diffs[pointer - 1][1]) { // Shift the edit over the previous equality. diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length); diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; diffs.splice(pointer - 1, 1); changes = true; } else if (diffPointer.substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) { // Shift the edit over the next equality. diffs[pointer - 1][1] += diffs[pointer + 1][1]; diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1]; diffs.splice(pointer + 1, 1); changes = true; } } pointer++; } // If shifts were made, the diff needs reordering and another shift sweep. if (changes) { this.diffCleanupMerge(diffs); } }; return function (o, n) { var diff, output, text; diff = new DiffMatchPatch(); output = diff.DiffMain(o, n); diff.diffCleanupEfficiency(output); text = diff.diffPrettyHtml(output); return text; }; }(); }((function() { return this; }()))); ================================================ FILE: webpack.config.js ================================================ /* global __dirname, require, module */ 'use strict' const webpack = require('webpack') const path = require('path') const env = require('yargs').argv.env const ExtractTextPlugin = require('extract-text-webpack-plugin') const extractSass = new ExtractTextPlugin({filename: 'noty.css'}) const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin const BrowserSyncPlugin = require('browser-sync-webpack-plugin') let libraryName = 'Noty' let plugins = [] let outputFile plugins.push(extractSass) plugins.push(new webpack.DefinePlugin({ VERSION: JSON.stringify(require('./package.json').version) })) if (env === 'build') { plugins.push(new UglifyJsPlugin({minimize: true, sourceMap: true})) outputFile = libraryName.toLowerCase() + '.min.js' } else { outputFile = libraryName.toLowerCase() + '.js' plugins.push(new BrowserSyncPlugin({ ui: false, host: 'localhost', port: 3000, server: { baseDir: ['./'], index: 'demo/index.html' } })) } const config = { entry: path.join(__dirname, '/src/index.js'), devtool: 'source-map', output: { path: path.join(__dirname, '/lib'), filename: outputFile, library: libraryName, libraryTarget: 'umd', umdNamedDefine: true }, module: { rules: [ { // standard-loader as a preloader enforce: 'pre', test: /\.js?$/, loader: 'standard-loader', exclude: /(node_modules|bower_components)/, options: { error: false, snazzy: true, parser: 'babel-eslint' } }, { test: /\.js$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/ }, { test: /\.scss$/, use: extractSass.extract(['css-loader', 'postcss-loader', 'sass-loader']), exclude: /(node_modules|bower_components)/ } ] }, resolve: { modules: [path.resolve('./src'), path.resolve('./node_modules')], extensions: ['.js', '.scss'] }, plugins: plugins } module.exports = config