diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..df43ed4
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,11 @@
+; This file is for unifying the coding style for different editors and IDEs.
+; More information at http://editorconfig.org
+
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1760e75
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,36 @@
+# CSS and JS maps
+*.js.map
+*.css.map
+
+# npm
+node_modules
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# Tool specific files
+# vim
+*~
+*.swp
+*.swo
+# sublime text & textmate
+*.sublime-*
+*.stTheme.cache
+*.tmlanguage.cache
+*.tmPreferences.cache
+# Eclipse
+.settings/*
+# JetBrains, aka PHPStorm, IntelliJ IDEA
+.idea/*
+# NetBeans
+nbproject/*
+# Visual Studio Code
+.vscode
+# Sass preprocessor
+.sass-cache/
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..22f54a1
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,13 @@
+{
+ "printWidth": 80,
+ "tabWidth": 2,
+ "useTabs": false,
+ "semi": true,
+ "singleQuote": true,
+ "jsxSingleQuote": true,
+ "quoteProps": "consistent",
+ "trailingComma": "none",
+ "bracketSpacing": true,
+ "jsxBracketSameLine": false,
+ "arrowParens": "always"
+}
diff --git a/Demo/Demo.css b/Demo/Demo.css
deleted file mode 100644
index 1b0ec29..0000000
--- a/Demo/Demo.css
+++ /dev/null
@@ -1,724 +0,0 @@
-
-/* Global */
-
-html {
- height: 100%;
- min-height: 100%;
-}
-
-body {
- position: relative;
- min-height: 100%;
- font-family: 'Helvetica Neue', 'Segoe UI', Arial, sans-serif;
- font-size: 17px;
- line-height: 1.4;
- color: #202428;
- background: #fff;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-main {
- padding: 20px 0;
-}
-
-.container {
- position: relative;
- width: calc(100% - 60px);
- max-width: 1000px;
- margin: auto;
-}
-
-h2 {
- font-size: 22px;
- font-weight: normal;
-}
-
-@media (max-width: 768px) {
-
- .container {
- width: calc(100% - 30px);
- }
-
-}
-
-/* Target elements */
-
-.targets-wrapper {
- margin: 0 -5px;
- padding: 10px 0 20px;
-}
-
-.targets-wrapper:after,
-.targets-wrapper:before {
- content: " ";
- display: table;
-}
-
-.targets-wrapper:after {
- clear: both;
-}
-
-.target,
-.target-click,
-.target-notice {
- cursor: default;
- font-size: 13px;
- line-height: 52px;
- height: 52px;
- border-radius: 2px;
- border: 1px solid #e2e2e2;
- text-align: center;
- background: #fafafa;
- position: relative;
- text-transform: uppercase;
- float: left;
- width: calc(25% - 10px);
- margin: 5px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-.target-click,
-.target-notice {
- cursor: pointer;
-}
-
-.target.active,
-.target-click.active,
-.target-notice.active {
- color: #07d;
-}
-
-.demo-img {
- float: left;
- width: calc(25% - 10px);
- margin: 5px;
-}
-
-.demo-img > img {
- border: 4px solid #eee;
- border-radius: 2px;
- width: 100%;
- height: auto;
- filter: grayscale(100%);
- transition: filter .2s, border-color .2s;
-}
-
-.demo-img:hover > img {
- filter: none;
- border-color: #ddd;
-}
-
-@media (max-width: 768px) {
-
- .target,
- .target-click,
- .target-notice {
- width: calc(50% - 10px);
- }
-
- .demo-img > img {
- border-width: 2px;
- }
-
-}
-
-/* jBox styles */
-
-.ajax-sending {
- color: #07d;
-}
-
-.ajax-complete {
- color: #6c0;
-}
-
-.ajax-success tt {
- color: #666;
- display: block;
- padding-top: 10px;
- font-size: 13px;
-}
-
-.ajax-error {
- color: #d00;
-}
-
-/* Header */
-
-header {
- height: 50px;
- line-height: 50px;
- font-size: 17px;
- background: #262c33;
- color: #99a3ad;
- box-shadow: 0 0 4px rgba(0, 0, 0, .6);
-}
-
-header a {
- margin-right: 20px;
- color: #99a3ad;
- text-decoration: none;
-}
-
-header a:last-child,
-header a:nth-child(3) {
- margin-right: 0;
-}
-
-header a.active,
-header a:hover {
- color: #fff;
- text-decoration: none;
-}
-
-#stephan {
- display: block;
- position: absolute;
- top: 50%;
- right: 0;
- width: 40px;
- height: 40px;
- margin-top: -20px;
- border-radius: 3px;
- background: no-repeat -3px -2px url(https://stephanwagner.me/img/stephan.jpg);
- background-size: 50px;
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, .3);
-}
-
-#stephan > span {
- font-size: 0;
- line-height: 0;
- white-space: nowrap;
- position: absolute;
- top: 50%;
- right: 50%;
- pointer-events: none;
- transition: font-size .2s, margin .2s, opacity .2s, line-height .2s;
- opacity: 0;
-}
-
-#stephan:hover > span {
- opacity: 1;
- font-size: 17px;
- margin-right: 40px;
-}
-
-@media (max-width: 500px) {
-
- #stephan > span {
- display: none;
- }
-
-}
-
-/* Common */
-
-.truncate {
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
-}
-
-.noselect {
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-.clearfix:after,
-.clearfix:before {
- content: " ";
- display: table;
-}
-
-.clearfix:after {
- clear: both;
-}
-
-/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS and IE text size adjust after device orientation change,
- * without disabling user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -ms-text-size-adjust: 100%; /* 2 */
- -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* HTML5 display definitions
- ========================================================================== */
-
-/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-main,
-menu,
-nav,
-section,
-summary {
- display: block;
-}
-
-/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
- */
-
-audio,
-canvas,
-progress,
-video {
- display: inline-block; /* 1 */
- vertical-align: baseline; /* 2 */
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
- display: none;
-}
-
-/* Links
- ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
- background-color: transparent;
-}
-
-/**
- * Improve readability of focused elements when they are also in an
- * active/hover state.
- */
-
-a:active,
-a:hover {
- outline: 0;
-}
-
-/* Text-level semantics
- ========================================================================== */
-
-/**
- * Address inconsistent styling of `abbr[title]`.
- * 1. Correct styling in Firefox 39 and Opera 12.
- * 2. Correct missing styling in Chrome, Edge, IE, Opera, and Safari.
- */
-
-abbr[title] {
- border-bottom: none; /* 1 */
- text-decoration: underline; /* 2 */
- text-decoration: underline dotted; /* 2 */
-}
-
-/**
- * Address inconsistent styling of b and strong.
- * 1. Correct duplicate application of `bolder` in Safari 6.0.2.
- * 2. Correct style set to `bold` in Edge 12+, Safari 6.2+, and Chrome 18+.
- */
-
-b,
-strong {
- font-weight: inherit; /* 1 */
-}
-
-b,
-strong {
- font-weight: bolder; /* 2 */
-}
-
-/**
- * Address styling not present in Safari and Chrome.
- */
-
-dfn {
- font-style: italic;
-}
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
- */
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
- background-color: #ff0;
- color: #000;
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* Embedded content
- ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9/10.
- */
-
-img {
- border: 0;
-}
-
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* Grouping content
- ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari.
- */
-
-figure {
- margin: 1em 40px;
-}
-
-/**
- * Address inconsistent styling of `hr`.
- * 1. Correct `box-sizing` set to `border-box` in Firefox.
- * 2. Correct `overflow` set to `hidden` in IE 8/9/10/11 and Edge 12.
- */
-
-hr {
- box-sizing: content-box; /* 1 */
- height: 0; /* 1 */
- overflow: visible; /* 2 */
-}
-
-/**
- * Contain overflow in all browsers.
- */
-
-pre {
- overflow: auto;
-}
-
-/**
- * 1. Correct inheritance and scaling of font-size for preformatted text.
- * 2. Address odd `em`-unit font size rendering in all browsers.
- */
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, monospace; /* 1 */
- font-size: 1em; /* 2 */
-}
-
-/* Forms
- ========================================================================== */
-
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
- */
-
-/**
- * 1. Correct font properties not being inherited.
- * 2. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font: inherit; /* 1 */
- margin: 0; /* 2 */
-}
-
-/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
-
-button {
- overflow: visible;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
- */
-
-button,
-select {
- text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
- cursor: default;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/**
- * Restore focus style in Firefox 4+ (unset by a rule above)
- */
-
-button:-moz-focusring,
-input:-moz-focusring {
- outline: 1px dotted ButtonText;
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-input {
- line-height: normal;
-}
-
-/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
- height: auto;
-}
-
-/**
- * Address `appearance` set to `searchfield` in Safari and Chrome.
- */
-
-input[type="search"] {
- -webkit-appearance: textfield;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
- */
-
-textarea {
- overflow: auto;
-}
-
-/**
- * Restore font weight (unset by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
- */
-
-optgroup {
- font-weight: bold;
-}
-
-/* Reset */
-
-html, body,
-ul, ol, li,
-h1, h2, h3, h4, h5, h6,
-form, table, tr, td,
-div, p, img, pre, iframe {
- margin: 0;
- padding: 0;
- border: 0;
-}
-
-input, textarea, button, select {
- margin: 0;
-}
-
-textarea, img {
- display: block;
-}
-
-html, body {
- min-width: 100%;
- min-height: 100%;
-}
-
-header, nav, footer, section, img {
- display: block;
-}
-
-ul, ol {
- list-style: none;
-}
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-td {
- vertical-align: top;
-}
-
-h1, h2, h3, h4, h5, h6 {
- font-weight: normal;
-}
-
-* {
- outline: none;
- box-sizing: border-box;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
- -webkit-text-size-adjust: none;
-}
-
-input::-moz-focus-inner,
-button::-moz-focus-inner {
- border: 0;
-}
diff --git a/Demo/Demo.html b/Demo/Demo.html
deleted file mode 100644
index 878a735..0000000
--- a/Demo/Demo.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-jBox Demos
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Tooltip
-
-
-
Hover me
-
Hover me
-
Hover me
-
Hover me
-
Hover me
-
Hover me
-
Click me
-
Click me
-
-
-Modal
-
-
-
Click me
-
Click me
-
Click me
-
Click me
-
-
-Notice
-
-
-
Click me
-
Click me
-
Click me
-
Click me
-
-
-Image
-
-
-
-Playground
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..51cda56
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Stephan Wagner
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index f7776ec..87f4ca8 100755
--- a/README.md
+++ b/README.md
@@ -6,6 +6,30 @@ Demo: https://stephanwagner.me/jBox
Docs: https://stephanwagner.me/jBox/documentation
+---
+
+## Install
+
+### ES6
+
+```bash
+npm install --save jbox
+```
+
+```javascript
+import jBox from 'jbox';
+import 'jbox/dist/jBox.all.css';
+```
+
+### CDN
+
+```html
+
+
+
+```
+
+---
## Tooltips
@@ -24,6 +48,8 @@ Now elements with `class="tooltip"` will open tooltips:
Hover me!
```
+---
+
## Modal windows
You can set up modal windows the same way as tooltips.
@@ -38,10 +64,12 @@ new jBox('Modal', {
content: 'Hello there! '
});
```
+
```html
Click me to open a modal window!
```
+---
## Confirm windows
@@ -54,11 +82,14 @@ new jBox('Confirm', {
cancelButton: 'Nope'
});
```
+
```html
Click me!
Click me!
```
+---
+
## Notices
A notice will open automatically and destroy itself after some time:
@@ -69,6 +100,8 @@ new jBox('Notice', {
});
```
+---
+
## Images
To create image windows you only need following few lines:
@@ -76,10 +109,15 @@ To create image windows you only need following few lines:
```javascript
new jBox('Image');
```
+
```html
-
+
+
+
```
+---
+
## Learn more
These few examples are very basic.
diff --git a/Source/jBox.js b/Source/jBox.js
deleted file mode 100644
index f5222f9..0000000
--- a/Source/jBox.js
+++ /dev/null
@@ -1,1798 +0,0 @@
-/**
- * jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
- *
- * Author: Stephan Wagner (https://stephanwagner.me)
- *
- * License: MIT (https://opensource.org/licenses/MIT)
- *
- * Requires: jQuery 3.1.1 (https://code.jquery.com/jquery-3.1.1.min.js)
- *
- * Documentation: https://stephanwagner.me/jBox/documentation
- *
- * Demos: https://stephanwagner.me/jBox/demos
- */
-
-function jBox(type, options) {
-
-
- // Options (https://stephanwagner.me/jBox/options)
-
- this.options = {
-
- // jBox ID
- id: null, // Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...)
-
- // Dimensions
- width: 'auto', // The width of the content area, e.g. 'auto', 200, '80%'
- height: 'auto', // The height of the content area
- minWidth: null, // Minimal width
- minHeight: null, // Minimal height
- maxWidth: null, // Maximal width
- maxHeight: null, // Maximal height
-
- // Responsive dimensions
- responsiveWidth: true, // Adjusts the width to fit the viewport
- responsiveHeight: true, // Adjusts the height to fit the viewport
- responsiveMinWidth: 100, // Don't adjust width below this value (in pixel)
- responsiveMinHeight: 100, // Don't adjust height below this value (in pixel)
-
- // Attach
- attach: null, // A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip'
- trigger: 'click', // The event to open or close your jBox, use 'click', 'touchclick' or 'mouseenter'
- preventDefault: false, // Prevent the default event when opening jBox, e.g. don't follow the href in a link
-
- // Content
- content: null, // You can use HTML or a jQuery element, e.g. jQuery('#jBox-content'). The elements will be appended to the content element and then made visible, so hide them with style="display: none" beforehand
- getContent: null, // Get the content from an attribute when jBox opens, e.g. getContent: 'data-content'. Use 'html' to get the attached elements HTML as content
- title: null, // Adds a title to your jBox
- getTitle: null, // Get the title from an attribute when jBox opens, e.g. getTitle: 'data-title'
- footer: null, // Adds a footer to your jBox
- isolateScroll: true, // Isolates scrolling to the content container
-
- // AJAX
- ajax: { // Setting an URL will make an AJAX request when jBox opens. Optional you can add any jQuery AJAX option (http://api.jquery.com/jquery.ajax/)
- url: null, // The URL to send the AJAX request to
- data: '', // Data to send with your AJAX request, e.g. {id: 82, limit: 10}
- reload: false, // Resend the AJAX request when jBox opens. Use true to send the AJAX request only once for every attached element or 'strict' to resend every time jBox opens
- getURL: 'data-url', // The attribute in the source element where the AJAX request will look for the URL, e.g. data-url="https://ajaxresponse.com"
- getData: 'data-ajax', // The attribute in the source element where the AJAX request will look for the data, e.g. data-ajax="id=82&limit=10"
- setContent: true, // Automatically set the response as new content when the AJAX request is finished
- spinner: true, // Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '
'
- spinnerDelay: 300, // Milliseconds to wait until spinner appears
- spinnerReposition: true // Repositions jBox when the spinner is added or removed
- },
-
- // Position
- target: null, // The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target
- position: {
- x: 'center', // Horizontal position, use a number, 'left', 'right' or 'center'
- y: 'center' // Vertical position, use a number, 'top', 'bottom' or 'center'
- },
- outside: null, // Use 'x', 'y', or 'xy' to move your jBox outside of the target element
- offset: 0, // Offset to final position, you can set different values for x and y with an object, e.g. {x: 20, y: 10}
- attributes: { // Note that attributes can only be 'left' or 'right' when using numbers for position, e.g. {x: 300, y: 20}
- x: 'left', // Horizontal position, use 'left' or 'right'
- y: 'top' // Vertical position, use 'top' or 'bottom'
- },
- fixed: false, // Your jBox will stay on position when scrolling
- adjustPosition: true, // Adjusts your jBoxes position if there is not enough space, use 'flip', 'move' or true for both. This option overrides the reposition options
- adjustTracker: false, // By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling
- adjustDistance: 5, // The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5}
- reposition: true, // Calculates new position when the window-size changes
- repositionOnOpen: true, // Calculates new position each time jBox opens (rather than only when it opens the first time)
- repositionOnContent: true, // Calculates new position when the content changes with .setContent() or .setTitle()
-
- // Pointer
- pointer: false, // Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20'
- pointTo: 'target', // Setting something else than 'target' will add a pointer even if there is no target element set or found. Use 'top', 'right', 'bottom' or 'left'
-
- // Animations
- fade: 180, // Fade duration in ms, set to 0 or false to disable
- animation: null, // Animation when opening or closing, use 'pulse', 'zoomIn', 'zoomOut', 'move', 'slide', 'flip', 'tada' (CSS inspired from Daniel Edens Animate.css: http://daneden.me/animate)
-
- // Appearance
- theme: 'Default', // Set a jBox theme class
- addClass: null, // Adds classes to the wrapper
- overlay: false, // Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS)
- zIndex: 10000, // Use a high z-index
-
- // Delays
- delayOpen: 0, // Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing
- delayClose: 0, // Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away
-
- // Closing
- closeOnEsc: false, // Close jBox when pressing [esc] key
- closeOnClick: false, // Close jBox with mouseclick. Use true (click anywhere), 'box' (click on jBox itself), 'overlay' (click on the overlay), 'body' (click anywhere but jBox)
- closeOnMouseleave: false, // Close jBox when the mouse leaves the jBox area or the area of the attached element
- closeButton: false, // Adds a close button to your jBox. Use 'title', 'box', 'overlay' or true (true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found)
-
- // Other options
- appendTo: jQuery('body'), // The element your jBox will be appended to. Any other element than jQuery('body') is only useful for fixed positions or when position values are numbers
- createOnInit: false, // Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time
- blockScroll: false, // Blocks scrolling when jBox is open
- draggable: false, // Make your jBox draggable (use 'true', 'title' or provide an element as handle) (inspired from Chris Coyiers CSS-Tricks http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/)
- dragOver: true, // When you have multiple draggable jBoxes, the one you select will always move over the other ones
- autoClose: false, // Time in ms when jBox will close automatically after it was opened
-
- // Audio // You can use the integrated audio function whenever you'd like to play an audio file, e.g. onInit: function () { this.audio('url_to_audio_file_without_file_extension', 75); }
- preloadAudio: true, // Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg']
- audio: null, // The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'}
- volume: 100, // The volume in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100}
-
- // Events // Note that you can use 'this' in all event functions, it refers to your jBox object (e.g. onInit: function () { this.open(); })
- onInit: null, // Fired when jBox is initialized
- onAttach: null, // Fired when jBox attached itself to elements, the attached element will be passed as a parameter, e.g. onAttach: function (element) { element.css({color: 'red'}); }
- onPosition: null, // Fired when jBox is positioned
- onCreated: null, // Fired when jBox is created and availible in DOM
- onOpen: null, // Fired when jBox opens
- onClose: null, // Fired when jBox closes
- onCloseComplete: null // Fired when jBox is completely closed (when fading is finished)
- };
-
-
- // Default plugin options
-
- this._pluginOptions = {
-
- // Default options for tooltips
- 'Tooltip': {
- getContent: 'title',
- trigger: 'mouseenter',
- position: {
- x: 'center',
- y: 'top'
- },
- outside: 'y',
- pointer: true
- },
-
- // Default options for mouse tooltips
- 'Mouse': {
- responsiveWidth: false,
- responsiveHeight: false,
- adjustPosition: 'flip',
- target: 'mouse',
- trigger: 'mouseenter',
- position: {
- x: 'right',
- y: 'bottom'
- },
- outside: 'xy',
- offset: 5
- },
-
- // Default options for modal windows
- 'Modal': {
- target: jQuery(window),
- fixed: true,
- blockScroll: true,
- closeOnEsc: true,
- closeOnClick: 'overlay',
- closeButton: true,
- overlay: true,
- animation: 'zoomIn'
- },
- };
-
-
- // Merge options
-
- this.options = jQuery.extend(true, this.options, this._pluginOptions[type] ? this._pluginOptions[type] : jBox._pluginOptions[type], options);
-
-
- // Set the jBox type
-
- jQuery.type(type) == 'string' && (this.type = type);
-
-
- // Local function to fire events
-
- this._fireEvent = function (event, pass)
- {
- this.options['_' + event] && (this.options['_' + event].bind(this))(pass);
- this.options[event] && (this.options[event].bind(this))(pass);
- };
-
-
- // Get a unique jBox ID
-
- this.options.id === null && (this.options.id = 'jBox' + jBox._getUniqueID());
- this.id = this.options.id;
-
-
- // Correct impossible options
-
- ((this.options.position.x == 'center' && this.options.outside == 'x') || (this.options.position.y == 'center' && this.options.outside == 'y')) && (this.options.outside = null);
- this.options.pointTo == 'target' && (!this.options.outside || this.options.outside == 'xy') && (this.options.pointer = false);
-
-
- // Correct multiple choice options
-
- jQuery.type(this.options.offset) != 'object' ? (this.options.offset = {x: this.options.offset, y: this.options.offset}) : (this.options.offset = jQuery.extend({x: 0, y: 0}, this.options.offset));
- jQuery.type(this.options.adjustDistance) != 'object' ? (this.options.adjustDistance = {top: this.options.adjustDistance, right: this.options.adjustDistance, bottom: this.options.adjustDistance, left: this.options.adjustDistance}) : (this.options.adjustDistance = jQuery.extend({top: 5, left: 5, right: 5, bottom: 5}, this.options.adjustDistance));
-
-
- // Save default outside position
-
- this.outside = this.options.outside && this.options.outside != 'xy' ? this.options.position[this.options.outside] : false;
-
-
- // Save where the jBox is aligned to
-
- this.align = this.outside ? this.outside : (this.options.position.y != 'center' && jQuery.type(this.options.position.y) != 'number' ? this.options.position.x : (this.options.position.x != 'center' && jQuery.type(this.options.position.x) != 'number' ? this.options.position.y : this.options.attributes.x));
-
-
- // Internal positioning functions
-
- this._getOpp = function (opp) { return {left: 'right', right: 'left', top: 'bottom', bottom: 'top', x: 'y', y: 'x'}[opp]; };
- this._getXY = function (xy) { return {left: 'x', right: 'x', top: 'y', bottom: 'y', center: 'x'}[xy]; };
- this._getTL = function (tl) { return {left: 'left', right: 'left', top: 'top', bottom: 'top', center: 'left', x: 'left', y: 'top'}[tl]; };
-
-
- // Get a dimension value in integer pixel dependent on appended element
-
- this._getInt = function (value, dimension) {
- if (value == 'auto') return 'auto';
- if (value && jQuery.type(value) == 'string' && value.slice(-1) == '%') {
- return jQuery(window)[dimension == 'height' ? 'innerHeight' : 'innerWidth']() * parseInt(value.replace('%', '')) / 100;
- }
- return value;
- };
-
-
- // Create an svg element
-
- this._createSVG = function (type, options)
- {
- var svg = document.createElementNS('http://www.w3.org/2000/svg', type);
- jQuery.each(options, function (index, item) {
- svg.setAttribute(item[0], (item[1] || ''));
- });
- return svg;
- };
-
-
- // Isolate scrolling in a container
-
- this._isolateScroll = function (el)
- {
- // Abort if element not found
- if (!el || !el.length) return;
-
- el.on('DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll', function (ev) {
- var delta = ev.wheelDelta || (ev.originalEvent && ev.originalEvent.wheelDelta) || -ev.detail;
- var overflowBottom = this.scrollTop + el.outerHeight() - this.scrollHeight >= 0;
- var overflowTop = this.scrollTop <= 0;
- ((delta < 0 && overflowBottom) || (delta > 0 && overflowTop)) && ev.preventDefault();
- });
- };
-
-
- // Set the title width to content width
-
- this._setTitleWidth = function ()
- {
- // Abort if there is no title or width of content is auto
- if (!this.titleContainer || (this.content[0].style.width == 'auto' && !this.content[0].style.maxWidth)) return null;
-
- // Expose wrapper to get actual width
- if (this.wrapper.css('display') == 'none') {
- this.wrapper.css('display', 'block');
- var contentWidth = this.content.outerWidth();
- this.wrapper.css('display', 'none');
- } else {
- var contentWidth = this.content.outerWidth();
- }
-
- // Set max-width only
- this.titleContainer.css({maxWidth: (Math.max(contentWidth, parseInt(this.content[0].style.maxWidth)) || null)});
- }
-
-
- // Make jBox draggable
-
- this._draggable = function ()
- {
- // Abort if jBox is not draggable
- if (!this.options.draggable) return false;
-
- // Get the handle where jBox will be dragged with
- var handle = this.options.draggable == 'title' ? this.titleContainer : (this.options.draggable instanceof jQuery ? this.options.draggable : (jQuery.type(this.options.draggable) == 'string' ? jQuery(this.options.draggable) : this.wrapper));
-
- // Abort if no handle or if draggable was set already
- if (!handle || !(handle instanceof jQuery) || !handle.length || handle.data('jBox-draggable')) return false;
-
- // Add mouse events
- handle.addClass('jBox-draggable').data('jBox-draggable', true).on('mousedown', function (ev)
- {
- if (ev.button == 2 || jQuery(ev.target).hasClass('jBox-noDrag') || jQuery(ev.target).parents('.jBox-noDrag').length) return;
-
- // Adjust z-index when dragging jBox over another draggable jBox
- if (this.options.dragOver && this.wrapper.css('zIndex') <= jBox.zIndexMax) {
- jBox.zIndexMax += 1;
- this.wrapper.css('zIndex', jBox.zIndexMax);
- }
-
- var drg_h = this.wrapper.outerHeight();
- var drg_w = this.wrapper.outerWidth();
- var pos_y = this.wrapper.offset().top + drg_h - ev.pageY;
- var pos_x = this.wrapper.offset().left + drg_w - ev.pageX;
-
- jQuery(document).on('mousemove.jBox-draggable-' + this.id, function (ev) {
- this.wrapper.offset({
- top: ev.pageY + pos_y - drg_h,
- left: ev.pageX + pos_x - drg_w
- });
- }.bind(this));
- ev.preventDefault();
-
- }.bind(this)).on('mouseup', function () { jQuery(document).off('mousemove.jBox-draggable-' + this.id); }.bind(this));
-
- // Get highest z-index
- jBox.zIndexMax = !jBox.zIndexMax ? this.options.zIndex : Math.max(jBox.zIndexMax, this.options.zIndex);
-
-
-
- return this;
- };
-
- // Create jBox
-
- this._create = function ()
- {
- // Abort if jBox was created already
- if (this.wrapper) return;
-
- // Create wrapper
- this.wrapper = jQuery('
', {
- id: this.id,
- 'class': 'jBox-wrapper' + (this.type ? ' jBox-' + this.type : '') + (this.options.theme ? ' jBox-' + this.options.theme : '') + (this.options.addClass ? ' ' + this.options.addClass : '')
- }).css({
- position: (this.options.fixed ? 'fixed' : 'absolute'),
- display: 'none',
- opacity: 0,
- zIndex: this.options.zIndex
-
- // Save the jBox instance in the wrapper, so you can get access to your jBox when you only have the element
- }).data('jBox', this);
-
- // Add mouseleave event, only close jBox when the new target is not the source element
- this.options.closeOnMouseleave && this.wrapper.on('mouseleave', function (ev) {
- !this.source || !(ev.relatedTarget == this.source[0] || jQuery.inArray(this.source[0], jQuery(ev.relatedTarget).parents('*')) !== -1) && this.close();
- }.bind(this));
-
- // Add closeOnClick: 'box' events
- (this.options.closeOnClick == 'box') && this.wrapper.on('touchend click', function () { this.close({ignoreDelay: true}); }.bind(this));
-
- // Create container
- this.container = jQuery('
').appendTo(this.wrapper);
-
- // Create content
- this.content = jQuery('
').appendTo(this.container);
-
- // Create footer
- this.options.footer && (this.footer = jQuery('').append(this.options.footer).appendTo(this.container));
-
- // Isolate scrolling
- this.options.isolateScroll && this._isolateScroll(this.content);
-
- // Create close button
- if (this.options.closeButton) {
- var closeButtonSVG = this._createSVG('svg', [['viewBox', '0 0 24 24']]);
- closeButtonSVG.appendChild(this._createSVG('path', [['d', 'M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z']]));
- this.closeButton = jQuery('
').on('touchend click', function (ev) { this.close({ignoreDelay: true}); }.bind(this)).append(closeButtonSVG);
-
- // Add close button to jBox container
- if (this.options.closeButton == 'box' || (this.options.closeButton === true && !this.options.overlay && !this.options.title)) {
- this.wrapper.addClass('jBox-closeButton-box');
- this.closeButton.appendTo(this.container);
- }
- }
-
- // Append jBox to DOM
- this.wrapper.appendTo(this.options.appendTo);
-
- // Fix adjustDistance if there is a close button in the box
- this.wrapper.find('.jBox-closeButton').length && jQuery.each(['top', 'right', 'bottom', 'left'], function (index, pos) {
- this.wrapper.find('.jBox-closeButton').css(pos) && this.wrapper.find('.jBox-closeButton').css(pos) != 'auto' && (this.options.adjustDistance[pos] = Math.max(this.options.adjustDistance[pos], this.options.adjustDistance[pos] + (((parseInt(this.wrapper.find('.jBox-closeButton').css(pos)) || 0) + (parseInt(this.container.css('border-' + pos + '-width')) || 0)) * -1)));
- }.bind(this));
-
- // Create pointer
- if (this.options.pointer) {
-
- // Get pointer vars and save globally
- this.pointer = {
- position: (this.options.pointTo != 'target') ? this.options.pointTo : this._getOpp(this.outside),
- xy: (this.options.pointTo != 'target') ? this._getXY(this.options.pointTo) : this._getXY(this.outside),
- align: 'center',
- offset: 0
- };
-
- this.pointer.element = jQuery('
').appendTo(this.wrapper);
- this.pointer.dimensions = {
- x: this.pointer.element.outerWidth(),
- y: this.pointer.element.outerHeight()
- };
-
- if (jQuery.type(this.options.pointer) == 'string') {
- var split = this.options.pointer.split(':');
- split[0] && (this.pointer.align = split[0]);
- split[1] && (this.pointer.offset = parseInt(split[1]));
- }
- this.pointer.alignAttribute = (this.pointer.xy == 'x' ? (this.pointer.align == 'bottom' ? 'bottom' : 'top') : (this.pointer.align == 'right' ? 'right' : 'left'));
-
- // Set wrapper CSS
- this.wrapper.css('padding-' + this.pointer.position, this.pointer.dimensions[this.pointer.xy]);
-
- // Set pointer CSS
- this.pointer.element.css(this.pointer.alignAttribute, (this.pointer.align == 'center' ? '50%' : 0)).css('margin-' + this.pointer.alignAttribute, this.pointer.offset);
- this.pointer.margin = {};
- this.pointer.margin['margin-' + this.pointer.alignAttribute] = this.pointer.offset;
-
- // Add a transform to fix centered position
- (this.pointer.align == 'center') && this.pointer.element.css('transform', 'translate(' + (this.pointer.xy == 'y' ? (this.pointer.dimensions.x * -0.5 + 'px') : 0) + ', ' + (this.pointer.xy == 'x' ? (this.pointer.dimensions.y * -0.5 + 'px') : 0) + ')');
-
- this.pointer.element.css((this.pointer.xy == 'x' ? 'width' : 'height'), parseInt(this.pointer.dimensions[this.pointer.xy]) + parseInt(this.container.css('border-' + this.pointer.alignAttribute + '-width')));
-
- // Add class to wrapper for CSS access
- this.wrapper.addClass('jBox-pointerPosition-' + this.pointer.position);
- }
-
- // Set title and content
- this.setContent(this.options.content, true);
- this.setTitle(this.options.title, true);
-
- this.options.draggable && this._draggable();
-
- // Fire onCreated event
- this._fireEvent('onCreated');
- };
-
-
- // Create jBox onInit
-
- this.options.createOnInit && this._create();
-
-
- // Attach jBox
-
- this.options.attach && this.attach();
-
-
- // Attach document and window events
-
- this._attachEvents = function ()
- {
- // Closing event: closeOnEsc
- this.options.closeOnEsc && jQuery(document).on('keyup.jBox-' + this.id, function (ev) { if (ev.keyCode == 27) { this.close({ignoreDelay: true}); }}.bind(this));
-
- // Closing event: closeOnClick
- if (this.options.closeOnClick === true || this.options.closeOnClick == 'body') {
- jQuery(document).on('touchend.jBox-' + this.id + ' click.jBox-' + this.id, function (ev) {
- if (this.blockBodyClick || (this.options.closeOnClick == 'body' && (ev.target == this.wrapper[0] || this.wrapper.has(ev.target).length))) return;
- this.close({ignoreDelay: true});
- }.bind(this));
- }
-
- // Positioning events
- if ((this.options.adjustPosition || this.options.reposition) && !this.fixed && this.outside) {
-
- // Trigger position events when scrolling
- this.options.adjustTracker && jQuery(window).on('scroll.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
-
- // Trigger position events when resizing
- (this.options.adjustPosition || this.options.reposition) && jQuery(window).on('resize.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
- }
-
- // Mousemove events
- this.options.target == 'mouse' && jQuery('body').on('mousemove.jBox-' + this.id, function (ev) { this.position({mouseTarget: {top: ev.pageY, left: ev.pageX}}); }.bind(this));
- };
-
-
- // Detach document and window events
-
- this._detachEvents = function ()
- {
- // Closing event: closeOnEsc
- this.options.closeOnEsc && jQuery(document).off('keyup.jBox-' + this.id);
-
- // Closing event: closeOnClick
- (this.options.closeOnClick === true || this.options.closeOnClick == 'body') && jQuery(document).off('touchend.jBox-' + this.id + ' click.jBox-' + this.id);
-
- // Positioning events
- this.options.adjustTracker && jQuery(window).off('scroll.jBox-' + this.id);
- (this.options.adjustPosition || this.options.reposition) && jQuery(window).off('resize.jBox-' + this.id);
-
- // Mousemove events
- this.options.target == 'mouse' && jQuery('body').off('mousemove.jBox-' + this.id);
- };
-
-
- // Show overlay
-
- this._showOverlay = function ()
- {
- // Create the overlay if wasn't created already
- if (!this.overlay) {
-
- // Create element and append to the element where jBox is appended to
- this.overlay = jQuery('
').addClass('jBox-overlay' + (this.type ? ' jBox-overlay-' + this.type : '')).css({
- display: 'none',
- opacity: 0,
- zIndex: this.options.zIndex - 1
- }).appendTo(this.options.appendTo);
-
- // Add close button to overlay
- (this.options.closeButton == 'overlay' || (this.options.closeButton === true && !this.titleContainer)) && this.overlay.append(this.closeButton);
-
- // Add closeOnClick: 'overlay' events
- this.options.closeOnClick == 'overlay' && this.overlay.on('touchend click', function () { this.close({ignoreDelay: true}); }.bind(this));
-
- // Adjust option adjustDistance if there is a close button in the overlay
- jQuery('#' + this.id + '-overlay .jBox-closeButton').length && (this.options.adjustDistance.top = Math.max(jQuery('#' + this.id + '-overlay .jBox-closeButton').outerHeight(), this.options.adjustDistance.top));
- }
-
- // Abort if overlay is already visible
- if (this.overlay.css('display') == 'block') return;
-
- // Show overlay
- this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 1}, {
- queue: false,
- duration: this.options.fade,
- start: function () { this.overlay.css({display: 'block'}); }.bind(this)
- })) : this.overlay.css({display: 'block', opacity: 1});
- };
-
-
- // Hide overlay
-
- this._hideOverlay = function ()
- {
- // Abort if the overlay wasn't created yet
- if (!this.overlay) return;
-
- // Hide overlay if no other jBox needs it
- this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 0}, {
- queue: false,
- duration: this.options.fade,
- complete: function () { this.overlay.css({display: 'none'}); }.bind(this)
- })) : this.overlay.css({display: 'none', opacity: 0});
- };
-
-
- // Get the correct jBox dimensions by moving jBox out of viewport
-
- this._exposeDimensions = function ()
- {
- // Move wrapper out of viewport
- this.wrapper.css({
- top: -10000,
- left: -10000,
- right: 'auto',
- bottom: 'auto'
- });
-
- // Get jBox dimensions
- var jBoxDimensions = {
- x: this.wrapper.outerWidth(),
- y: this.wrapper.outerHeight()
- };
-
- // Reset position to viewport
- this.wrapper.css({
- top: 'auto',
- left: 'auto'
- });
-
- return jBoxDimensions;
- };
-
-
- // Generate CSS for animations and append to header
-
- this._generateAnimationCSS = function ()
- {
- // Get open and close animations if none provided
- (jQuery.type(this.options.animation) != 'object') && (this.options.animation = {
- pulse: {open: 'pulse', close: 'zoomOut'},
- zoomIn: {open: 'zoomIn', close: 'zoomIn'},
- zoomOut: {open: 'zoomOut', close: 'zoomOut'},
- move: {open: 'move', close: 'move'},
- slide: {open: 'slide', close: 'slide'},
- flip: {open: 'flip', close: 'flip'},
- tada: {open: 'tada', close: 'zoomOut'}
- }[this.options.animation]);
-
- // Abort if animation not found
- if (!this.options.animation) return null;
-
- // Get direction var
- this.options.animation.open && (this.options.animation.open = this.options.animation.open.split(':'));
- this.options.animation.close && (this.options.animation.close = this.options.animation.close.split(':'));
- this.options.animation.openDirection = this.options.animation.open[1] ? this.options.animation.open[1] : null;
- this.options.animation.closeDirection = this.options.animation.close[1] ? this.options.animation.close[1] : null;
- this.options.animation.open && (this.options.animation.open = this.options.animation.open[0]);
- this.options.animation.close && (this.options.animation.close = this.options.animation.close[0]);
-
- // Add 'Open' and 'Close' to animation names
- this.options.animation.open && (this.options.animation.open += 'Open');
- this.options.animation.close && (this.options.animation.close += 'Close');
-
- // All animations
- var animations = {
- pulse: {
- duration: 350,
- css: [['0%', 'scale(1)'], ['50%', 'scale(1.1)'], ['100%', 'scale(1)']]
- },
- zoomInOpen: {
- duration: (this.options.fade || 180),
- css: [['0%', 'scale(0.9)'], ['100%', 'scale(1)']]
- },
- zoomInClose: {
- duration: (this.options.fade || 180),
- css: [['0%', 'scale(1)'], ['100%', 'scale(0.9)']]
- },
- zoomOutOpen: {
- duration: (this.options.fade || 180),
- css: [['0%', 'scale(1.1)'], ['100%', 'scale(1)']]
- },
- zoomOutClose: {
- duration: (this.options.fade || 180),
- css: [['0%', 'scale(1)'], ['100%', 'scale(1.1)']]
- },
- moveOpen: {
- duration: (this.options.fade || 180),
- positions: {top: {'0%': -12}, right: {'0%': 12}, bottom: {'0%': 12}, left: {'0%': -12}},
- css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
- },
- moveClose: {
- duration: (this.options.fade || 180),
- timing: 'ease-in',
- positions: {top: {'100%': -12}, right: {'100%': 12}, bottom: {'100%': 12}, left: {'100%': -12}},
- css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
- },
- slideOpen: {
- duration: 400,
- positions: {top: {'0%': -400}, right: {'0%': 400}, bottom: {'0%': 400}, left: {'0%': -400}},
- css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
- },
- slideClose: {
- duration: 400,
- timing: 'ease-in',
- positions: {top: {'100%': -400}, right: {'100%': 400}, bottom: {'100%': 400}, left: {'100%': -400}},
- css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
- },
- flipOpen: {
- duration: 600,
- css: [['0%', 'perspective(400px) rotateX(90deg)'], ['40%', 'perspective(400px) rotateX(-15deg)'], ['70%', 'perspective(400px) rotateX(15deg)'], ['100%', 'perspective(400px) rotateX(0deg)']]
- },
- flipClose: {
- duration: (this.options.fade || 300),
- css: [['0%', 'perspective(400px) rotateX(0deg)'], ['100%', 'perspective(400px) rotateX(90deg)']]
- },
- tada: {
- duration: 800,
- css: [['0%', 'scale(1)'], ['10%, 20%', 'scale(0.9) rotate(-3deg)'], ['30%, 50%, 70%, 90%', 'scale(1.1) rotate(3deg)'], ['40%, 60%, 80%', 'scale(1.1) rotate(-3deg)'], ['100%', 'scale(1) rotate(0)']]
- }
- };
-
- // Set Open and Close names for standalone animations
- jQuery.each(['pulse', 'tada'], function (index, item) { animations[item + 'Open'] = animations[item + 'Close'] = animations[item]; });
-
- // Function to generate the CSS for the keyframes
- var generateKeyframeCSS = function (ev, position)
- {
- // Generate keyframes CSS
- keyframe_css = '@keyframes jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
- jQuery.each(animations[this.options.animation[ev]].css, function (index, item) {
- var translate = position ? item[1].replace('%XY', this._getXY(position).toUpperCase()) : item[1];
- animations[this.options.animation[ev]].positions && (translate = translate.replace('%V', animations[this.options.animation[ev]].positions[position][item[0]]));
- keyframe_css += item[0] + ' {transform:' + translate + ';}';
- }.bind(this));
- keyframe_css += '}';
-
- // Generate class CSS
- keyframe_css += '.jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
- keyframe_css += 'animation-duration: ' + animations[this.options.animation[ev]].duration + 'ms;';
- keyframe_css += 'animation-name: jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ';';
- keyframe_css += animations[this.options.animation[ev]].timing ? ('animation-timing-function: ' + animations[this.options.animation[ev]].timing + ';') : '';
- keyframe_css += '}';
-
- return keyframe_css;
- }.bind(this);
-
- // Generate css for each event and positions
- this._animationCSS = '';
- jQuery.each(['open', 'close'], function (index, ev)
- {
- // No CSS needed for closing with no fade
- if (!this.options.animation[ev] || !animations[this.options.animation[ev]] || (ev == 'close' && !this.options.fade)) return '';
-
- // Generate CSS
- animations[this.options.animation[ev]].positions ?
- jQuery.each(['top', 'right', 'bottom', 'left'], function (index2, position) { this._animationCSS += generateKeyframeCSS(ev, position); }.bind(this)) :
- this._animationCSS += generateKeyframeCSS(ev);
- }.bind(this));
-
- };
-
-
- // Add css for animations
-
- this.options.animation && this._generateAnimationCSS();
-
-
- // Block body clicks for 10ms to prevent extra event triggering
-
- this._blockBodyClick = function ()
- {
- this.blockBodyClick = true;
- setTimeout(function () { this.blockBodyClick = false; }.bind(this), 10);
- };
-
-
- // Animations
-
- this._animate = function (ev)
- {
- // The event which triggers the animation
- !ev && (ev = this.isOpen ? 'open' : 'close');
-
- // Don't animate when closing with no fade duration
- if (!this.options.fade && ev == 'close') return null;
-
- // Get the current position, use opposite if jBox is flipped
- var animationDirection = (this.options.animation[ev + 'Direction'] || ((this.align != 'center') ? this.align : this.options.attributes.x));
- this.flipped && this._getXY(animationDirection) == (this._getXY(this.align)) && (animationDirection = this._getOpp(animationDirection));
-
- // Add event and position classes
- var classnames = 'jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + ' jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + '-' + animationDirection;
- this.wrapper.addClass(classnames);
-
- // Get duration of animation
- var animationDuration = parseFloat(this.wrapper.css('animation-duration')) * 1000;
- ev == 'close' && (animationDuration = Math.min(animationDuration, this.options.fade));
-
- // Remove animation classes when animation is finished
- setTimeout(function () { this.wrapper.removeClass(classnames); }.bind(this), animationDuration);
- };
-
-
- // Abort an animation
-
- this._abortAnimation = function ()
- {
- // Remove all animation classes
- var classes = this.wrapper.attr('class').split(' ').filter(function (c) {
- return c.lastIndexOf('jBox-' + this.id + '-animation', 0) !== 0;
- }.bind(this));
- this.wrapper.attr('class', classes.join(' '));
- };
-
-
- // Adjust dimensions when browser is resized
-
- if (this.options.responsiveWidth || this.options.responsiveHeight)
- {
- // Responsive positioning overrides options adjustPosition and reposition
- // TODO: Only add this resize event when the other one from adjustPosition and reposition was not set
- jQuery(window).on('resize.responsivejBox-' + this.id, function (ev) { if (this.isOpen) { this.position(); } }.bind(this));
- }
-
-
- // Fix audio options
-
- jQuery.type(this.options.preloadAudio) === 'string' && (this.options.preloadAudio = [this.options.preloadAudio]);
- jQuery.type(this.options.audio) === 'string' && (this.options.audio = {open: this.options.audio});
- jQuery.type(this.options.volume) === 'number' && (this.options.volume = {open: this.options.volume, close: this.options.volume});
-
- if (this.options.preloadAudio === true && this.options.audio) {
- this.options.preloadAudio = [];
- jQuery.each(this.options.audio, function (index, url) {
- this.options.preloadAudio.push(url + '.mp3');
- this.options.preloadAudio.push(url + '.ogg');
- }.bind(this));
- }
-
-
- // Preload audio files
-
- this.options.preloadAudio.length && jQuery.each(this.options.preloadAudio, function (index, url) {
- var audio = new Audio();
- audio.src = url;
- audio.preload = 'auto';
- });
-
-
- // Fire onInit event
-
- this._fireEvent('onInit');
-
-
- return this;
-};
-
-
-// Attach jBox to elements
-
-jBox.prototype.attach = function (elements, trigger)
-{
- // Get elements from options if none passed
- !elements && (elements = this.options.attach);
-
- // Convert selectors to jQuery objects
- jQuery.type(elements) == 'string' && (elements = jQuery(elements))
-
- // Get trigger event from options if not passed
- !trigger && (trigger = this.options.trigger);
-
- // Loop through elements and attach jBox
- elements && elements.length && jQuery.each(elements, function (index, el) {
- el = jQuery(el);
-
- // Only attach if the element wasn't attached to this jBox already
- if (!el.data('jBox-attached-' + this.id)) {
-
- // Remove title attribute and store content on element
- (this.options.getContent == 'title' && el.attr('title') != undefined) && el.data('jBox-getContent', el.attr('title')).removeAttr('title');
-
- // Add Element to collection
- this.attachedElements || (this.attachedElements = []);
- this.attachedElements.push(el[0]);
-
- // Add click or mouseenter event, click events can prevent default as well
- el.on(trigger + '.jBox-attach-' + this.id, function (ev)
- {
- // Clear timer
- this.timer && clearTimeout(this.timer);
-
- // Block opening when jbox is open and the source element is triggering
- if (trigger == 'mouseenter' && this.isOpen && this.source[0] == el[0]) return;
-
- // Only close jBox if you click the current target element, otherwise open at new target
- if (this.isOpen && this.source && this.source[0] != el[0]) var forceOpen = true;
-
- // Set new source element
- this.source = el;
-
- // Set new target
- !this.options.target && (this.target = el);
-
- // Prevent default action on click
- trigger == 'click' && this.options.preventDefault && ev.preventDefault();
-
- // Toggle or open jBox
- this[trigger == 'click' && !forceOpen ? 'toggle' : 'open']();
-
- }.bind(this));
-
- // Add close event for trigger event mouseenter
- (this.options.trigger == 'mouseenter') && el.on('mouseleave', function (ev)
- {
- // Abort if jBox wasn't created yet
- if (!this.wrapper) return null;
-
- // If we have set closeOnMouseleave, do not close jBox when leaving attached element and mouse is over jBox
- if (!this.options.closeOnMouseleave || !(ev.relatedTarget == this.wrapper[0] || jQuery(ev.relatedTarget).parents('#' + this.id).length)) this.close();
- }.bind(this));
-
- // Store
- el.data('jBox-attached-' + this.id, trigger);
-
- // Fire onAttach event
- this._fireEvent('onAttach', el);
- }
-
- }.bind(this));
-
- return this;
-};
-
-
-// Detach jBox from elements
-
-jBox.prototype.detach = function (elements)
-{
- // Get elements from stores elements if none passed
- !elements && (elements = this.attachedElements || []);
-
- elements && elements.length && jQuery.each(elements, function (index, el) {
- el = jQuery(el);
-
- // Remove events
- if (el.data('jBox-attached-' + this.id)) {
- el.off(el.data('jBox-attached-' + this.id) + '.jBox-attach-' + this.id);
- el.data('jBox-attached-' + this.id, null);
- }
- // Remove element from collection
- this.attachedElements = jQuery.grep(this.attachedElements, function (value) {
- return value != el[0];
- });
- }.bind(this));
-
- return this;
-};
-
-
-// Set title
-
-jBox.prototype.setTitle = function (title, ignore_positioning)
-{
- // Abort if title to set
- if (title == null || title == undefined) return this;
-
- // Create jBox if it wasn't created already
- !this.wrapper && this._create();
-
- // Get the width and height of wrapper, only if they change we need to reposition
- var wrapperHeight = this.wrapper.outerHeight();
- var wrapperWidth = this.wrapper.outerWidth();
-
- // Create title elements if they weren't created already
- if (!this.title) {
- this.titleContainer = jQuery('
');
- this.title = jQuery('
').appendTo(this.titleContainer);
- this.wrapper.addClass('jBox-hasTitle');
- if (this.options.closeButton == 'title' || (this.options.closeButton === true && !this.options.overlay)) {
- this.wrapper.addClass('jBox-closeButton-title');
- this.closeButton.appendTo(this.titleContainer);
- }
- this.titleContainer.insertBefore(this.content);
- this._setTitleWidth();
- }
- this.title.html(title);
-
- // Adjust width of title
- wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
-
- // Make jBox draggable
- this.options.draggable && this._draggable();
-
- // Reposition if dimensions changed
- !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
-
- return this;
-};
-
-
-// Set content
-
-jBox.prototype.setContent = function (content, ignore_positioning)
-{
- // Abort if no content to set
- if (content == null || content == undefined) return this;
-
- // Create jBox if it wasn't created already
- !this.wrapper && this._create();
-
- // Get the width and height of wrapper, only if they change we need to reposition
- var wrapperHeight = this.wrapper.outerHeight();
- var wrapperWidth = this.wrapper.outerWidth();
-
- // Move all appended containers to body
- this.content.children('[data-jbox-content-appended]').appendTo('body').css({display: 'none'});
-
- // Set the new content
- switch (jQuery.type(content)) {
- case 'string': this.content.html(content); break;
- case 'object': this.content.html(''); content.attr('data-jbox-content-appended', 1).appendTo(this.content).css({display: 'block'}); break;
- }
-
- // Adjust title width
- wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
-
- // Make jBox draggable
- this.options.draggable && this._draggable();
-
- // Reposition if dimensions changed
- !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
-
- return this;
-};
-
-
-// Set jBox dimensions
-
-jBox.prototype.setDimensions = function (type, value, pos)
-{
- // Create jBox if it wasn't created already
- !this.wrapper && this._create();
-
- // Default value is 'auto'
- value == undefined && (value = 'auto');
-
- // Set CSS of content and title
- this.content.css(type, this._getInt(value));
-
- // Adjust title width
- type == 'width' && this._setTitleWidth();
-
- // Reposition by default
- (pos == undefined || pos) && this.position();
-};
-
-
-// Set jBox width or height
-
-jBox.prototype.setWidth = function (value, pos) { this.setDimensions('width', value, pos); };
-jBox.prototype.setHeight = function (value, pos) { this.setDimensions('height', value, pos); };
-
-
-// Position jBox
-
-jBox.prototype.position = function (options)
-{
- // Options are required
- !options && (options = {});
-
- // Combine passed options with jBox options
- options = jQuery.extend(true, this.options, options);
-
- // Get the target
- this.target = options.target || this.target || jQuery(window);
-
- // Make sure target is a jQuery element
- !(this.target instanceof jQuery || this.target == 'mouse') && (this.target = jQuery(this.target));
-
- // Abort if target is missing
- if (!this.target.length) return this;
-
- // Reset content css to get original dimensions
- this.content.css({
- width: this._getInt(options.width, 'width'),
- height: this._getInt(options.height, 'height'),
- minWidth: this._getInt(options.minWidth, 'width'),
- minHeight: this._getInt(options.minHeight, 'height'),
- maxWidth: this._getInt(options.maxWidth, 'width'),
- maxHeight: this._getInt(options.maxHeight, 'height'),
- });
-
- // Reset width of title
- this._setTitleWidth();
-
- // Get jBox dimensions
- var jBoxDimensions = this._exposeDimensions();
-
- // Check if target has fixed position, store in elements data
- this.target != 'mouse' && !this.target.data('jBox-' + this.id + '-fixed') && this.target.data('jBox-' + this.id + '-fixed', (this.target[0] != jQuery(window)[0] && (this.target.css('position') == 'fixed' || this.target.parents().filter(function () { return jQuery(this).css('position') == 'fixed'; }).length > 0)) ? 'fixed' : 'static');
-
- // Get the window dimensions
- var windowDimensions = {
- x: jQuery(window).outerWidth(),
- y: jQuery(window).outerHeight(),
- top: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollTop()),
- left: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollLeft())
- };
- windowDimensions.bottom = windowDimensions.top + windowDimensions.y;
- windowDimensions.right = windowDimensions.left + windowDimensions.x;
-
- // Get target offset
- try { var targetOffset = this.target.offset(); } catch (e) { var targetOffset = {top: 0, left: 0}; };
-
- // When the target is fixed and jBox is fixed, remove scroll offset
- if (this.target != 'mouse' && this.target.data('jBox-' + this.id + '-fixed') == 'fixed' && options.fixed) {
- targetOffset.top = targetOffset.top - jQuery(window).scrollTop();
- targetOffset.left = targetOffset.left - jQuery(window).scrollLeft();
- }
-
- // Get target dimensions
- var targetDimensions = {
- x: this.target == 'mouse' ? 12 : this.target.outerWidth(),
- y: this.target == 'mouse' ? 20 : this.target.outerHeight(),
- top: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.top : (targetOffset ? targetOffset.top : 0),
- left: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.left : (targetOffset ? targetOffset.left : 0)
- };
-
- // Check if jBox is outside
- var outside = options.outside && !(options.position.x == 'center' && options.position.y == 'center');
-
- // Get the available space on all sides
- var availableSpace = {
- x: windowDimensions.x - options.adjustDistance.left - options.adjustDistance.right, // TODO: substract position.x when they are numbers
- y: windowDimensions.y - options.adjustDistance.top - options.adjustDistance.bottom, // TODO: substract position.x when they are numbers
- left: !outside ? 0 : (targetDimensions.left - jQuery(window).scrollLeft() - options.adjustDistance.left),
- right: !outside ? 0 : (windowDimensions.x - targetDimensions.left + jQuery(window).scrollLeft() - targetDimensions.x - options.adjustDistance.right),
- top: !outside ? 0 : (targetDimensions.top - jQuery(window).scrollTop() - this.options.adjustDistance.top),
- bottom: !outside ? 0 : (windowDimensions.y - targetDimensions.top + jQuery(window).scrollTop() - targetDimensions.y - options.adjustDistance.bottom),
- };
-
- // Get the default outside position, check if box will be flipped
- var jBoxOutsidePosition = {
- x: (options.outside == 'x' || options.outside == 'xy') && jQuery.type(options.position.x) != 'number' ? options.position.x : null,
- y: (options.outside == 'y' || options.outside == 'xy') && jQuery.type(options.position.y) != 'number' ? options.position.y : null
- };
- var flip = {x: false, y: false};
- (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
- (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
-
- // Adjust responsive dimensions
- if (options.responsiveWidth || options.responsiveHeight) {
-
- // Adjust width and height according to default outside position
- var adjustResponsiveWidth = function ()
- {
- if (options.responsiveWidth && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x || 'x']) {
- var contentWidth = availableSpace[jBoxOutsidePosition.x || 'x'] - (this.pointer && outside && options.outside == 'x' ? this.pointer.dimensions.x : 0) - parseInt(this.container.css('border-left-width')) - parseInt(this.container.css('border-right-width'));
- this.content.css({
- width: contentWidth > this.options.responsiveMinWidth ? contentWidth : null,
- minWidth: contentWidth < parseInt(this.content.css('minWidth')) ? 0 : null
- });
- this._setTitleWidth();
- }
- jBoxDimensions = this._exposeDimensions();
-
- }.bind(this);
- options.responsiveWidth && adjustResponsiveWidth();
-
- // After adjusting width, check if jBox will be flipped for y
- options.responsiveWidth && !flip.y && (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
-
- // Adjust width and height according to default outside position
- var adjustResponsiveHeight = function ()
- {
- if (options.responsiveHeight && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y || 'y']) {
-
- // Expose wrapper to get correct title height
- var exposeTitleFooterHeight = function () {
- if (!this.titleContainer && !this.footer) return 0;
- if (this.wrapper.css('display') == 'none') {
- this.wrapper.css('display', 'block');
- var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
- this.wrapper.css('display', 'none');
- } else {
- var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
- }
- return height || 0;
- }.bind(this);
-
- var contentHeight = availableSpace[jBoxOutsidePosition.y || 'y'] - (this.pointer && outside && options.outside == 'y' ? this.pointer.dimensions.y : 0) - exposeTitleFooterHeight() - parseInt(this.container.css('border-top-width')) - parseInt(this.container.css('border-bottom-width'));
- this.content.css({height: contentHeight > this.options.responsiveMinHeight ? contentHeight : null});
- this._setTitleWidth();
- }
- jBoxDimensions = this._exposeDimensions();
-
- }.bind(this);
- options.responsiveHeight && adjustResponsiveHeight();
-
- // After adjusting height, check if jBox will be flipped for x
- options.responsiveHeight && !flip.x && (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
-
- // Adjust width and height if jBox will be flipped
- if (options.adjustPosition && options.adjustPosition != 'move') {
- flip.x && adjustResponsiveWidth();
- flip.y && adjustResponsiveHeight();
- }
- }
-
- // Store new positioning vars in local var
- var pos = {};
-
- // Calculate positions
- var setPosition = function (p)
- {
- // Set number positions
- if (jQuery.type(options.position[p]) == 'number') {
- pos[options.attributes[p]] = options.position[p];
- return;
- }
-
- // We have a target, so use 'left' or 'top' as attributes
- var a = options.attributes[p] = (p == 'x' ? 'left' : 'top');
-
- // Start at target position
- pos[a] = targetDimensions[a];
-
- // Set centered position
- if (options.position[p] == 'center') {
- pos[a] += Math.ceil((targetDimensions[p] - jBoxDimensions[p]) / 2);
-
- // If the target is the window, adjust centered position depending on adjustDistance
- (this.target != 'mouse' && this.target[0] && this.target[0] == jQuery(window)[0]) && (pos[a] += (options.adjustDistance[a] - options.adjustDistance[this._getOpp(a)]) * 0.5);
- return;
- }
-
- // Move inside
- (a != options.position[p]) && (pos[a] += targetDimensions[p] - jBoxDimensions[p]);
-
- // Move outside
- (options.outside == p || options.outside == 'xy') && (pos[a] += jBoxDimensions[p] * (a != options.position[p] ? 1 : -1));
-
- }.bind(this);
-
- // Set position including offset
- setPosition('x');
- setPosition('y');
-
- // Adjust position depending on pointer align
- if (this.pointer && options.pointTo == 'target' && jQuery.type(options.position.x) != 'number' && jQuery.type(options.position.y) != 'number') {
-
- var adjustWrapper = 0;
-
- // Where is the pointer aligned? Add or substract accordingly
- switch (this.pointer.align) {
- case 'center':
- if (options.position[this._getOpp(options.outside)] != 'center') {
- adjustWrapper += (jBoxDimensions[this._getOpp(options.outside)] / 2);
- }
- break;
- default:
- switch (options.position[this._getOpp(options.outside)]) {
- case 'center':
- adjustWrapper += ((jBoxDimensions[this._getOpp(options.outside)] / 2) - (this.pointer.dimensions[this._getOpp(options.outside)] / 2)) * (this.pointer.align == this._getTL(this.pointer.align) ? 1 : -1);
- break;
- default:
- adjustWrapper += (this.pointer.align != options.position[this._getOpp(options.outside)]) ?
-
- // If pointer align is different to position align
- (this.dimensions[this._getOpp(options.outside)] * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1)) + ((this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? -1 : 1)) :
-
- // If pointer align is same as position align
- (this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1);
- break;
- }
- break;
- }
-
- adjustWrapper *= (options.position[this._getOpp(options.outside)] == this.pointer.alignAttribute ? -1 : 1);
- adjustWrapper += this.pointer.offset * (this.pointer.align == this._getOpp(this._getTL(this.pointer.align)) ? 1 : -1);
-
- pos[this._getTL(this._getOpp(this.pointer.xy))] += adjustWrapper;
- }
-
- // Add final offset
- pos[options.attributes.x] += options.offset.x;
- pos[options.attributes.y] += options.offset.y;
-
- // Set CSS
- this.wrapper.css(pos);
-
- // Adjust position
- if (options.adjustPosition) {
-
- // Reset cached pointer position
- if (this.positionAdjusted) {
- this.pointer && this.wrapper.css('padding', 0).css('padding-' + this._getOpp(this.outside), this.pointer.dimensions[this._getXY(this.outside)]).removeClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).addClass('jBox-pointerPosition-' + this.pointer.position);
- this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + this._getOpp(this.outside)).css(this.pointer.margin);
- this.positionAdjusted = false;
- this.flipped = false;
- }
-
- // Find out where the jBox is out of view area
- var outYT = (windowDimensions.top > pos.top - (options.adjustDistance.top || 0)),
- outXR = (windowDimensions.right < pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0)),
- outYB = (windowDimensions.bottom < pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0)),
- outXL = (windowDimensions.left > pos.left - (options.adjustDistance.left || 0)),
- outX = outXL ? 'left' : (outXR ? 'right' : null),
- outY = outYT ? 'top' : (outYB ? 'bottom' : null),
- out = outX || outY;
-
- // Only continue if jBox is out of view area
- if (out) {
-
- // Function to flip position
- var flipJBox = function (xy) {
- this.wrapper.css(this._getTL(xy), pos[this._getTL(xy)] + ((jBoxDimensions[this._getXY(xy)] + (options.offset[this._getXY(xy)] * (xy == 'top' || xy == 'left' ? -2 : 2)) + targetDimensions[this._getXY(xy)]) * (xy == 'top' || xy == 'left' ? 1 : -1)));
- this.pointer && this.wrapper.removeClass('jBox-pointerPosition-' + this.pointer.position).addClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).css('padding', 0).css('padding-' + xy, this.pointer.dimensions[this._getXY(xy)]);
- this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + xy);
- this.positionAdjusted = true;
- this.flipped = true;
- }.bind(this);
-
- // Flip jBox
- flip.x && flipJBox(this.options.position.x);
- flip.y && flipJBox(this.options.position.y);
-
- // Move jBox (only possible with pointer)
- var outMove = (this._getXY(this.outside) == 'x') ? outY : outX;
-
- if (this.pointer && options.pointTo == 'target' && options.adjustPosition != 'flip' && this._getXY(outMove) == this._getOpp(this._getXY(this.outside))) {
-
- // Get the maximum space we have availible to adjust
- if (this.pointer.align == 'center') {
- var spaceAvail = (jBoxDimensions[this._getXY(outMove)] / 2) - (this.pointer.dimensions[this._getOpp(this.pointer.xy)] / 2) - (parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) * (outMove != this._getTL(outMove) ? -1 : 1));
- } else {
- var spaceAvail = (outMove == this.pointer.alignAttribute) ?
- parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) :
- jBoxDimensions[this._getXY(outMove)] - parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - this.pointer.dimensions[this._getXY(outMove)];
- }
-
- // Get the overlapping space
- spaceDiff = (outMove == this._getTL(outMove)) ?
- windowDimensions[this._getTL(outMove)] - pos[this._getTL(outMove)] + options.adjustDistance[outMove] :
- (windowDimensions[this._getOpp(this._getTL(outMove))] - pos[this._getTL(outMove)] - options.adjustDistance[outMove] - jBoxDimensions[this._getXY(outMove)]) * -1;
-
- // Add overlapping space on left or top window edge
- if (outMove == this._getOpp(this._getTL(outMove)) && pos[this._getTL(outMove)] - spaceDiff < windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)]) {
- spaceDiff -= windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)] - (this.pos[this._getTL(outMove)] - spaceDiff);
- }
-
- // Only adjust the maximum availible
- spaceDiff = Math.min(spaceDiff, spaceAvail);
-
- // Move jBox
- if (spaceDiff <= spaceAvail && spaceDiff > 0) {
- this.pointer.element.css('margin-' + this.pointer.alignAttribute, parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - (spaceDiff * (outMove != this.pointer.alignAttribute ? -1 : 1)));
- this.wrapper.css(this._getTL(outMove), pos[this._getTL(outMove)] + (spaceDiff * (outMove != this._getTL(outMove) ? -1 : 1)));
- this.positionAdjusted = true;
- }
- }
- }
- }
-
- // Fire onPosition event
- this._fireEvent('onPosition');
-
- return this;
-};
-
-
-// Open jBox
-
-jBox.prototype.open = function (options)
-{
- // Create blank options if none passed
- !options && (options = {});
-
- // Abort if jBox was destroyed
- if (this.isDestroyed) return false;
-
- // Construct jBox if not already constructed
- !this.wrapper && this._create();
-
- // Add css to header if not added already
- !this._styles && (this._styles = jQuery('
').append(this._animationCSS).appendTo(jQuery('head')));
-
- // Abort any opening or closing timer
- this.timer && clearTimeout(this.timer);
-
- // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body'
- this._blockBodyClick();
-
- // Block opening
- if (this.isDisabled) return this;
-
- // Opening function
- var open = function () {
-
- // Set title from source element
- this.source && this.options.getTitle && (this.source.attr(this.options.getTitle) && this.setTitle(this.source.attr(this.options.getTitle)), true);
-
- // Set content from source element
- this.source && this.options.getContent && (this.source.data('jBox-getContent') ? this.setContent(this.source.data('jBox-getContent'), true) : (this.source.attr(this.options.getContent) ? this.setContent(this.source.attr(this.options.getContent), true) : (this.options.getContent == 'html' ? this.setContent(this.source.html(), true) : null)));
-
- // Fire onOpen event
- this._fireEvent('onOpen');
-
- // Get content from ajax
- if ((this.options.ajax && (this.options.ajax.url || (this.source && this.source.attr(this.options.ajax.getURL))) && (!this.ajaxLoaded || this.options.ajax.reload)) || (options.ajax && (options.ajax.url || options.ajax.data))) {
- // Send the content from stored data if there is any, otherwise load new data
- (this.options.ajax.reload != 'strict' && this.source && this.source.data('jBox-ajax-data') && !(options.ajax && (options.ajax.url || options.ajax.data))) ? this.setContent(this.source.data('jBox-ajax-data')) : this.ajax((options.ajax || null), true);
- }
-
- // Set position
- (!this.positionedOnOpen || this.options.repositionOnOpen) && this.position(options) && (this.positionedOnOpen = true);
-
- // Abort closing
- this.isClosing && this._abortAnimation();
-
- // Open functions to call when jBox is closed
- if (!this.isOpen) {
-
- // jBox is open now
- this.isOpen = true;
-
- // Automatically close jBox after some time
- this.options.autoClose && (this.options.delayClose = this.options.autoClose) && this.close();
-
- // Attach events
- this._attachEvents();
-
- // Block scrolling
- this.options.blockScroll && jQuery('body').addClass('jBox-blockScroll-' + this.id);
-
- // Show overlay
- this.options.overlay && this._showOverlay();
-
- // Only animate if jBox is completely closed
- this.options.animation && !this.isClosing && this._animate('open');
-
- // Play audio file
- this.options.audio && this.options.audio.open && this.audio(this.options.audio.open, this.options.volume.open);
-
- // Fading animation or show immediately
- if (this.options.fade) {
- this.wrapper.stop().animate({opacity: 1}, {
- queue: false,
- duration: this.options.fade,
- start: function () {
- this.isOpening = true;
- this.wrapper.css({display: 'block'});
- }.bind(this),
- always: function () {
- this.isOpening = false;
-
- // Delay positioning for ajax to prevent positioning during animation
- setTimeout(function () { this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false); }.bind(this), 10);
- }.bind(this)
- });
- } else {
- this.wrapper.css({display: 'block', opacity: 1});
- this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false);
- }
- }
- }.bind(this);
-
- // Open jBox
- this.options.delayOpen && !this.isOpen && !this.isClosing && !options.ignoreDelay ? (this.timer = setTimeout(open, this.options.delayOpen)) : open();
-
- return this;
-};
-
-
-// Close jBox
-
-jBox.prototype.close = function (options)
-{
- // Create blank options if none passed
- options || (options = {});
-
- // Abort if jBox was destroyed or is currently closing
- if (this.isDestroyed || this.isClosing) return false;
-
- // Abort opening
- this.timer && clearTimeout(this.timer);
-
- // Block body click for 10ms, so jBox can open on attached elements while closeOnClock = 'body' is true
- this._blockBodyClick();
-
- // Block closing
- if (this.isDisabled) return this;
-
- // Close function
- var close = function () {
-
- // Fire onClose event
- this._fireEvent('onClose');
-
- // Only close if jBox is open
- if (this.isOpen) {
-
- // jBox is not open anymore
- this.isOpen = false;
-
- // Detach events
- this._detachEvents();
-
- // Unblock scrolling
- this.options.blockScroll && jQuery('body').removeClass('jBox-blockScroll-' + this.id);
-
- // Hide overlay
- this.options.overlay && this._hideOverlay();
-
- // Only animate if jBox is compleately closed
- this.options.animation && !this.isOpening && this._animate('close');
-
- // Play audio file
- this.options.audio && this.options.audio.close && this.audio(this.options.audio.close, this.options.volume.close);
-
- // Fading animation or show immediately
- if (this.options.fade) {
- this.wrapper.stop().animate({opacity: 0}, {
- queue: false,
- duration: this.options.fade,
- start: function () {
- this.isClosing = true;
- }.bind(this),
- complete: function () {
- this.wrapper.css({display: 'none'});
- this._fireEvent('onCloseComplete');
- }.bind(this),
- always: function () {
- this.isClosing = false;
- }.bind(this)
- });
- } else {
- this.wrapper.css({display: 'none', opacity: 0});
- this._fireEvent('onCloseComplete');
- }
- }
- }.bind(this);
-
- // Close jBox
- options.ignoreDelay ? close() : (this.timer = setTimeout(close, Math.max(this.options.delayClose, 10)));
-
- return this;
-};
-
-
-// Open or close jBox
-
-jBox.prototype.toggle = function (options)
-{
- this[this.isOpen ? 'close' : 'open'](options);
- return this;
-};
-
-
-// Block opening and closing
-
-jBox.prototype.disable = function ()
-{
- this.isDisabled = true;
- return this;
-};
-
-
-// Unblock opening and closing
-
-jBox.prototype.enable = function ()
-{
- this.isDisabled = false;
- return this;
-};
-
-
-// Hide jBox
-
-jBox.prototype.hide = function ()
-{
- this.disable();
- this.wrapper && this.wrapper.css({display: 'none'});
- return this;
-};
-
-
-// Show jBox
-
-jBox.prototype.show = function ()
-{
- this.enable();
- this.wrapper && this.wrapper.css({display: 'block'});
- return this;
-};
-
-
-// Get content from ajax
-
-jBox.prototype.ajax = function (options, opening)
-{
- options || (options = {});
-
- // Add data or url from source element if none set in options
- jQuery.each([['getData', 'data'], ['getURL', 'url']], function (index, item) {
- (this.options.ajax[item[0]] && !options[item[1]] && this.source && this.source.attr(this.options.ajax[item[0]]) != undefined) && (options[item[1]] = this.source.attr(this.options.ajax[item[0]]) || '');
- }.bind(this));
-
- // Clone the system options
- var sysOptions = jQuery.extend(true, {}, this.options.ajax);
-
- // Abort running ajax call
- this.ajaxRequest && this.ajaxRequest.abort();
-
- // Extract events
- var beforeSend = options.beforeSend || sysOptions.beforeSend || function () {};
- var complete = options.complete || sysOptions.complete || function () {};
- var success = options.success || sysOptions.success || function () {};
- var error = options.error || sysOptions.error || function () {};
-
- // Merge options
- var userOptions = jQuery.extend(true, sysOptions, options);
-
- // Set new beforeSend event
- userOptions.beforeSend = function ()
- {
- // jBox is loading
- this.wrapper.addClass('jBox-loading');
-
- // Add loading spinner
- userOptions.spinner && (this.spinnerDelay = setTimeout(function ()
- {
- // If there is a dela
- this.wrapper.addClass('jBox-loading-spinner');
-
- // Reposition jBox
- // TODO: Only reposition if dimensions change
- userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
-
- // Add spinner to container
- this.spinner = jQuery(userOptions.spinner !== true ? userOptions.spinner : '
').appendTo(this.container);
-
- // Fix spinners position if there is a title
- this.titleContainer && this.spinner.css('position') == 'absolute' && this.spinner.css({transform: 'translateY(' + (this.titleContainer.outerHeight() * 0.5) + 'px)'});
-
- }.bind(this), (this.content.html() == '' ? 0 : (userOptions.spinnerDelay || 0))));
-
- // Fire users beforeSend event
- (beforeSend.bind(this))();
-
- }.bind(this);
-
- // Set up new complete event
- userOptions.complete = function (response)
- {
- // Abort spinner timeout
- this.spinnerDelay && clearTimeout(this.spinnerDelay);
-
- // jBox finished loading
- this.wrapper.removeClass('jBox-loading jBox-loading-spinner jBox-loading-spinner-delay');
-
- // Remove spinner
- this.spinner && this.spinner.length && this.spinner.remove() && userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
-
- // Store that ajax loading finished
- this.ajaxLoaded = true;
-
- // Fire users complete event
- (complete.bind(this))(response);
-
- }.bind(this);
-
- // Set up new success event
- userOptions.success = function (response)
- {
- // Set content
- userOptions.setContent && this.setContent(response, true) && (opening ? (this.positionOnFadeComplete = true) : this.position());
-
- // Store content in source element
- userOptions.setContent && this.source && this.source.data('jBox-ajax-data', response);
-
- // Fire users success event
- (success.bind(this))(response);
-
- }.bind(this);
-
- // Add error event
- userOptions.error = function (response) { (error.bind(this))(response); }.bind(this);
-
- // Send new ajax request
- this.ajaxRequest = jQuery.ajax(userOptions);
-
- return this;
-};
-
-
-// Play an audio file
-
-jBox.prototype.audio = function (url, volume)
-{
- // URL is required
- if (!url) return this;
-
- // Create intern audio object if it wasn't created already
- !jBox._audio && (jBox._audio = {});
-
- // Create an audio element specific to this audio file if it doesn't exist already
- if (!jBox._audio[url]) {
- var audio = jQuery(' ');
- jQuery(' ', {src: url + '.mp3'}).appendTo(audio);
- jQuery(' ', {src: url + '.ogg'}).appendTo(audio);
- jBox._audio[url] = audio[0];
- }
-
- // Set volume
- jBox._audio[url].volume = Math.min(((volume != undefined ? volume : 100) / 100), 1);
-
- // Try to pause current audio
- try {
- jBox._audio[url].pause();
- jBox._audio[url].currentTime = 0;
- } catch (e) {}
-
- // Play audio
- jBox._audio[url].play();
-
- return this;
-};
-
-
-// Apply custom animations to jBox
-
-jBox._animationSpeeds = {
- 'tada': 1000,
- 'tadaSmall': 1000,
- 'flash': 500,
- 'shake': 400,
- 'pulseUp': 250,
- 'pulseDown': 250,
- 'popIn': 250,
- 'popOut': 250,
- 'fadeIn': 200,
- 'fadeOut': 200,
- 'slideUp': 400,
- 'slideRight': 400,
- 'slideLeft': 400,
- 'slideDown': 400
-};
-
-jBox.prototype.animate = function (animation, options)
-{
- // Options are required
- !options && (options = {});
-
- // Timout needs to be an object
- !this.animationTimeout && (this.animationTimeout = {});
-
- // Use jBox wrapper by default
- !options.element && (options.element = this.wrapper);
-
- // Give the element an unique id
- !options.element.data('jBox-animating-id') && options.element.data('jBox-animating-id', jBox._getUniqueElementID());
-
- // Abort if element is animating
- if (options.element.data('jBox-animating')) {
- options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null);
- this.animationTimeout[options.element.data('jBox-animating-id')] && clearTimeout(this.animationTimeout[options.element.data('jBox-animating-id')]);
- }
-
- // Animate the element
- options.element.addClass('jBox-animated-' + animation).data('jBox-animating', 'jBox-animated-' + animation);
- this.animationTimeout[options.element.data('jBox-animating-id')] = setTimeout((function() { options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null); options.complete && options.complete(); }), jBox._animationSpeeds[animation]);
-};
-
-
-// Destroy jBox and remove it from DOM
-
-jBox.prototype.destroy = function ()
-{
- // Detach from attached elements
- this.detach();
-
- // If jBox is open, close without delay
- this.isOpen && this.close({ignoreDelay: true});
-
- // Remove wrapper
- this.wrapper && this.wrapper.remove();
-
- // Remove overlay
- this.overlay && this.overlay.remove();
-
- // Remove styles
- this._styles && this._styles.remove();
-
- // Tell the jBox instance it is destroyed
- this.isDestroyed = true;
-
- return this;
-};
-
-
-// Get a unique ID for jBoxes
-
-jBox._getUniqueID = (function ()
-{
- var i = 1;
- return function () { return i++; };
-}());
-
-
-// Get a unique ID for animating elements
-
-jBox._getUniqueElementID = (function ()
-{
- var i = 1;
- return function () { return i++; };
-}());
-
-
-// Function to create jBox plugins
-
-jBox._pluginOptions = {};
-function jBoxPlugin(type, options)
-{
- jBox._pluginOptions[type] = options;
-};
-
-
-// Make jBox usable with jQuery selectors
-
-jQuery.fn.jBox = function (type, options)
-{
- // Variables type and object are required
- !type && (type = {});
- !options && (options = {});
-
- // Return a new instance of jBox with the selector as attached element
- return new jBox(type, jQuery.extend(options, {
- attach: this
- }));
-};
diff --git a/Source/jBox.min.js b/Source/jBox.min.js
deleted file mode 100644
index 3239272..0000000
--- a/Source/jBox.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-function jBox(t,i){return this.options={id:null,width:"auto",height:"auto",minWidth:null,minHeight:null,maxWidth:null,maxHeight:null,responsiveWidth:!0,responsiveHeight:!0,responsiveMinWidth:100,responsiveMinHeight:100,attach:null,trigger:"click",preventDefault:!1,content:null,getContent:null,title:null,getTitle:null,footer:null,isolateScroll:!0,ajax:{url:null,data:"",reload:!1,getURL:"data-url",getData:"data-ajax",setContent:!0,spinner:!0,spinnerDelay:300,spinnerReposition:!0},target:null,position:{x:"center",y:"center"},outside:null,offset:0,attributes:{x:"left",y:"top"},fixed:!1,adjustPosition:!0,adjustTracker:!1,adjustDistance:5,reposition:!0,repositionOnOpen:!0,repositionOnContent:!0,pointer:!1,pointTo:"target",fade:180,animation:null,theme:"Default",addClass:null,overlay:!1,zIndex:1e4,delayOpen:0,delayClose:0,closeOnEsc:!1,closeOnClick:!1,closeOnMouseleave:!1,closeButton:!1,appendTo:jQuery("body"),createOnInit:!1,blockScroll:!1,draggable:!1,dragOver:!0,autoClose:!1,preloadAudio:!0,audio:null,volume:100,onInit:null,onAttach:null,onPosition:null,onCreated:null,onOpen:null,onClose:null,onCloseComplete:null},this._pluginOptions={Tooltip:{getContent:"title",trigger:"mouseenter",position:{x:"center",y:"top"},outside:"y",pointer:!0},Mouse:{responsiveWidth:!1,responsiveHeight:!1,adjustPosition:"flip",target:"mouse",trigger:"mouseenter",position:{x:"right",y:"bottom"},outside:"xy",offset:5},Modal:{target:jQuery(window),fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"overlay",closeButton:!0,overlay:!0,animation:"zoomIn"}},this.options=jQuery.extend(!0,this.options,this._pluginOptions[t]?this._pluginOptions[t]:jBox._pluginOptions[t],i),"string"==jQuery.type(t)&&(this.type=t),this._fireEvent=function(t,i){this.options["_"+t]&&this.options["_"+t].bind(this)(i),this.options[t]&&this.options[t].bind(this)(i)},null===this.options.id&&(this.options.id="jBox"+jBox._getUniqueID()),this.id=this.options.id,("center"==this.options.position.x&&"x"==this.options.outside||"center"==this.options.position.y&&"y"==this.options.outside)&&(this.options.outside=null),"target"==this.options.pointTo&&(!this.options.outside||"xy"==this.options.outside)&&(this.options.pointer=!1),"object"!=jQuery.type(this.options.offset)?this.options.offset={x:this.options.offset,y:this.options.offset}:this.options.offset=jQuery.extend({x:0,y:0},this.options.offset),"object"!=jQuery.type(this.options.adjustDistance)?this.options.adjustDistance={top:this.options.adjustDistance,right:this.options.adjustDistance,bottom:this.options.adjustDistance,left:this.options.adjustDistance}:this.options.adjustDistance=jQuery.extend({top:5,left:5,right:5,bottom:5},this.options.adjustDistance),this.outside=!(!this.options.outside||"xy"==this.options.outside)&&this.options.position[this.options.outside],this.align=this.outside?this.outside:"center"!=this.options.position.y&&"number"!=jQuery.type(this.options.position.y)?this.options.position.x:"center"!=this.options.position.x&&"number"!=jQuery.type(this.options.position.x)?this.options.position.y:this.options.attributes.x,this._getOpp=function(t){return{left:"right",right:"left",top:"bottom",bottom:"top",x:"y",y:"x"}[t]},this._getXY=function(t){return{left:"x",right:"x",top:"y",bottom:"y",center:"x"}[t]},this._getTL=function(t){return{left:"left",right:"left",top:"top",bottom:"top",center:"left",x:"left",y:"top"}[t]},this._getInt=function(t,i){return"auto"==t?"auto":t&&"string"==jQuery.type(t)&&"%"==t.slice(-1)?jQuery(window)["height"==i?"innerHeight":"innerWidth"]()*parseInt(t.replace("%",""))/100:t},this._createSVG=function(t,i){var s=document.createElementNS("http://www.w3.org/2000/svg",t);return jQuery.each(i,function(t,i){s.setAttribute(i[0],i[1]||"")}),s},this._isolateScroll=function(t){t&&t.length&&t.on("DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll",function(i){var s=i.wheelDelta||i.originalEvent&&i.originalEvent.wheelDelta||-i.detail,o=this.scrollTop+t.outerHeight()-this.scrollHeight>=0,e=this.scrollTop<=0;(s<0&&o||s>0&&e)&&i.preventDefault()})},this._setTitleWidth=function(){if(!this.titleContainer||"auto"==this.content[0].style.width&&!this.content[0].style.maxWidth)return null;if("none"==this.wrapper.css("display")){this.wrapper.css("display","block");var t=this.content.outerWidth();this.wrapper.css("display","none")}else var t=this.content.outerWidth();this.titleContainer.css({maxWidth:Math.max(t,parseInt(this.content[0].style.maxWidth))||null})},this._draggable=function(){if(!this.options.draggable)return!1;var t="title"==this.options.draggable?this.titleContainer:this.options.draggable instanceof jQuery?this.options.draggable:"string"==jQuery.type(this.options.draggable)?jQuery(this.options.draggable):this.wrapper;return!(!(t&&t instanceof jQuery&&t.length)||t.data("jBox-draggable"))&&(t.addClass("jBox-draggable").data("jBox-draggable",!0).on("mousedown",function(t){if(2!=t.button&&!jQuery(t.target).hasClass("jBox-noDrag")&&!jQuery(t.target).parents(".jBox-noDrag").length){this.options.dragOver&&this.wrapper.css("zIndex")<=jBox.zIndexMax&&(jBox.zIndexMax+=1,this.wrapper.css("zIndex",jBox.zIndexMax));var i=this.wrapper.outerHeight(),s=this.wrapper.outerWidth(),o=this.wrapper.offset().top+i-t.pageY,e=this.wrapper.offset().left+s-t.pageX;jQuery(document).on("mousemove.jBox-draggable-"+this.id,function(t){this.wrapper.offset({top:t.pageY+o-i,left:t.pageX+e-s})}.bind(this)),t.preventDefault()}}.bind(this)).on("mouseup",function(){jQuery(document).off("mousemove.jBox-draggable-"+this.id)}.bind(this)),jBox.zIndexMax=jBox.zIndexMax?Math.max(jBox.zIndexMax,this.options.zIndex):this.options.zIndex,this)},this._create=function(){if(!this.wrapper){if(this.wrapper=jQuery("
",{id:this.id,class:"jBox-wrapper"+(this.type?" jBox-"+this.type:"")+(this.options.theme?" jBox-"+this.options.theme:"")+(this.options.addClass?" "+this.options.addClass:"")}).css({position:this.options.fixed?"fixed":"absolute",display:"none",opacity:0,zIndex:this.options.zIndex}).data("jBox",this),this.options.closeOnMouseleave&&this.wrapper.on("mouseleave",function(t){!this.source||!(t.relatedTarget==this.source[0]||jQuery.inArray(this.source[0],jQuery(t.relatedTarget).parents("*"))!==-1)&&this.close()}.bind(this)),"box"==this.options.closeOnClick&&this.wrapper.on("touchend click",function(){this.close({ignoreDelay:!0})}.bind(this)),this.container=jQuery('
').appendTo(this.wrapper),this.content=jQuery('
').appendTo(this.container),this.options.footer&&(this.footer=jQuery('').append(this.options.footer).appendTo(this.container)),this.options.isolateScroll&&this._isolateScroll(this.content),this.options.closeButton){var t=this._createSVG("svg",[["viewBox","0 0 24 24"]]);t.appendChild(this._createSVG("path",[["d","M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z"]])),this.closeButton=jQuery('
').on("touchend click",function(t){this.close({ignoreDelay:!0})}.bind(this)).append(t),"box"!=this.options.closeButton&&(this.options.closeButton!==!0||this.options.overlay||this.options.title)||(this.wrapper.addClass("jBox-closeButton-box"),this.closeButton.appendTo(this.container))}if(this.wrapper.appendTo(this.options.appendTo),this.wrapper.find(".jBox-closeButton").length&&jQuery.each(["top","right","bottom","left"],function(t,i){this.wrapper.find(".jBox-closeButton").css(i)&&"auto"!=this.wrapper.find(".jBox-closeButton").css(i)&&(this.options.adjustDistance[i]=Math.max(this.options.adjustDistance[i],this.options.adjustDistance[i]+((parseInt(this.wrapper.find(".jBox-closeButton").css(i))||0)+(parseInt(this.container.css("border-"+i+"-width"))||0))*-1))}.bind(this)),this.options.pointer){if(this.pointer={position:"target"!=this.options.pointTo?this.options.pointTo:this._getOpp(this.outside),xy:"target"!=this.options.pointTo?this._getXY(this.options.pointTo):this._getXY(this.outside),align:"center",offset:0},this.pointer.element=jQuery('
').appendTo(this.wrapper),this.pointer.dimensions={x:this.pointer.element.outerWidth(),y:this.pointer.element.outerHeight()},"string"==jQuery.type(this.options.pointer)){var i=this.options.pointer.split(":");i[0]&&(this.pointer.align=i[0]),i[1]&&(this.pointer.offset=parseInt(i[1]))}this.pointer.alignAttribute="x"==this.pointer.xy?"bottom"==this.pointer.align?"bottom":"top":"right"==this.pointer.align?"right":"left",this.wrapper.css("padding-"+this.pointer.position,this.pointer.dimensions[this.pointer.xy]),this.pointer.element.css(this.pointer.alignAttribute,"center"==this.pointer.align?"50%":0).css("margin-"+this.pointer.alignAttribute,this.pointer.offset),this.pointer.margin={},this.pointer.margin["margin-"+this.pointer.alignAttribute]=this.pointer.offset,"center"==this.pointer.align&&this.pointer.element.css("transform","translate("+("y"==this.pointer.xy?this.pointer.dimensions.x*-.5+"px":0)+", "+("x"==this.pointer.xy?this.pointer.dimensions.y*-.5+"px":0)+")"),this.pointer.element.css("x"==this.pointer.xy?"width":"height",parseInt(this.pointer.dimensions[this.pointer.xy])+parseInt(this.container.css("border-"+this.pointer.alignAttribute+"-width"))),this.wrapper.addClass("jBox-pointerPosition-"+this.pointer.position)}this.setContent(this.options.content,!0),this.setTitle(this.options.title,!0),this.options.draggable&&this._draggable(),this._fireEvent("onCreated")}},this.options.createOnInit&&this._create(),this.options.attach&&this.attach(),this._attachEvents=function(){this.options.closeOnEsc&&jQuery(document).on("keyup.jBox-"+this.id,function(t){27==t.keyCode&&this.close({ignoreDelay:!0})}.bind(this)),this.options.closeOnClick!==!0&&"body"!=this.options.closeOnClick||jQuery(document).on("touchend.jBox-"+this.id+" click.jBox-"+this.id,function(t){this.blockBodyClick||"body"==this.options.closeOnClick&&(t.target==this.wrapper[0]||this.wrapper.has(t.target).length)||this.close({ignoreDelay:!0})}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&!this.fixed&&this.outside&&(this.options.adjustTracker&&jQuery(window).on("scroll.jBox-"+this.id,function(t){this.position()}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&jQuery(window).on("resize.jBox-"+this.id,function(t){this.position()}.bind(this))),"mouse"==this.options.target&&jQuery("body").on("mousemove.jBox-"+this.id,function(t){this.position({mouseTarget:{top:t.pageY,left:t.pageX}})}.bind(this))},this._detachEvents=function(){this.options.closeOnEsc&&jQuery(document).off("keyup.jBox-"+this.id),(this.options.closeOnClick===!0||"body"==this.options.closeOnClick)&&jQuery(document).off("touchend.jBox-"+this.id+" click.jBox-"+this.id),this.options.adjustTracker&&jQuery(window).off("scroll.jBox-"+this.id),(this.options.adjustPosition||this.options.reposition)&&jQuery(window).off("resize.jBox-"+this.id),"mouse"==this.options.target&&jQuery("body").off("mousemove.jBox-"+this.id)},this._showOverlay=function(){this.overlay||(this.overlay=jQuery('
').addClass("jBox-overlay"+(this.type?" jBox-overlay-"+this.type:"")).css({display:"none",opacity:0,zIndex:this.options.zIndex-1}).appendTo(this.options.appendTo),("overlay"==this.options.closeButton||this.options.closeButton===!0&&!this.titleContainer)&&this.overlay.append(this.closeButton),"overlay"==this.options.closeOnClick&&this.overlay.on("touchend click",function(){this.close({ignoreDelay:!0})}.bind(this)),jQuery("#"+this.id+"-overlay .jBox-closeButton").length&&(this.options.adjustDistance.top=Math.max(jQuery("#"+this.id+"-overlay .jBox-closeButton").outerHeight(),this.options.adjustDistance.top))),"block"!=this.overlay.css("display")&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.overlay.css({display:"block"})}.bind(this)}):this.overlay.css({display:"block",opacity:1}))},this._hideOverlay=function(){this.overlay&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:0},{queue:!1,duration:this.options.fade,complete:function(){this.overlay.css({display:"none"})}.bind(this)}):this.overlay.css({display:"none",opacity:0}))},this._exposeDimensions=function(){this.wrapper.css({top:-1e4,left:-1e4,right:"auto",bottom:"auto"});var t={x:this.wrapper.outerWidth(),y:this.wrapper.outerHeight()};return this.wrapper.css({top:"auto",left:"auto"}),t},this._generateAnimationCSS=function(){if("object"!=jQuery.type(this.options.animation)&&(this.options.animation={pulse:{open:"pulse",close:"zoomOut"},zoomIn:{open:"zoomIn",close:"zoomIn"},zoomOut:{open:"zoomOut",close:"zoomOut"},move:{open:"move",close:"move"},slide:{open:"slide",close:"slide"},flip:{open:"flip",close:"flip"},tada:{open:"tada",close:"zoomOut"}}[this.options.animation]),!this.options.animation)return null;this.options.animation.open&&(this.options.animation.open=this.options.animation.open.split(":")),this.options.animation.close&&(this.options.animation.close=this.options.animation.close.split(":")),this.options.animation.openDirection=this.options.animation.open[1]?this.options.animation.open[1]:null,this.options.animation.closeDirection=this.options.animation.close[1]?this.options.animation.close[1]:null,this.options.animation.open&&(this.options.animation.open=this.options.animation.open[0]),this.options.animation.close&&(this.options.animation.close=this.options.animation.close[0]),this.options.animation.open&&(this.options.animation.open+="Open"),this.options.animation.close&&(this.options.animation.close+="Close");var t={pulse:{duration:350,css:[["0%","scale(1)"],["50%","scale(1.1)"],["100%","scale(1)"]]},zoomInOpen:{duration:this.options.fade||180,css:[["0%","scale(0.9)"],["100%","scale(1)"]]},zoomInClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(0.9)"]]},zoomOutOpen:{duration:this.options.fade||180,css:[["0%","scale(1.1)"],["100%","scale(1)"]]},zoomOutClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(1.1)"]]},moveOpen:{duration:this.options.fade||180,positions:{top:{"0%":-12},right:{"0%":12},bottom:{"0%":12},left:{"0%":-12}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},moveClose:{duration:this.options.fade||180,timing:"ease-in",positions:{top:{"100%":-12},right:{"100%":12},bottom:{"100%":12},left:{"100%":-12}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},slideOpen:{duration:400,positions:{top:{"0%":-400},right:{"0%":400},bottom:{"0%":400},left:{"0%":-400}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},slideClose:{duration:400,timing:"ease-in",positions:{top:{"100%":-400},right:{"100%":400},bottom:{"100%":400},left:{"100%":-400}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},flipOpen:{duration:600,css:[["0%","perspective(400px) rotateX(90deg)"],["40%","perspective(400px) rotateX(-15deg)"],["70%","perspective(400px) rotateX(15deg)"],["100%","perspective(400px) rotateX(0deg)"]]},flipClose:{duration:this.options.fade||300,css:[["0%","perspective(400px) rotateX(0deg)"],["100%","perspective(400px) rotateX(90deg)"]]},tada:{duration:800,css:[["0%","scale(1)"],["10%, 20%","scale(0.9) rotate(-3deg)"],["30%, 50%, 70%, 90%","scale(1.1) rotate(3deg)"],["40%, 60%, 80%","scale(1.1) rotate(-3deg)"],["100%","scale(1) rotate(0)"]]}};jQuery.each(["pulse","tada"],function(i,s){t[s+"Open"]=t[s+"Close"]=t[s]});var i=function(i,s){return keyframe_css="@keyframes jBox-"+this.id+"-animation-"+this.options.animation[i]+"-"+i+(s?"-"+s:"")+" {",jQuery.each(t[this.options.animation[i]].css,function(o,e){var n=s?e[1].replace("%XY",this._getXY(s).toUpperCase()):e[1];t[this.options.animation[i]].positions&&(n=n.replace("%V",t[this.options.animation[i]].positions[s][e[0]])),keyframe_css+=e[0]+" {transform:"+n+";}"}.bind(this)),keyframe_css+="}",keyframe_css+=".jBox-"+this.id+"-animation-"+this.options.animation[i]+"-"+i+(s?"-"+s:"")+" {",keyframe_css+="animation-duration: "+t[this.options.animation[i]].duration+"ms;",keyframe_css+="animation-name: jBox-"+this.id+"-animation-"+this.options.animation[i]+"-"+i+(s?"-"+s:"")+";",keyframe_css+=t[this.options.animation[i]].timing?"animation-timing-function: "+t[this.options.animation[i]].timing+";":"",keyframe_css+="}",keyframe_css}.bind(this);this._animationCSS="",jQuery.each(["open","close"],function(s,o){return this.options.animation[o]&&t[this.options.animation[o]]&&("close"!=o||this.options.fade)?void(t[this.options.animation[o]].positions?jQuery.each(["top","right","bottom","left"],function(t,s){this._animationCSS+=i(o,s)}.bind(this)):this._animationCSS+=i(o)):""}.bind(this))},this.options.animation&&this._generateAnimationCSS(),this._blockBodyClick=function(){this.blockBodyClick=!0,setTimeout(function(){this.blockBodyClick=!1}.bind(this),10)},this._animate=function(t){if(!t&&(t=this.isOpen?"open":"close"),!this.options.fade&&"close"==t)return null;var i=this.options.animation[t+"Direction"]||("center"!=this.align?this.align:this.options.attributes.x);this.flipped&&this._getXY(i)==this._getXY(this.align)&&(i=this._getOpp(i));var s="jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+" jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+"-"+i;this.wrapper.addClass(s);var o=1e3*parseFloat(this.wrapper.css("animation-duration"));"close"==t&&(o=Math.min(o,this.options.fade)),setTimeout(function(){this.wrapper.removeClass(s)}.bind(this),o)},this._abortAnimation=function(){var t=this.wrapper.attr("class").split(" ").filter(function(t){return 0!==t.lastIndexOf("jBox-"+this.id+"-animation",0)}.bind(this));this.wrapper.attr("class",t.join(" "))},(this.options.responsiveWidth||this.options.responsiveHeight)&&jQuery(window).on("resize.responsivejBox-"+this.id,function(t){this.isOpen&&this.position()}.bind(this)),"string"===jQuery.type(this.options.preloadAudio)&&(this.options.preloadAudio=[this.options.preloadAudio]),"string"===jQuery.type(this.options.audio)&&(this.options.audio={open:this.options.audio}),"number"===jQuery.type(this.options.volume)&&(this.options.volume={open:this.options.volume,close:this.options.volume}),this.options.preloadAudio===!0&&this.options.audio&&(this.options.preloadAudio=[],jQuery.each(this.options.audio,function(t,i){this.options.preloadAudio.push(i+".mp3"),this.options.preloadAudio.push(i+".ogg")}.bind(this))),this.options.preloadAudio.length&&jQuery.each(this.options.preloadAudio,function(t,i){var s=new Audio;s.src=i,s.preload="auto"}),this._fireEvent("onInit"),this}function jBoxPlugin(t,i){jBox._pluginOptions[t]=i}jBox.prototype.attach=function(t,i){return!t&&(t=this.options.attach),"string"==jQuery.type(t)&&(t=jQuery(t)),!i&&(i=this.options.trigger),t&&t.length&&jQuery.each(t,function(t,s){s=jQuery(s),s.data("jBox-attached-"+this.id)||("title"==this.options.getContent&&void 0!=s.attr("title")&&s.data("jBox-getContent",s.attr("title")).removeAttr("title"),this.attachedElements||(this.attachedElements=[]),this.attachedElements.push(s[0]),s.on(i+".jBox-attach-"+this.id,function(t){if(this.timer&&clearTimeout(this.timer),"mouseenter"!=i||!this.isOpen||this.source[0]!=s[0]){if(this.isOpen&&this.source&&this.source[0]!=s[0])var o=!0;this.source=s,!this.options.target&&(this.target=s),"click"==i&&this.options.preventDefault&&t.preventDefault(),this["click"!=i||o?"open":"toggle"]()}}.bind(this)),"mouseenter"==this.options.trigger&&s.on("mouseleave",function(t){return this.wrapper?void(this.options.closeOnMouseleave&&(t.relatedTarget==this.wrapper[0]||jQuery(t.relatedTarget).parents("#"+this.id).length)||this.close()):null}.bind(this)),s.data("jBox-attached-"+this.id,i),this._fireEvent("onAttach",s))}.bind(this)),this},jBox.prototype.detach=function(t){return!t&&(t=this.attachedElements||[]),t&&t.length&&jQuery.each(t,function(t,i){i=jQuery(i),i.data("jBox-attached-"+this.id)&&(i.off(i.data("jBox-attached-"+this.id)+".jBox-attach-"+this.id),i.data("jBox-attached-"+this.id,null)),this.attachedElements=jQuery.grep(this.attachedElements,function(t){return t!=i[0]})}.bind(this)),this},jBox.prototype.setTitle=function(t,i){if(null==t||void 0==t)return this;!this.wrapper&&this._create();var s=this.wrapper.outerHeight(),o=this.wrapper.outerWidth();return this.title||(this.titleContainer=jQuery('
'),this.title=jQuery("
").appendTo(this.titleContainer),this.wrapper.addClass("jBox-hasTitle"),("title"==this.options.closeButton||this.options.closeButton===!0&&!this.options.overlay)&&(this.wrapper.addClass("jBox-closeButton-title"),this.closeButton.appendTo(this.titleContainer)),this.titleContainer.insertBefore(this.content),this._setTitleWidth()),this.title.html(t),o!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),!i&&this.options.repositionOnContent&&(s!=this.wrapper.outerHeight()||o!=this.wrapper.outerWidth())&&this.position(),this},jBox.prototype.setContent=function(t,i){if(null==t||void 0==t)return this;!this.wrapper&&this._create();var s=this.wrapper.outerHeight(),o=this.wrapper.outerWidth();switch(this.content.children("[data-jbox-content-appended]").appendTo("body").css({display:"none"}),jQuery.type(t)){case"string":this.content.html(t);break;case"object":this.content.html(""),t.attr("data-jbox-content-appended",1).appendTo(this.content).css({display:"block"})}return o!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),!i&&this.options.repositionOnContent&&(s!=this.wrapper.outerHeight()||o!=this.wrapper.outerWidth())&&this.position(),this},jBox.prototype.setDimensions=function(t,i,s){!this.wrapper&&this._create(),void 0==i&&(i="auto"),this.content.css(t,this._getInt(i)),"width"==t&&this._setTitleWidth(),(void 0==s||s)&&this.position()},jBox.prototype.setWidth=function(t,i){this.setDimensions("width",t,i)},jBox.prototype.setHeight=function(t,i){this.setDimensions("height",t,i)},jBox.prototype.position=function(t){if(!t&&(t={}),t=jQuery.extend(!0,this.options,t),this.target=t.target||this.target||jQuery(window),!(this.target instanceof jQuery||"mouse"==this.target)&&(this.target=jQuery(this.target)),!this.target.length)return this;this.content.css({width:this._getInt(t.width,"width"),height:this._getInt(t.height,"height"),minWidth:this._getInt(t.minWidth,"width"),minHeight:this._getInt(t.minHeight,"height"),maxWidth:this._getInt(t.maxWidth,"width"),maxHeight:this._getInt(t.maxHeight,"height")}),this._setTitleWidth();var i=this._exposeDimensions();"mouse"!=this.target&&!this.target.data("jBox-"+this.id+"-fixed")&&this.target.data("jBox-"+this.id+"-fixed",this.target[0]!=jQuery(window)[0]&&("fixed"==this.target.css("position")||this.target.parents().filter(function(){return"fixed"==jQuery(this).css("position")}).length>0)?"fixed":"static");var s={x:jQuery(window).outerWidth(),y:jQuery(window).outerHeight(),top:t.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:jQuery(window).scrollTop(),left:t.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:jQuery(window).scrollLeft()};s.bottom=s.top+s.y,s.right=s.left+s.x;try{var o=this.target.offset()}catch(t){var o={top:0,left:0}}"mouse"!=this.target&&"fixed"==this.target.data("jBox-"+this.id+"-fixed")&&t.fixed&&(o.top=o.top-jQuery(window).scrollTop(),o.left=o.left-jQuery(window).scrollLeft());var e={x:"mouse"==this.target?12:this.target.outerWidth(),y:"mouse"==this.target?20:this.target.outerHeight(),top:"mouse"==this.target&&t.mouseTarget?t.mouseTarget.top:o?o.top:0,left:"mouse"==this.target&&t.mouseTarget?t.mouseTarget.left:o?o.left:0},n=t.outside&&!("center"==t.position.x&&"center"==t.position.y),a={x:s.x-t.adjustDistance.left-t.adjustDistance.right,y:s.y-t.adjustDistance.top-t.adjustDistance.bottom,left:n?e.left-jQuery(window).scrollLeft()-t.adjustDistance.left:0,right:n?s.x-e.left+jQuery(window).scrollLeft()-e.x-t.adjustDistance.right:0,top:n?e.top-jQuery(window).scrollTop()-this.options.adjustDistance.top:0,bottom:n?s.y-e.top+jQuery(window).scrollTop()-e.y-t.adjustDistance.bottom:0},h={x:"x"!=t.outside&&"xy"!=t.outside||"number"==jQuery.type(t.position.x)?null:t.position.x,y:"y"!=t.outside&&"xy"!=t.outside||"number"==jQuery.type(t.position.y)?null:t.position.y},r={x:!1,y:!1};if(h.x&&i.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),h.y&&i.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),t.responsiveWidth||t.responsiveHeight){var p=function(){if(t.responsiveWidth&&i.x>a[h.x||"x"]){var s=a[h.x||"x"]-(this.pointer&&n&&"x"==t.outside?this.pointer.dimensions.x:0)-parseInt(this.container.css("border-left-width"))-parseInt(this.container.css("border-right-width"));this.content.css({width:s>this.options.responsiveMinWidth?s:null,minWidth:sa[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0);var l=function(){if(t.responsiveHeight&&i.y>a[h.y||"y"]){var s=function(){if(!this.titleContainer&&!this.footer)return 0;if("none"==this.wrapper.css("display")){this.wrapper.css("display","block");var t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0);this.wrapper.css("display","none")}else var t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0);return t||0}.bind(this),o=a[h.y||"y"]-(this.pointer&&n&&"y"==t.outside?this.pointer.dimensions.y:0)-s()-parseInt(this.container.css("border-top-width"))-parseInt(this.container.css("border-bottom-width"));this.content.css({height:o>this.options.responsiveMinHeight?o:null}),this._setTitleWidth()}i=this._exposeDimensions()}.bind(this);t.responsiveHeight&&l(),t.responsiveHeight&&!r.x&&h.x&&i.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),t.adjustPosition&&"move"!=t.adjustPosition&&(r.x&&p(),r.y&&l())}var d={},u=function(s){if("number"==jQuery.type(t.position[s]))return void(d[t.attributes[s]]=t.position[s]);var o=t.attributes[s]="x"==s?"left":"top";return d[o]=e[o],"center"==t.position[s]?(d[o]+=Math.ceil((e[s]-i[s])/2),void("mouse"!=this.target&&this.target[0]&&this.target[0]==jQuery(window)[0]&&(d[o]+=.5*(t.adjustDistance[o]-t.adjustDistance[this._getOpp(o)])))):(o!=t.position[s]&&(d[o]+=e[s]-i[s]),void((t.outside==s||"xy"==t.outside)&&(d[o]+=i[s]*(o!=t.position[s]?1:-1))))}.bind(this);if(u("x"),u("y"),this.pointer&&"target"==t.pointTo&&"number"!=jQuery.type(t.position.x)&&"number"!=jQuery.type(t.position.y)){var c=0;switch(this.pointer.align){case"center":"center"!=t.position[this._getOpp(t.outside)]&&(c+=i[this._getOpp(t.outside)]/2);break;default:switch(t.position[this._getOpp(t.outside)]){case"center":c+=(i[this._getOpp(t.outside)]/2-this.pointer.dimensions[this._getOpp(t.outside)]/2)*(this.pointer.align==this._getTL(this.pointer.align)?1:-1);break;default:c+=this.pointer.align!=t.position[this._getOpp(t.outside)]?this.dimensions[this._getOpp(t.outside)]*(jQuery.inArray(this.pointer.align,["top","left"])!==-1?1:-1)+this.pointer.dimensions[this._getOpp(t.outside)]/2*(jQuery.inArray(this.pointer.align,["top","left"])!==-1?-1:1):this.pointer.dimensions[this._getOpp(t.outside)]/2*(jQuery.inArray(this.pointer.align,["top","left"])!==-1?1:-1)}}c*=t.position[this._getOpp(t.outside)]==this.pointer.alignAttribute?-1:1,c+=this.pointer.offset*(this.pointer.align==this._getOpp(this._getTL(this.pointer.align))?1:-1),d[this._getTL(this._getOpp(this.pointer.xy))]+=c}if(d[t.attributes.x]+=t.offset.x,d[t.attributes.y]+=t.offset.y,this.wrapper.css(d),t.adjustPosition){this.positionAdjusted&&(this.pointer&&this.wrapper.css("padding",0).css("padding-"+this._getOpp(this.outside),this.pointer.dimensions[this._getXY(this.outside)]).removeClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).addClass("jBox-pointerPosition-"+this.pointer.position),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+this._getOpp(this.outside)).css(this.pointer.margin),this.positionAdjusted=!1,this.flipped=!1);var g=s.top>d.top-(t.adjustDistance.top||0),m=s.rightd.left-(t.adjustDistance.left||0),x=y?"left":m?"right":null,j=g?"top":f?"bottom":null,b=x||j;if(b){var v=function(s){this.wrapper.css(this._getTL(s),d[this._getTL(s)]+(i[this._getXY(s)]+t.offset[this._getXY(s)]*("top"==s||"left"==s?-2:2)+e[this._getXY(s)])*("top"==s||"left"==s?1:-1)),this.pointer&&this.wrapper.removeClass("jBox-pointerPosition-"+this.pointer.position).addClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).css("padding",0).css("padding-"+s,this.pointer.dimensions[this._getXY(s)]),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+s),this.positionAdjusted=!0,this.flipped=!0}.bind(this);r.x&&v(this.options.position.x),r.y&&v(this.options.position.y);var B="x"==this._getXY(this.outside)?j:x;if(this.pointer&&"target"==t.pointTo&&"flip"!=t.adjustPosition&&this._getXY(B)==this._getOpp(this._getXY(this.outside))){if("center"==this.pointer.align)var _=i[this._getXY(B)]/2-this.pointer.dimensions[this._getOpp(this.pointer.xy)]/2-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))*(B!=this._getTL(B)?-1:1);else var _=B==this.pointer.alignAttribute?parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute)):i[this._getXY(B)]-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-this.pointer.dimensions[this._getXY(B)];spaceDiff=B==this._getTL(B)?s[this._getTL(B)]-d[this._getTL(B)]+t.adjustDistance[B]:(s[this._getOpp(this._getTL(B))]-d[this._getTL(B)]-t.adjustDistance[B]-i[this._getXY(B)])*-1,B==this._getOpp(this._getTL(B))&&d[this._getTL(B)]-spaceDiff<=_&&spaceDiff>0&&(this.pointer.element.css("margin-"+this.pointer.alignAttribute,parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-spaceDiff*(B!=this.pointer.alignAttribute?-1:1)),this.wrapper.css(this._getTL(B),d[this._getTL(B)]+spaceDiff*(B!=this._getTL(B)?-1:1)),this.positionAdjusted=!0)}}}return this._fireEvent("onPosition"),this},jBox.prototype.open=function(t){if(!t&&(t={}),this.isDestroyed)return!1;if(!this.wrapper&&this._create(),!this._styles&&(this._styles=jQuery("
").append(this._animationCSS).appendTo(jQuery("head"))),this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i=function(){this.source&&this.options.getTitle&&(this.source.attr(this.options.getTitle)&&this.setTitle(this.source.attr(this.options.getTitle)),!0),this.source&&this.options.getContent&&(this.source.data("jBox-getContent")?this.setContent(this.source.data("jBox-getContent"),!0):this.source.attr(this.options.getContent)?this.setContent(this.source.attr(this.options.getContent),!0):"html"==this.options.getContent?this.setContent(this.source.html(),!0):null),this._fireEvent("onOpen"),(this.options.ajax&&(this.options.ajax.url||this.source&&this.source.attr(this.options.ajax.getURL))&&(!this.ajaxLoaded||this.options.ajax.reload)||t.ajax&&(t.ajax.url||t.ajax.data))&&("strict"==this.options.ajax.reload||!this.source||!this.source.data("jBox-ajax-data")||t.ajax&&(t.ajax.url||t.ajax.data)?this.ajax(t.ajax||null,!0):this.setContent(this.source.data("jBox-ajax-data"))),(!this.positionedOnOpen||this.options.repositionOnOpen)&&this.position(t)&&(this.positionedOnOpen=!0),this.isClosing&&this._abortAnimation(),this.isOpen||(this.isOpen=!0,this.options.autoClose&&(this.options.delayClose=this.options.autoClose)&&this.close(),this._attachEvents(),this.options.blockScroll&&jQuery("body").addClass("jBox-blockScroll-"+this.id),
-this.options.overlay&&this._showOverlay(),this.options.animation&&!this.isClosing&&this._animate("open"),this.options.audio&&this.options.audio.open&&this.audio(this.options.audio.open,this.options.volume.open),this.options.fade?this.wrapper.stop().animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.isOpening=!0,this.wrapper.css({display:"block"})}.bind(this),always:function(){this.isOpening=!1,setTimeout(function(){this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)}.bind(this),10)}.bind(this)}):(this.wrapper.css({display:"block",opacity:1}),this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)))}.bind(this);return!this.options.delayOpen||this.isOpen||this.isClosing||t.ignoreDelay?i():this.timer=setTimeout(i,this.options.delayOpen),this},jBox.prototype.close=function(t){if(t||(t={}),this.isDestroyed||this.isClosing)return!1;if(this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i=function(){this._fireEvent("onClose"),this.isOpen&&(this.isOpen=!1,this._detachEvents(),this.options.blockScroll&&jQuery("body").removeClass("jBox-blockScroll-"+this.id),this.options.overlay&&this._hideOverlay(),this.options.animation&&!this.isOpening&&this._animate("close"),this.options.audio&&this.options.audio.close&&this.audio(this.options.audio.close,this.options.volume.close),this.options.fade?this.wrapper.stop().animate({opacity:0},{queue:!1,duration:this.options.fade,start:function(){this.isClosing=!0}.bind(this),complete:function(){this.wrapper.css({display:"none"}),this._fireEvent("onCloseComplete")}.bind(this),always:function(){this.isClosing=!1}.bind(this)}):(this.wrapper.css({display:"none",opacity:0}),this._fireEvent("onCloseComplete")))}.bind(this);return t.ignoreDelay?i():this.timer=setTimeout(i,Math.max(this.options.delayClose,10)),this},jBox.prototype.toggle=function(t){return this[this.isOpen?"close":"open"](t),this},jBox.prototype.disable=function(){return this.isDisabled=!0,this},jBox.prototype.enable=function(){return this.isDisabled=!1,this},jBox.prototype.hide=function(){return this.disable(),this.wrapper&&this.wrapper.css({display:"none"}),this},jBox.prototype.show=function(){return this.enable(),this.wrapper&&this.wrapper.css({display:"block"}),this},jBox.prototype.ajax=function(t,i){t||(t={}),jQuery.each([["getData","data"],["getURL","url"]],function(i,s){this.options.ajax[s[0]]&&!t[s[1]]&&this.source&&void 0!=this.source.attr(this.options.ajax[s[0]])&&(t[s[1]]=this.source.attr(this.options.ajax[s[0]])||"")}.bind(this));var s=jQuery.extend(!0,{},this.options.ajax);this.ajaxRequest&&this.ajaxRequest.abort();var o=t.beforeSend||s.beforeSend||function(){},e=t.complete||s.complete||function(){},n=t.success||s.success||function(){},a=t.error||s.error||function(){},h=jQuery.extend(!0,s,t);return h.beforeSend=function(){this.wrapper.addClass("jBox-loading"),h.spinner&&(this.spinnerDelay=setTimeout(function(){this.wrapper.addClass("jBox-loading-spinner"),h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.spinner=jQuery(h.spinner!==!0?h.spinner:'
').appendTo(this.container),this.titleContainer&&"absolute"==this.spinner.css("position")&&this.spinner.css({transform:"translateY("+.5*this.titleContainer.outerHeight()+"px)"})}.bind(this),""==this.content.html()?0:h.spinnerDelay||0)),o.bind(this)()}.bind(this),h.complete=function(t){this.spinnerDelay&&clearTimeout(this.spinnerDelay),this.wrapper.removeClass("jBox-loading jBox-loading-spinner jBox-loading-spinner-delay"),this.spinner&&this.spinner.length&&this.spinner.remove()&&h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.ajaxLoaded=!0,e.bind(this)(t)}.bind(this),h.success=function(t){h.setContent&&this.setContent(t,!0)&&(i?this.positionOnFadeComplete=!0:this.position()),h.setContent&&this.source&&this.source.data("jBox-ajax-data",t),n.bind(this)(t)}.bind(this),h.error=function(t){a.bind(this)(t)}.bind(this),this.ajaxRequest=jQuery.ajax(h),this},jBox.prototype.audio=function(t,i){if(!t)return this;if(!jBox._audio&&(jBox._audio={}),!jBox._audio[t]){var s=jQuery(" ");jQuery(" ",{src:t+".mp3"}).appendTo(s),jQuery(" ",{src:t+".ogg"}).appendTo(s),jBox._audio[t]=s[0]}jBox._audio[t].volume=Math.min((void 0!=i?i:100)/100,1);try{jBox._audio[t].pause(),jBox._audio[t].currentTime=0}catch(t){}return jBox._audio[t].play(),this},jBox._animationSpeeds={tada:1e3,tadaSmall:1e3,flash:500,shake:400,pulseUp:250,pulseDown:250,popIn:250,popOut:250,fadeIn:200,fadeOut:200,slideUp:400,slideRight:400,slideLeft:400,slideDown:400},jBox.prototype.animate=function(t,i){!i&&(i={}),!this.animationTimeout&&(this.animationTimeout={}),!i.element&&(i.element=this.wrapper),!i.element.data("jBox-animating-id")&&i.element.data("jBox-animating-id",jBox._getUniqueElementID()),i.element.data("jBox-animating")&&(i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),this.animationTimeout[i.element.data("jBox-animating-id")]&&clearTimeout(this.animationTimeout[i.element.data("jBox-animating-id")])),i.element.addClass("jBox-animated-"+t).data("jBox-animating","jBox-animated-"+t),this.animationTimeout[i.element.data("jBox-animating-id")]=setTimeout(function(){i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),i.complete&&i.complete()},jBox._animationSpeeds[t])},jBox.prototype.destroy=function(){return this.detach(),this.isOpen&&this.close({ignoreDelay:!0}),this.wrapper&&this.wrapper.remove(),this.overlay&&this.overlay.remove(),this._styles&&this._styles.remove(),this.isDestroyed=!0,this},jBox._getUniqueID=function(){var t=1;return function(){return t++}}(),jBox._getUniqueElementID=function(){var t=1;return function(){return t++}}(),jBox._pluginOptions={},jQuery.fn.jBox=function(t,i){return!t&&(t={}),!i&&(i={}),new jBox(t,jQuery.extend(i,{attach:this}))};
\ No newline at end of file
diff --git a/Source/plugins/Confirm/jBox.Confirm.min.js b/Source/plugins/Confirm/jBox.Confirm.min.js
deleted file mode 100644
index a7386ad..0000000
--- a/Source/plugins/Confirm/jBox.Confirm.min.js
+++ /dev/null
@@ -1 +0,0 @@
-jQuery(document).ready(function(){new jBoxPlugin("Confirm",{confirmButton:"Submit",cancelButton:"Cancel",confirm:null,cancel:null,closeOnConfirm:!0,target:window,addClass:"jBox-Modal",fixed:!0,attach:"[data-confirm]",getContent:"data-confirm",content:"Do you really want to do this?",minWidth:360,maxWidth:500,blockScroll:!0,closeOnEsc:!0,closeOnClick:!1,closeButton:!1,overlay:!0,animation:"zoomIn",preventDefault:!0,_onAttach:function(t){if(!this.options.confirm){var o=t.attr("onclick")?t.attr("onclick"):t.attr("href")?t.attr("target")?'window.open("'+t.attr("href")+'", "'+t.attr("target")+'");':'window.location.href = "'+t.attr("href")+'";':"";t.prop("onclick",null).data("jBox-Confirm-submit",o)}},_onCreated:function(){this.footer=jQuery(''),jQuery('
').html(this.options.cancelButton).click(function(){this.options.cancel&&this.options.cancel(),this.close()}.bind(this)).appendTo(this.footer),this.submitButton=jQuery('
').html(this.options.confirmButton).appendTo(this.footer),this.footer.appendTo(this.container)},_onOpen:function(){this.submitButton.off("click.jBox-Confirm"+this.id).on("click.jBox-Confirm"+this.id,function(){this.options.confirm?this.options.confirm():eval(this.source.data("jBox-Confirm-submit")),this.options.closeOnConfirm&&this.close()}.bind(this))}})});
\ No newline at end of file
diff --git a/Source/plugins/Image/jBox.Image.js b/Source/plugins/Image/jBox.Image.js
deleted file mode 100644
index 21e6cba..0000000
--- a/Source/plugins/Image/jBox.Image.js
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * jBox Image plugin: Adds a lightbox to your images
- *
- * Author: Stephan Wagner (https://stephanwagner.me)
- *
- * License: MIT (https://opensource.org/licenses/MIT)
- *
- * Requires: jBox (https://code.jboxcdn.com/jBox.min.js)
- */
-
-jQuery(document).ready(function () {
-
- new jBoxPlugin('Image', {
-
-
- // Options (https://stephanwagner.me/jBox/options#options-confirm)
-
- src: 'href', // The attribute where jBox gets the image source from, e.g. href="/path_to_image/image.jpg"
- gallery: 'data-jbox-image', // The attribute to set the galleries, e.g. data-jbox-image="gallery1"
- imageLabel: 'title', // The attribute where jBox gets the image label from, e.g. title="My label"
- imageFade: 360, // The fade duration for images in ms
- imageSize: 'contain', // How to display the images. Use CSS background-position values, e.g. 'cover', 'contain', 'auto', 'initial', '50% 50%'
- imageCounter: false, // Set to true to add an image counter, e.g. 4/20
- imageCounterSeparator: '/', // HTML to separate the current image number from all image numbers, e.g. '/' or ' of '
- target: window,
- attach: '[data-jbox-image]',
- fixed: true,
- blockScroll: true,
- closeOnEsc: true,
- closeOnClick: 'button',
- closeButton: true,
- overlay: true,
- animation: 'zoomIn',
- preventDefault: true,
- width: '100%',
- height: '100%',
- adjustDistance: {
- top: 40,
- right: 5,
- bottom: 40,
- left: 5
- },
-
-
- // Triggered when jBox is initialized
-
- _onInit: function ()
- {
- // Initial images and z-index
- this.images = this.currentImage = {};
- this.imageZIndex = 1;
-
- // Loop through images, sort and save in global variable
- this.attachedElements && jQuery.each(this.attachedElements, function (index, item)
- {
- item = jQuery(item);
-
- // Abort if the item was added to a gallery already
- if (item.data('jBox-image-gallery')) return;
-
- // Add item to a gallery
- var gallery = item.attr(this.options.gallery) || 'default';
- !this.images[gallery] && (this.images[gallery] = []);
- this.images[gallery].push({src: item.attr(this.options.src), label: (item.attr(this.options.imageLabel) || '')});
-
- // Remove the title attribute so it won't show the browsers tooltip
- this.options.imageLabel == 'title' && item.removeAttr('title');
-
- // Store data in source element for easy access
- item.data('jBox-image-gallery', gallery);
- item.data('jBox-image-id', (this.images[gallery].length - 1));
-
- }.bind(this));
-
- // Helper to inject the image into content area
- var appendImage = function (gallery, id, preload, open, error)
- {
- // Abort if image was appended already
- if (jQuery('#jBox-image-' + gallery + '-' + id).length) return;
-
- // Create image container
- var image = jQuery('
', {
- id: 'jBox-image-' + gallery + '-' + id,
- 'class': 'jBox-image-container' + (error ? ' jBox-image-not-found' : '') + (!open && !preload ? ' jBox-image-' + gallery + '-current' : '')
- }).css({
- backgroundImage: error ? '' : 'url("' + this.images[gallery][id].src + '")',
- backgroundSize: this.options.imageSize,
- opacity: (open ? 1 : 0),
- zIndex: (preload ? 0 : this.imageZIndex++)
- }).appendTo(this.content);
-
- // Create labels
- jQuery('
', {
- id: 'jBox-image-label-' + gallery + '-' + id,
- 'class': 'jBox-image-label' + (open ? ' active' : '')
- }).html(this.images[gallery][id].label).click(function () { $(this).toggleClass('expanded'); }).appendTo(this.imageLabel);
-
- // Show image
- !open && !preload && image.animate({opacity: 1}, this.options.imageFade);
-
- }.bind(this);
-
- // Helper to show new image label
- var showLabel = function (gallery, id)
- {
- jQuery('.jBox-image-label.active').removeClass('active expanded');
- jQuery('#jBox-image-label-' + gallery + '-' + id).addClass('active');
- };
-
- // Show images when they are loaded or load them if not
- this.showImage = function (img)
- {
- // Get the gallery and the image id from the next or the previous image
- if (img != 'open') {
- var gallery = this.currentImage.gallery;
- var id = this.currentImage.id + (1 * (img == 'prev') ? -1 : 1);
- id = id > (this.images[gallery].length - 1) ? 0 : (id < 0 ? (this.images[gallery].length - 1) : id);
-
- // Or get image data from source element
- } else {
- var gallery = this.source.data('jBox-image-gallery');
- var id = this.source.data('jBox-image-id');
-
- // Remove or show the next and prev buttons
- jQuery('.jBox-image-pointer-prev, .jBox-image-pointer-next').css({display: (this.images[gallery].length > 1 ? 'block' : 'none')});
- }
-
- // If there is a current image already shown, hide it
- if (jQuery('.jBox-image-' + gallery + '-current').length) {
- jQuery('.jBox-image-' + gallery + '-current').removeClass('jBox-image-' + gallery + '-current').animate({opacity: 0}, (img == 'open') ? 0 : this.options.imageFade);
- }
-
- // Set new current image
- this.currentImage = {gallery: gallery, id: id};
-
- // Show image if it already exists
- if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
- jQuery('#jBox-image-' + gallery + '-' + id).addClass('jBox-image-' + gallery + '-current').css({zIndex: this.imageZIndex++, opacity: 0}).animate({opacity: 1}, (img == 'open') ? 0 : this.options.imageFade);
- showLabel(gallery, id);
-
- // Load image
- } else {
- this.wrapper.addClass('jBox-image-loading');
-
- jQuery(' ').each(function ()
- {
- var tmpImg = new Image();
- tmpImg.onload = function ()
- {
- appendImage(gallery, id, false);
- showLabel(gallery, id);
- this.wrapper.removeClass('jBox-image-loading');
- }.bind(this);
-
- tmpImg.onerror = function () {
- appendImage(gallery, id, false, null, true);
- showLabel(gallery, id);
- this.wrapper.removeClass('jBox-image-loading');
- }.bind(this);
-
- tmpImg.src = this.images[gallery][id].src;
- }.bind(this));
- }
-
- // Update the image counter numbers
- if (this.imageCounter) {
- if (this.images[gallery].length > 1) {
- this.wrapper.addClass('jBox-image-has-counter');
- this.imageCounter.find('.jBox-image-counter-all').html(this.images[gallery].length);
- this.imageCounter.find('.jBox-image-counter-current').html(id + 1);
- } else {
- this.wrapper.removeClass('jBox-image-has-counter');
- }
- }
-
- // Preload next image
- var next_id = id + 1;
- next_id = next_id > (this.images[gallery].length - 1) ? 0 : (next_id < 0 ? (this.images[gallery].length - 1) : next_id);
-
- (!jQuery('#jBox-image-' + gallery + '-' + next_id).length) && jQuery(' ').each(function ()
- {
- var tmpImg = new Image();
- tmpImg.onload = function ()
- {
- appendImage(gallery, next_id, true);
- }.bind(this);
-
- tmpImg.onerror = function ()
- {
- appendImage(gallery, next_id, true, null, true);
- }.bind(this);
-
- tmpImg.src = this.images[gallery][next_id].src;
- }.bind(this));
- };
- },
-
-
- // Triggered when jBox was created
-
- _onCreated: function ()
- {
- // Append image label containers
- this.imageLabel = jQuery('
', {'class': 'jBox-image-label-container'}).appendTo(this.wrapper);
- this.imageLabel.append(jQuery('
', {'class': 'jBox-image-pointer-prev', click: function () { this.showImage('prev'); }.bind(this)})).append(jQuery('
', {'class': 'jBox-image-pointer-next', click: function () { this.showImage('next'); }.bind(this)}));
-
- // Creating the image counter containers
- if (this.options.imageCounter) {
- this.imageCounter = jQuery('
', {'class': 'jBox-image-counter-container'}).appendTo(this.wrapper);
- this.imageCounter.append(jQuery(' ', {'class': 'jBox-image-counter-current'})).append(jQuery(' ').html(this.options.imageCounterSeparator)).append(jQuery(' ', {'class': 'jBox-image-counter-all'}));
- }
- },
-
-
- // Triggered when jBox opens
-
- _onOpen: function ()
- {
- // Add key events
- jQuery(document).on('keyup.jBox-Image-' + this.id, function (ev) {
- (ev.keyCode == 37) && this.showImage('prev');
- (ev.keyCode == 39) && this.showImage('next');
- }.bind(this));
-
- // Load the image from the attached element
- this.showImage('open');
- },
-
-
- // Triggered when jBox closes
-
- _onClose: function ()
- {
- // Remove key events
- jQuery(document).off('keyup.jBox-Image-' + this.id);
- },
-
-
- // Triggered when jBox finished closing
-
- _onCloseComplete: function ()
- {
- // Hide all image containers
- this.wrapper.find('.jBox-image-container').css('opacity', 0);
- }
-
- });
-
-});
\ No newline at end of file
diff --git a/Source/plugins/Image/jBox.Image.min.js b/Source/plugins/Image/jBox.Image.min.js
deleted file mode 100644
index 9cb6c27..0000000
--- a/Source/plugins/Image/jBox.Image.min.js
+++ /dev/null
@@ -1 +0,0 @@
-jQuery(document).ready(function(){new jBoxPlugin("Image",{src:"href",gallery:"data-jbox-image",imageLabel:"title",imageFade:360,imageSize:"contain",imageCounter:!1,imageCounterSeparator:"/",target:window,attach:"[data-jbox-image]",fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"button",closeButton:!0,overlay:!0,animation:"zoomIn",preventDefault:!0,width:"100%",height:"100%",adjustDistance:{top:40,right:5,bottom:40,left:5},_onInit:function(){this.images=this.currentImage={},this.imageZIndex=1,this.attachedElements&&jQuery.each(this.attachedElements,function(e,i){if(i=jQuery(i),!i.data("jBox-image-gallery")){var a=i.attr(this.options.gallery)||"default";!this.images[a]&&(this.images[a]=[]),this.images[a].push({src:i.attr(this.options.src),label:i.attr(this.options.imageLabel)||""}),"title"==this.options.imageLabel&&i.removeAttr("title"),i.data("jBox-image-gallery",a),i.data("jBox-image-id",this.images[a].length-1)}}.bind(this));var e=function(e,i,a,t,n){if(!jQuery("#jBox-image-"+e+"-"+i).length){var o=jQuery("
",{id:"jBox-image-"+e+"-"+i,class:"jBox-image-container"+(n?" jBox-image-not-found":"")+(t||a?"":" jBox-image-"+e+"-current")}).css({backgroundImage:n?"":'url("'+this.images[e][i].src+'")',backgroundSize:this.options.imageSize,opacity:t?1:0,zIndex:a?0:this.imageZIndex++}).appendTo(this.content);jQuery("
",{id:"jBox-image-label-"+e+"-"+i,class:"jBox-image-label"+(t?" active":"")}).html(this.images[e][i].label).click(function(){$(this).toggleClass("expanded")}).appendTo(this.imageLabel),!t&&!a&&o.animate({opacity:1},this.options.imageFade)}}.bind(this),i=function(e,i){jQuery(".jBox-image-label.active").removeClass("active expanded"),jQuery("#jBox-image-label-"+e+"-"+i).addClass("active")};this.showImage=function(a){if("open"!=a){var t=this.currentImage.gallery,n=this.currentImage.id+(1*("prev"==a)?-1:1);n=n>this.images[t].length-1?0:n<0?this.images[t].length-1:n}else{var t=this.source.data("jBox-image-gallery"),n=this.source.data("jBox-image-id");jQuery(".jBox-image-pointer-prev, .jBox-image-pointer-next").css({display:this.images[t].length>1?"block":"none"})}jQuery(".jBox-image-"+t+"-current").length&&jQuery(".jBox-image-"+t+"-current").removeClass("jBox-image-"+t+"-current").animate({opacity:0},"open"==a?0:this.options.imageFade),this.currentImage={gallery:t,id:n},jQuery("#jBox-image-"+t+"-"+n).length?(jQuery("#jBox-image-"+t+"-"+n).addClass("jBox-image-"+t+"-current").css({zIndex:this.imageZIndex++,opacity:0}).animate({opacity:1},"open"==a?0:this.options.imageFade),i(t,n)):(this.wrapper.addClass("jBox-image-loading"),jQuery(' ').each(function(){var a=new Image;a.onload=function(){e(t,n,!1),i(t,n),this.wrapper.removeClass("jBox-image-loading")}.bind(this),a.onerror=function(){e(t,n,!1,null,!0),i(t,n),this.wrapper.removeClass("jBox-image-loading")}.bind(this),a.src=this.images[t][n].src}.bind(this))),this.imageCounter&&(this.images[t].length>1?(this.wrapper.addClass("jBox-image-has-counter"),this.imageCounter.find(".jBox-image-counter-all").html(this.images[t].length),this.imageCounter.find(".jBox-image-counter-current").html(n+1)):this.wrapper.removeClass("jBox-image-has-counter"));var o=n+1;o=o>this.images[t].length-1?0:o<0?this.images[t].length-1:o,!jQuery("#jBox-image-"+t+"-"+o).length&&jQuery(' ').each(function(){var i=new Image;i.onload=function(){e(t,o,!0)}.bind(this),i.onerror=function(){e(t,o,!0,null,!0)}.bind(this),i.src=this.images[t][o].src}.bind(this))}},_onCreated:function(){this.imageLabel=jQuery("
",{class:"jBox-image-label-container"}).appendTo(this.wrapper),this.imageLabel.append(jQuery("
",{class:"jBox-image-pointer-prev",click:function(){this.showImage("prev")}.bind(this)})).append(jQuery("
",{class:"jBox-image-pointer-next",click:function(){this.showImage("next")}.bind(this)})),this.options.imageCounter&&(this.imageCounter=jQuery("
",{class:"jBox-image-counter-container"}).appendTo(this.wrapper),this.imageCounter.append(jQuery(" ",{class:"jBox-image-counter-current"})).append(jQuery(" ").html(this.options.imageCounterSeparator)).append(jQuery(" ",{class:"jBox-image-counter-all"})))},_onOpen:function(){jQuery(document).on("keyup.jBox-Image-"+this.id,function(e){37==e.keyCode&&this.showImage("prev"),39==e.keyCode&&this.showImage("next")}.bind(this)),this.showImage("open")},_onClose:function(){jQuery(document).off("keyup.jBox-Image-"+this.id)},_onCloseComplete:function(){this.wrapper.find(".jBox-image-container").css("opacity",0)}})});
\ No newline at end of file
diff --git a/Source/plugins/Notice/jBox.Notice.css b/Source/plugins/Notice/jBox.Notice.css
deleted file mode 100644
index 727ab25..0000000
--- a/Source/plugins/Notice/jBox.Notice.css
+++ /dev/null
@@ -1,80 +0,0 @@
-
-.jBox-Notice {
- transition: margin .2s;
-}
-
-.jBox-Notice .jBox-container {
- border-radius: 3px;
- box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, .25), inset -1px -1px 0 0 rgba(0, 0, 0, .1);
-}
-
-.jBox-Notice .jBox-content {
- border-radius: 3px;
- padding: 12px 20px;
-}
-
-.jBox-Notice .jBox-title {
- padding: 12px 20px 0;
- font-weight: bold;
-}
-
-.jBox-hasTitle.jBox-Notice .jBox-content {
- padding-top: 5px;
-}
-
-.jBox-Notice-black .jBox-container {
- color: #fff;
- background: #000;
-}
-
-.jBox-Notice-gray .jBox-container {
- color: #333;
- background: #f6f6f6;
-}
-
-.jBox-Notice-red .jBox-container {
- color: #fff;
- background: #d00;
-}
-
-.jBox-Notice-green .jBox-container {
- color: #fff;
- background: #5d0;
-}
-
-.jBox-Notice-blue .jBox-container {
- color: #fff;
- background: #07d;
-}
-
-.jBox-Notice-yellow .jBox-container {
- color: #000;
- background: #fd0;
-}
-
-@media (max-width: 768px) {
-
- .jBox-Notice .jBox-content {
- padding: 10px 15px;
- }
-
- .jBox-Notice .jBox-title {
- padding: 10px 15px 0;
- }
-
-}
-
-@media (max-width: 500px) {
-
- .jBox-Notice .jBox-content {
- padding: 8px 10px;
- }
-
- .jBox-Notice .jBox-title {
- padding: 8px 10px 0;
- }
-
- .jBox-hasTitle.jBox-Notice .jBox-content {
- padding-top: 0;
- }
-}
\ No newline at end of file
diff --git a/Source/plugins/Notice/jBox.Notice.min.js b/Source/plugins/Notice/jBox.Notice.min.js
deleted file mode 100644
index e9688e2..0000000
--- a/Source/plugins/Notice/jBox.Notice.min.js
+++ /dev/null
@@ -1 +0,0 @@
-jQuery(document).ready(function(){new jBoxPlugin("Notice",{color:null,stack:!0,stackSpacing:10,autoClose:6e3,attributes:{x:"right",y:"top"},position:{x:15,y:15},responsivePositions:{500:{x:5,y:5},768:{x:10,y:10}},target:window,fixed:!0,animation:"zoomIn",closeOnClick:"box",zIndex:12e3,_onInit:function(){this.defaultNoticePosition=jQuery.extend({},this.options.position),this._adjustNoticePositon=function(){var t=jQuery(window),i={x:t.width(),y:t.height()};this.options.position=jQuery.extend({},this.defaultNoticePosition),jQuery.each(this.options.responsivePositions,function(t,o){if(i.x<=t)return this.options.position=o,!1}.bind(this)),this.options.adjustDistance={top:this.options.position.y,right:this.options.position.x,bottom:this.options.position.y,left:this.options.position.x}},this.options.content instanceof jQuery&&(this.options.content=this.options.content.clone().attr("id","")),jQuery(window).on("resize.responsivejBoxNotice-"+this.id,function(t){this.isOpen&&this._adjustNoticePositon()}.bind(this)),this.open()},_onCreated:function(){this.wrapper.addClass("jBox-Notice-color jBox-Notice-"+(this.options.color||"gray")),this.wrapper.data("jBox-Notice-position",this.options.attributes.x+"-"+this.options.attributes.y)},_onOpen:function(){this._adjustNoticePositon(),jQuery.each(jQuery(".jBox-Notice"),function(t,i){if(i=jQuery(i),i.attr("id")!=this.id&&i.data("jBox-Notice-position")==this.options.attributes.x+"-"+this.options.attributes.y){if(!this.options.stack)return void i.data("jBox").close({ignoreDelay:!0});var o=(i.data("jBoxNoticeMargin")?parseInt(i.data("jBoxNoticeMargin")):parseInt(i.css("margin-"+this.options.attributes.y)))+this.wrapper.outerHeight()+this.options.stackSpacing;i.data("jBoxNoticeMargin",o),i.css("margin-"+this.options.attributes.y,o)}}.bind(this))},_onCloseComplete:function(){this.destroy()}})});
\ No newline at end of file
diff --git a/Source/audio/LICENCE.txt b/assets/audio/LICENCE.txt
similarity index 100%
rename from Source/audio/LICENCE.txt
rename to assets/audio/LICENCE.txt
diff --git a/Source/audio/beep1.mp3 b/assets/audio/beep1.mp3
similarity index 100%
rename from Source/audio/beep1.mp3
rename to assets/audio/beep1.mp3
diff --git a/Source/audio/beep1.ogg b/assets/audio/beep1.ogg
similarity index 100%
rename from Source/audio/beep1.ogg
rename to assets/audio/beep1.ogg
diff --git a/Source/audio/beep2.mp3 b/assets/audio/beep2.mp3
similarity index 100%
rename from Source/audio/beep2.mp3
rename to assets/audio/beep2.mp3
diff --git a/Source/audio/beep2.ogg b/assets/audio/beep2.ogg
similarity index 100%
rename from Source/audio/beep2.ogg
rename to assets/audio/beep2.ogg
diff --git a/Source/audio/beep3.mp3 b/assets/audio/beep3.mp3
similarity index 100%
rename from Source/audio/beep3.mp3
rename to assets/audio/beep3.mp3
diff --git a/Source/audio/beep3.ogg b/assets/audio/beep3.ogg
similarity index 100%
rename from Source/audio/beep3.ogg
rename to assets/audio/beep3.ogg
diff --git a/Source/audio/bling1.mp3 b/assets/audio/bling1.mp3
similarity index 100%
rename from Source/audio/bling1.mp3
rename to assets/audio/bling1.mp3
diff --git a/Source/audio/bling1.ogg b/assets/audio/bling1.ogg
similarity index 100%
rename from Source/audio/bling1.ogg
rename to assets/audio/bling1.ogg
diff --git a/Source/audio/bling2.mp3 b/assets/audio/bling2.mp3
similarity index 100%
rename from Source/audio/bling2.mp3
rename to assets/audio/bling2.mp3
diff --git a/Source/audio/bling2.ogg b/assets/audio/bling2.ogg
similarity index 100%
rename from Source/audio/bling2.ogg
rename to assets/audio/bling2.ogg
diff --git a/Source/audio/bling3.mp3 b/assets/audio/bling3.mp3
similarity index 100%
rename from Source/audio/bling3.mp3
rename to assets/audio/bling3.mp3
diff --git a/Source/audio/bling3.ogg b/assets/audio/bling3.ogg
similarity index 100%
rename from Source/audio/bling3.ogg
rename to assets/audio/bling3.ogg
diff --git a/Source/audio/bling4.mp3 b/assets/audio/bling4.mp3
similarity index 100%
rename from Source/audio/bling4.mp3
rename to assets/audio/bling4.mp3
diff --git a/Source/audio/bling4.ogg b/assets/audio/bling4.ogg
similarity index 100%
rename from Source/audio/bling4.ogg
rename to assets/audio/bling4.ogg
diff --git a/Source/audio/bling5.mp3 b/assets/audio/bling5.mp3
similarity index 100%
rename from Source/audio/bling5.mp3
rename to assets/audio/bling5.mp3
diff --git a/Source/audio/bling5.ogg b/assets/audio/bling5.ogg
similarity index 100%
rename from Source/audio/bling5.ogg
rename to assets/audio/bling5.ogg
diff --git a/Source/audio/blop.mp3 b/assets/audio/blop.mp3
similarity index 100%
rename from Source/audio/blop.mp3
rename to assets/audio/blop.mp3
diff --git a/Source/audio/blop.ogg b/assets/audio/blop.ogg
similarity index 100%
rename from Source/audio/blop.ogg
rename to assets/audio/blop.ogg
diff --git a/Source/audio/boop1.mp3 b/assets/audio/boop1.mp3
similarity index 100%
rename from Source/audio/boop1.mp3
rename to assets/audio/boop1.mp3
diff --git a/Source/audio/boop1.ogg b/assets/audio/boop1.ogg
similarity index 100%
rename from Source/audio/boop1.ogg
rename to assets/audio/boop1.ogg
diff --git a/Source/audio/boop2.mp3 b/assets/audio/boop2.mp3
similarity index 100%
rename from Source/audio/boop2.mp3
rename to assets/audio/boop2.mp3
diff --git a/Source/audio/boop2.ogg b/assets/audio/boop2.ogg
similarity index 100%
rename from Source/audio/boop2.ogg
rename to assets/audio/boop2.ogg
diff --git a/Source/audio/boop3.mp3 b/assets/audio/boop3.mp3
similarity index 100%
rename from Source/audio/boop3.mp3
rename to assets/audio/boop3.mp3
diff --git a/Source/audio/boop3.ogg b/assets/audio/boop3.ogg
similarity index 100%
rename from Source/audio/boop3.ogg
rename to assets/audio/boop3.ogg
diff --git a/demo/es6/css/demo.css b/demo/es6/css/demo.css
new file mode 100755
index 0000000..ab5a160
--- /dev/null
+++ b/demo/es6/css/demo.css
@@ -0,0 +1,233 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ position: relative;
+ font-family: Roboto, sans-serif;
+ font-size: 17px;
+ line-height: 1.4;
+ color: #222;
+ background: #fff;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: none;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+* {
+ outline: none;
+ box-sizing: border-box;
+}
+
+p {
+ margin: 0 0 15px;
+}
+
+p:last-child {
+ margin-bottom: 0;
+}
+
+h2 {
+ margin: 0;
+ font-size: 22px;
+ font-weight: normal;
+}
+
+main {
+ padding: 20px 0;
+}
+
+.container {
+ position: relative;
+ width: calc(100% - 60px);
+ max-width: 1000px;
+ margin: auto;
+}
+
+@media (max-width: 768px) {
+ .container {
+ width: calc(100% - 30px);
+ }
+}
+
+/* Target elements */
+
+.targets-wrapper {
+ margin: 0 -5px;
+ padding: 10px 0 20px;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.target,
+.target-click,
+.target-notice {
+ cursor: default;
+ font-size: 14px;
+ line-height: 50px;
+ height: 52px;
+ border-radius: 4px;
+ overflow: hidden;
+ border: 2px solid #e2e2e2;
+ background: #fafafa;
+ text-align: center;
+ font-weight: 500;
+ position: relative;
+ text-transform: uppercase;
+ width: calc(25% - 10px);
+ margin: 5px;
+ transition: border-color .2s, background-color .2s;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.target:hover,
+.target-click:hover,
+.target-notice:hover {
+ border-color: #bbb;
+ background-color: #eee;
+}
+
+.target-click,
+.target-notice {
+ cursor: pointer;
+}
+
+.target.active,
+.target-click.active,
+.target-notice.active {
+ color: #49d;
+}
+
+@media (max-width: 768px) {
+
+ .target,
+ .target-click,
+ .target-notice {
+ width: calc(50% - 10px);
+ }
+}
+
+.demo-img {
+ width: calc(25% - 10px);
+ margin: 5px;
+}
+
+@media (max-width: 500px) {
+ .demo-img {
+ width: calc(50% - 10px);
+ }
+}
+
+.demo-img>img {
+ border: 4px solid #e2e2e2;
+ border-radius: 4px;
+ width: 100%;
+ height: auto;
+ filter: grayscale(100%);
+ transition: filter .2s, border-color .2s;
+}
+
+.demo-img:hover>img {
+ filter: none;
+ border-color: #bbb;
+}
+
+@media (max-width: 768px) {
+ .demo-img>img {
+ border-width: 2px;
+ }
+}
+
+/* Header */
+
+header {
+ height: 50px;
+ line-height: 50px;
+ font-size: 17px;
+ background: #000;
+ color: #aaa;
+ box-shadow: 0 0 3px rgba(0, 0, 0, .6);
+}
+
+header a {
+ margin-right: 20px;
+ color: #aaa;
+ text-decoration: none;
+ transition: color .2s;
+}
+
+header a:last-child,
+header a:nth-child(2) {
+ margin-right: 0;
+}
+
+header a.active,
+header a:hover {
+ color: #fff;
+ text-decoration: none;
+}
+
+#stephan {
+ display: block;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ width: 40px;
+ height: 40px;
+ transform: translateY(-50%);
+ border-radius: 3px;
+ background: no-repeat center center url(https://stephanwagner.me/img/stephan.jpg);
+ background-size: 100%;
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .3);
+}
+
+#stephan>span {
+ font-size: 0;
+ line-height: 0;
+ white-space: nowrap;
+ position: absolute;
+ top: 50%;
+ right: 50%;
+ pointer-events: none;
+ transition: font-size .2s, margin .2s, opacity .2s, line-height .2s;
+ opacity: 0;
+}
+
+#stephan:hover>span {
+ opacity: 1;
+ font-size: 17px;
+ margin-right: 40px;
+}
+
+@media (max-width: 500px) {
+ #stephan>span {
+ display: none;
+ }
+}
+
+/* jBox styles */
+
+.ajax-sending {
+ color: #49d;
+}
+
+.ajax-complete {
+ color: #390;
+}
+
+.ajax-success tt {
+ color: #666;
+ display: block;
+ padding-top: 10px;
+ font-size: 14px;
+}
+
+.ajax-error {
+ color: #d00;
+}
diff --git a/demo/es6/css/normalize.css b/demo/es6/css/normalize.css
new file mode 100755
index 0000000..c469989
--- /dev/null
+++ b/demo/es6/css/normalize.css
@@ -0,0 +1,349 @@
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+ ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+ html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+ display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ border-bottom: none; /* 1 */
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+ border-style: none;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+ overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+ text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box; /* 1 */
+ color: inherit; /* 2 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ white-space: normal; /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/* Misc
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+ display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+ display: none;
+}
diff --git a/demo/es6/index.html b/demo/es6/index.html
new file mode 100644
index 0000000..6ea6209
--- /dev/null
+++ b/demo/es6/index.html
@@ -0,0 +1,71 @@
+
+
+
+ jBox ES6 demos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tooltip
+
+
+
Hover me
+
Hover me
+
Hover me
+
Hover me
+
Hover me
+
Hover me
+
Click me
+
Click me
+
+
+ Modal
+
+
+
Click me
+
Click me
+
Click me
+
Click me
+
+
+ Notice
+
+
+
Click me
+
Click me
+
Click me
+
Click me
+
+
+ Image
+
+
+
+
+
+
+
diff --git a/Demo/Demo.js b/demo/es6/index.js
similarity index 57%
rename from Demo/Demo.js
rename to demo/es6/index.js
index 28d3c50..380042f 100644
--- a/Demo/Demo.js
+++ b/demo/es6/index.js
@@ -1,15 +1,14 @@
+import jQuery from 'jquery';
+import jBox from 'jbox';
+import 'jbox/dist/jBox.all.css';
-$(document).ready(function() {
-
-
-/* Tooltip */
+// Tooltip
new jBox('Tooltip', {
attach: '#Tooltip-1',
content: 'This is a basic jBox tooltip'
});
-
new jBox('Tooltip', {
attach: '#Tooltip-2',
theme: 'TooltipBorderThick',
@@ -24,15 +23,13 @@ new jBox('Tooltip', {
animation: 'move'
});
-
new jBox('Tooltip', {
attach: '#Tooltip-3',
theme: 'TooltipDark',
animation: 'zoomOut',
- content: 'Use themes to change appearance',
+ content: 'Use themes to change appearance'
});
-
new jBox('Tooltip', {
attach: '#Tooltip-4',
width: 300,
@@ -41,31 +38,31 @@ new jBox('Tooltip', {
delayOpen: 1000,
delayClose: 2000,
content: 'This tooltip waits 1 second to open and closes after 2 seconds',
- onOpen: function() {
+ onOpen: function () {
this.source.removeClass('active').html('Hover me');
},
- onClose: function() {
+ onClose: function () {
this.source.removeClass('active').html('Hover me');
}
});
-
new jBox('Mouse', {
attach: '#Tooltip-5',
- position: {x: 'right', y: 'bottom'},
+ position: {
+ x: 'right',
+ y: 'bottom'
+ },
content: 'I will follow you!'
});
-
new jBox('Tooltip', {
attach: '#Tooltip-6',
width: 280,
closeOnMouseleave: true,
animation: 'zoomIn',
- content: 'I won\'t close when you move your mouse over me'
+ content: "I won't close when you move your mouse over me"
});
-
new jBox('Tooltip', {
attach: '#Tooltip-7',
target: '#Tooltip-1',
@@ -84,22 +81,22 @@ new jBox('Tooltip', {
offset: {
x: 25
},
- content: 'You can position your tooltips at any element. Scroll up and down to see this tooltip flip position!',
- onOpen: function() {
+ content:
+ 'You can position your tooltips at any element. Scroll up and down to see this tooltip flip position!',
+ onOpen: function () {
this.source.addClass('active').html('Now scroll');
},
- onClose: function() {
+ onClose: function () {
this.source.removeClass('active').html('Click me');
}
});
-
new jBox('Tooltip', {
attach: '#Tooltip-8',
theme: 'TooltipBorder',
trigger: 'click',
width: 200,
- height: ($(window).height() - 160),
+ height: jQuery(window).height() - 160,
adjustTracker: true,
closeOnClick: 'body',
closeOnEsc: true,
@@ -109,27 +106,26 @@ new jBox('Tooltip', {
y: 'center'
},
outside: 'x',
- content: 'Scroll up and down or resize your browser, I will adjust my position! Press [ESC] or click anywhere to close.',
- onOpen: function() {
+ content:
+ 'Scroll up and down or resize your browser, I will adjust my position! Press [ESC] or click anywhere to close.',
+ onOpen: function () {
this.source.addClass('active').html('Now scroll');
},
- onClose: function() {
+ onClose: function () {
this.source.removeClass('active').html('Click me');
}
});
-
-/* Modal */
-
+// Modal
new jBox('Modal', {
attach: '#Modal-1',
height: 200,
- title: 'I\'m a basic jBox modal window',
- content: 'Try to scroll ...it\'s blocked. Press [ESC] or click anywhere to close.
'
+ title: "I'm a basic jBox modal window",
+ content:
+ 'Try to scroll ...it\'s blocked. Press [ESC] or click anywhere to close.
'
});
-
new jBox('Modal', {
attach: '#Modal-2',
width: 350,
@@ -145,7 +141,6 @@ new jBox('Modal', {
repositionOnOpen: false
});
-
new jBox('Modal', {
attach: '#Modal-3',
width: 450,
@@ -154,66 +149,64 @@ new jBox('Modal', {
animation: false,
title: 'AJAX request',
ajax: {
- url: 'https://ajaxresponse.com/2',
+ url: 'https://reqres.in/api/users?delay=2',
data: {
id: '1982',
name: 'Stephan Wagner'
},
+ method: 'post',
reload: 'strict',
setContent: false,
- beforeSend: function() {
+ beforeSend: function () {
this.setContent('');
this.setTitle('Sending AJAX request...
');
},
- complete: function(response) {
+ complete: function () {
this.setTitle('AJAX request complete
');
},
- success: function(response) {
- this.setContent('Response:' + response + '
');
+ success: function (response) {
+ this.setContent(
+ 'Response:' +
+ JSON.stringify(response) +
+ '
'
+ );
},
- error: function() {
- this.setContent('Oops, something went wrong
');
+ error: function () {
+ this.setContent(
+ 'Oops, something went wrong
'
+ );
}
}
});
-
-/* Confirm */
-
+// Confirm
new jBox('Confirm', {
- content: 'Do you really want to do this?',
- cancelButton: 'Nope',
- confirmButton: 'Sure do!'
+ content: 'Do you really want to do this?',
+ cancelButton: 'Nope',
+ confirmButton: 'Sure do!'
});
+// Notice
-/* Notice */
-
-
-$('#Notice-1').click(function() {
-
+jQuery('#Notice-1').on('click', function () {
new jBox('Notice', {
- content: 'Hello, I\'m a notice',
+ content: "Hello, I'm a notice",
color: 'black'
});
-
});
-
-$('#Notice-2').click(function() {
-
+jQuery('#Notice-2').on('click', function () {
new jBox('Notice', {
animation: 'flip',
color: getColor(),
- content: 'Oooh! They also come in colors'
+ content: 'Oooh! They also come in colors',
+ delayOnHover: true,
+ showCountdown: true
});
-
});
-
-$('#Notice-3').click(function() {
-
+jQuery('#Notice-3').on('click', function () {
new jBox('Notice', {
theme: 'NoticeFancy',
attributes: {
@@ -221,17 +214,17 @@ $('#Notice-3').click(function() {
y: 'bottom'
},
color: getColor(),
- content: 'Hello, I\'m down here',
- audio: '../Source/audio/bling2',
+ content: "Hello, I'm down here",
+ audio: 'https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/assets/audio/bling2',
volume: 80,
- animation: {open: 'slide:bottom', close: 'slide:left'}
+ animation: {
+ open: 'slide:bottom',
+ close: 'slide:left'
+ }
});
-
});
-
-$('#Notice-4').click(function() {
-
+jQuery('#Notice-4').on('click', function () {
new jBox('Notice', {
attributes: {
x: 'right',
@@ -243,43 +236,37 @@ $('#Notice-4').click(function() {
close: 'zoomIn'
},
color: getColor(),
- title: 'Tadaaa! I\'m single',
- content: 'Open another notice, I won\'t stack'
+ title: "Tadaaa! I'm single",
+ content: "Open another notice, I won't stack"
});
-
});
-
-/* Image */
-
+// Image
new jBox('Image', {
imageCounter: true,
imageCounterSeparator: ' of '
});
+// Additional JS for demo purposes
-/* Additional JS for demo purposes */
-
-
-$('#Tooltip-4').mouseenter(function() {
- $('#Tooltip-4').addClass('active').html('Wait...');
-}).mouseleave(function() {
- $('#Tooltip-4').addClass('active').html('Wait...');
+jQuery('#Tooltip-4').on('mouseenter mouseleave', function () {
+ jQuery('#Tooltip-4').addClass('active').html('Wait...');
});
-$('.target-notice').click(function() {
- $(this).addClass('active').html('Click me again');
-}).mouseleave(function() {
- $(this).removeClass('active').html('Click me');
-});
+jQuery('.target-notice')
+ .on('click', function () {
+ jQuery(this).addClass('active').html('Click me again');
+ })
+ .on('mouseleave', function () {
+ jQuery(this).removeClass('active').html('Click me');
+ });
-var colors = ['red', 'green', 'blue', 'yellow'], index = 0;
+var colors = ['red', 'green', 'blue', 'yellow'];
+var index = 0;
var getColor = function () {
- (index >= colors.length) && (index = 0);
+ if (index >= colors.length) {
+ index = 0;
+ }
return colors[index++];
};
-
-
-});
-
diff --git a/demo/es6/package-lock.json b/demo/es6/package-lock.json
new file mode 100644
index 0000000..4ae6082
--- /dev/null
+++ b/demo/es6/package-lock.json
@@ -0,0 +1,1566 @@
+{
+ "name": "jbox-es6-demo",
+ "version": "0.0.1",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@npmcli/ci-detect": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz",
+ "integrity": "sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==",
+ "dev": true
+ },
+ "@npmcli/git": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.8.tgz",
+ "integrity": "sha512-LPnzyBZ+1p7+JzHVwwKycMF8M3lr1ze3wxGRnxn/QxJtk++Y3prSJQrdBDGCxJyRpFsup6J3lrRBVYBhJVrM8Q==",
+ "dev": true,
+ "requires": {
+ "@npmcli/promise-spawn": "^1.3.2",
+ "lru-cache": "^6.0.0",
+ "mkdirp": "^1.0.4",
+ "npm-pick-manifest": "^6.1.1",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^2.0.2"
+ }
+ },
+ "@npmcli/installed-package-contents": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz",
+ "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==",
+ "dev": true,
+ "requires": {
+ "npm-bundled": "^1.1.1",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "@npmcli/move-file": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+ "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^1.0.4",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "@npmcli/node-gyp": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz",
+ "integrity": "sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==",
+ "dev": true
+ },
+ "@npmcli/promise-spawn": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz",
+ "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==",
+ "dev": true,
+ "requires": {
+ "infer-owner": "^1.0.4"
+ }
+ },
+ "@npmcli/run-script": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.4.tgz",
+ "integrity": "sha512-Yd9HXTtF1JGDXZw0+SOn+mWLYS0e7bHBHVC/2C8yqs4wUrs/k8rwBSinD7rfk+3WG/MFGRZKxjyoD34Pch2E/A==",
+ "dev": true,
+ "requires": {
+ "@npmcli/node-gyp": "^1.0.2",
+ "@npmcli/promise-spawn": "^1.3.2",
+ "infer-owner": "^1.0.4",
+ "node-gyp": "^7.1.0",
+ "read-package-json-fast": "^2.0.1"
+ }
+ },
+ "@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "requires": {
+ "debug": "4"
+ }
+ },
+ "agentkeepalive": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz",
+ "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "depd": "^1.1.2",
+ "humanize-ms": "^1.2.1"
+ }
+ },
+ "aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "big-integer": {
+ "version": "1.6.48",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
+ "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==",
+ "dev": true
+ },
+ "bplist-parser": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz",
+ "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=",
+ "dev": true,
+ "requires": {
+ "big-integer": "^1.6.7"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "builtins": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
+ "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
+ "dev": true
+ },
+ "cacache": {
+ "version": "15.0.6",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.6.tgz",
+ "integrity": "sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==",
+ "dev": true,
+ "requires": {
+ "@npmcli/move-file": "^1.0.1",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "glob": "^7.1.4",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^6.0.0",
+ "minipass": "^3.1.1",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.2",
+ "mkdirp": "^1.0.3",
+ "p-map": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^8.0.1",
+ "tar": "^6.0.2",
+ "unique-filename": "^1.1.1"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "cli-spinners": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz",
+ "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "default-browser-id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-2.0.0.tgz",
+ "integrity": "sha1-AezONxpx6F8VoXF354YwR+c9vn0=",
+ "dev": true,
+ "requires": {
+ "bplist-parser": "^0.1.0",
+ "pify": "^2.3.0",
+ "untildify": "^2.0.0"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true
+ },
+ "err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "dev": true
+ },
+ "esbuild": {
+ "version": "0.9.7",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.9.7.tgz",
+ "integrity": "sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==",
+ "dev": true
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fdir": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-5.0.0.tgz",
+ "integrity": "sha512-cteqwWMA43lEmgwOg5HSdvhVFD39vHjQDhZkRMlKmeoNPtSSgUw1nUypydiY2upMdGiBFBZvNBDbnoBh0yCzaQ==",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "dev": true
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
+ "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "dev": true
+ },
+ "http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "requires": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "dev": true,
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
+ "humanize-ms": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+ "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
+ "dev": true,
+ "requires": {
+ "ms": "^2.0.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+ "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ },
+ "ignore-walk": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
+ "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
+ "dev": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true
+ },
+ "infer-owner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "ip": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz",
+ "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==",
+ "dev": true
+ },
+ "is-core-module": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
+ "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-lambda": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+ "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "jbox": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/jbox/-/jbox-1.2.13.tgz",
+ "integrity": "sha512-BxEeLer6FjzNbnqgSEGMoKvkm7GxkkbOHYLfr7YnAlcL+9/jj+UY/47mpKvRP+P+LFKFgjpUyxmMEwefAkv8Ng==",
+ "requires": {
+ "jquery": "^3.6.0"
+ }
+ },
+ "jquery": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
+ "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true
+ },
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ },
+ "dependencies": {
+ "json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true
+ }
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "make-fetch-happen": {
+ "version": "8.0.14",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz",
+ "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==",
+ "dev": true,
+ "requires": {
+ "agentkeepalive": "^4.1.3",
+ "cacache": "^15.0.5",
+ "http-cache-semantics": "^4.1.0",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-lambda": "^1.0.1",
+ "lru-cache": "^6.0.0",
+ "minipass": "^3.1.3",
+ "minipass-collect": "^1.0.2",
+ "minipass-fetch": "^1.3.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "promise-retry": "^2.0.1",
+ "socks-proxy-agent": "^5.0.0",
+ "ssri": "^8.0.0"
+ }
+ },
+ "mime-db": {
+ "version": "1.47.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
+ "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.30",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
+ "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.47.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minipass": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
+ "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-fetch": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz",
+ "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==",
+ "dev": true,
+ "requires": {
+ "encoding": "^0.1.12",
+ "minipass": "^3.1.0",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.0.0"
+ }
+ },
+ "minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-json-stream": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz",
+ "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==",
+ "dev": true,
+ "requires": {
+ "jsonparse": "^1.3.1",
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node-gyp": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
+ "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
+ "dev": true,
+ "requires": {
+ "env-paths": "^2.2.0",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.3",
+ "nopt": "^5.0.0",
+ "npmlog": "^4.1.2",
+ "request": "^2.88.2",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.2",
+ "tar": "^6.0.2",
+ "which": "^2.0.2"
+ }
+ },
+ "nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
+ "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==",
+ "dev": true,
+ "requires": {
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-install-checks": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz",
+ "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==",
+ "dev": true,
+ "requires": {
+ "semver": "^7.1.1"
+ }
+ },
+ "npm-normalize-package-bin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
+ "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
+ "dev": true
+ },
+ "npm-package-arg": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.2.tgz",
+ "integrity": "sha512-6Eem455JsSMJY6Kpd3EyWE+n5hC+g9bSyHr9K9U2zqZb7+02+hObQ2c0+8iDk/mNF+8r1MhY44WypKJAkySIYA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^4.0.1",
+ "semver": "^7.3.4",
+ "validate-npm-package-name": "^3.0.0"
+ }
+ },
+ "npm-packlist": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.1.5.tgz",
+ "integrity": "sha512-KCfK3Vi2F+PH1klYauoQzg81GQ8/GGjQRKYY6tRnpQUPKTs/1gBZSRWtTEd7jGdSn1LZL7gpAmJT+BcS55k2XQ==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.6",
+ "ignore-walk": "^3.0.3",
+ "npm-bundled": "^1.1.1",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-pick-manifest": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz",
+ "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==",
+ "dev": true,
+ "requires": {
+ "npm-install-checks": "^4.0.0",
+ "npm-normalize-package-bin": "^1.0.1",
+ "npm-package-arg": "^8.1.2",
+ "semver": "^7.3.4"
+ }
+ },
+ "npm-registry-fetch": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz",
+ "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==",
+ "dev": true,
+ "requires": {
+ "@npmcli/ci-detect": "^1.0.0",
+ "lru-cache": "^6.0.0",
+ "make-fetch-happen": "^8.0.9",
+ "minipass": "^3.1.3",
+ "minipass-fetch": "^1.3.0",
+ "minipass-json-stream": "^1.0.1",
+ "minizlib": "^2.0.0",
+ "npm-package-arg": "^8.0.0"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ },
+ "pacote": {
+ "version": "11.3.1",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.1.tgz",
+ "integrity": "sha512-TymtwoAG12cczsJIrwI/euOQKtjrQHlD0k0oyt9QSmZGpqa+KdlxKdWR/YUjYizkixaVyztxt/Wsfo8bL3A6Fg==",
+ "dev": true,
+ "requires": {
+ "@npmcli/git": "^2.0.1",
+ "@npmcli/installed-package-contents": "^1.0.6",
+ "@npmcli/promise-spawn": "^1.2.0",
+ "@npmcli/run-script": "^1.8.2",
+ "cacache": "^15.0.5",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.1.0",
+ "infer-owner": "^1.0.4",
+ "minipass": "^3.1.3",
+ "mkdirp": "^1.0.3",
+ "npm-package-arg": "^8.0.1",
+ "npm-packlist": "^2.1.4",
+ "npm-pick-manifest": "^6.0.0",
+ "npm-registry-fetch": "^9.0.0",
+ "promise-retry": "^2.0.1",
+ "read-package-json-fast": "^2.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^8.0.1",
+ "tar": "^6.1.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
+ "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==",
+ "dev": true
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+ "dev": true
+ },
+ "promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "dev": true,
+ "requires": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ }
+ },
+ "psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "dev": true
+ },
+ "read-package-json-fast": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz",
+ "integrity": "sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ==",
+ "dev": true,
+ "requires": {
+ "json-parse-even-better-errors": "^2.3.0",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ }
+ },
+ "retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "rollup": {
+ "version": "2.37.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.37.1.tgz",
+ "integrity": "sha512-V3ojEeyGeSdrMSuhP3diBb06P+qV4gKQeanbDv+Qh/BZbhdZ7kHV0xAt8Yjk4GFshq/WjO7R4c7DFM20AwTFVQ==",
+ "dev": true,
+ "requires": {
+ "fsevents": "~2.1.2"
+ },
+ "dependencies": {
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "smart-buffer": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
+ "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==",
+ "dev": true
+ },
+ "snowpack": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/snowpack/-/snowpack-3.3.5.tgz",
+ "integrity": "sha512-QI6/PcSud39ZAmrs7IiBSCr3PWXxc4/w2SNJp32+n7XsXxSB4waJ+jpG5rtJAeif5pqRNkX4887PKwWsMzFRCw==",
+ "dev": true,
+ "requires": {
+ "cli-spinners": "^2.5.0",
+ "default-browser-id": "^2.0.0",
+ "esbuild": "^0.9.3",
+ "fdir": "^5.0.0",
+ "fsevents": "^2.2.0",
+ "open": "^7.0.4",
+ "pacote": "^11.3.1",
+ "picomatch": "^2.2.2",
+ "resolve": "^1.20.0",
+ "rollup": "~2.37.1"
+ }
+ },
+ "socks": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
+ "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
+ "dev": true,
+ "requires": {
+ "ip": "^1.1.5",
+ "smart-buffer": "^4.1.0"
+ }
+ },
+ "socks-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==",
+ "dev": true,
+ "requires": {
+ "agent-base": "6",
+ "debug": "4",
+ "socks": "^2.3.3"
+ }
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "ssri": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+ "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.1.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "tar": {
+ "version": "6.1.11",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
+ "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true
+ },
+ "unique-filename": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+ "dev": true,
+ "requires": {
+ "unique-slug": "^2.0.0"
+ }
+ },
+ "unique-slug": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4"
+ }
+ },
+ "untildify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz",
+ "integrity": "sha1-F+soB5h/dpUunASF/DEdBqgmouA=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0"
+ }
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true
+ },
+ "validate-npm-package-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
+ "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
+ "dev": true,
+ "requires": {
+ "builtins": "^1.0.3"
+ }
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+}
diff --git a/demo/es6/package.json b/demo/es6/package.json
new file mode 100644
index 0000000..9cdd534
--- /dev/null
+++ b/demo/es6/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "jbox-es6-demo",
+ "description": "",
+ "version": "0.0.1",
+ "author": "Stephan Wagner (https://stephanwagner.me)",
+ "license": "ISC",
+ "main": "index.js",
+ "dependencies": {
+ "jbox": "*"
+ },
+ "devDependencies": {
+ "snowpack": "^3.3.5"
+ },
+ "scripts": {
+ "start": "snowpack dev"
+ }
+}
diff --git a/demo/html/css/demo.css b/demo/html/css/demo.css
new file mode 100755
index 0000000..ab5a160
--- /dev/null
+++ b/demo/html/css/demo.css
@@ -0,0 +1,233 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ position: relative;
+ font-family: Roboto, sans-serif;
+ font-size: 17px;
+ line-height: 1.4;
+ color: #222;
+ background: #fff;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: none;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+* {
+ outline: none;
+ box-sizing: border-box;
+}
+
+p {
+ margin: 0 0 15px;
+}
+
+p:last-child {
+ margin-bottom: 0;
+}
+
+h2 {
+ margin: 0;
+ font-size: 22px;
+ font-weight: normal;
+}
+
+main {
+ padding: 20px 0;
+}
+
+.container {
+ position: relative;
+ width: calc(100% - 60px);
+ max-width: 1000px;
+ margin: auto;
+}
+
+@media (max-width: 768px) {
+ .container {
+ width: calc(100% - 30px);
+ }
+}
+
+/* Target elements */
+
+.targets-wrapper {
+ margin: 0 -5px;
+ padding: 10px 0 20px;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.target,
+.target-click,
+.target-notice {
+ cursor: default;
+ font-size: 14px;
+ line-height: 50px;
+ height: 52px;
+ border-radius: 4px;
+ overflow: hidden;
+ border: 2px solid #e2e2e2;
+ background: #fafafa;
+ text-align: center;
+ font-weight: 500;
+ position: relative;
+ text-transform: uppercase;
+ width: calc(25% - 10px);
+ margin: 5px;
+ transition: border-color .2s, background-color .2s;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.target:hover,
+.target-click:hover,
+.target-notice:hover {
+ border-color: #bbb;
+ background-color: #eee;
+}
+
+.target-click,
+.target-notice {
+ cursor: pointer;
+}
+
+.target.active,
+.target-click.active,
+.target-notice.active {
+ color: #49d;
+}
+
+@media (max-width: 768px) {
+
+ .target,
+ .target-click,
+ .target-notice {
+ width: calc(50% - 10px);
+ }
+}
+
+.demo-img {
+ width: calc(25% - 10px);
+ margin: 5px;
+}
+
+@media (max-width: 500px) {
+ .demo-img {
+ width: calc(50% - 10px);
+ }
+}
+
+.demo-img>img {
+ border: 4px solid #e2e2e2;
+ border-radius: 4px;
+ width: 100%;
+ height: auto;
+ filter: grayscale(100%);
+ transition: filter .2s, border-color .2s;
+}
+
+.demo-img:hover>img {
+ filter: none;
+ border-color: #bbb;
+}
+
+@media (max-width: 768px) {
+ .demo-img>img {
+ border-width: 2px;
+ }
+}
+
+/* Header */
+
+header {
+ height: 50px;
+ line-height: 50px;
+ font-size: 17px;
+ background: #000;
+ color: #aaa;
+ box-shadow: 0 0 3px rgba(0, 0, 0, .6);
+}
+
+header a {
+ margin-right: 20px;
+ color: #aaa;
+ text-decoration: none;
+ transition: color .2s;
+}
+
+header a:last-child,
+header a:nth-child(2) {
+ margin-right: 0;
+}
+
+header a.active,
+header a:hover {
+ color: #fff;
+ text-decoration: none;
+}
+
+#stephan {
+ display: block;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ width: 40px;
+ height: 40px;
+ transform: translateY(-50%);
+ border-radius: 3px;
+ background: no-repeat center center url(https://stephanwagner.me/img/stephan.jpg);
+ background-size: 100%;
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .3);
+}
+
+#stephan>span {
+ font-size: 0;
+ line-height: 0;
+ white-space: nowrap;
+ position: absolute;
+ top: 50%;
+ right: 50%;
+ pointer-events: none;
+ transition: font-size .2s, margin .2s, opacity .2s, line-height .2s;
+ opacity: 0;
+}
+
+#stephan:hover>span {
+ opacity: 1;
+ font-size: 17px;
+ margin-right: 40px;
+}
+
+@media (max-width: 500px) {
+ #stephan>span {
+ display: none;
+ }
+}
+
+/* jBox styles */
+
+.ajax-sending {
+ color: #49d;
+}
+
+.ajax-complete {
+ color: #390;
+}
+
+.ajax-success tt {
+ color: #666;
+ display: block;
+ padding-top: 10px;
+ font-size: 14px;
+}
+
+.ajax-error {
+ color: #d00;
+}
diff --git a/demo/html/css/normalize.css b/demo/html/css/normalize.css
new file mode 100755
index 0000000..c469989
--- /dev/null
+++ b/demo/html/css/normalize.css
@@ -0,0 +1,349 @@
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+ ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+ html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+ display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ border-bottom: none; /* 1 */
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+ border-style: none;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+ overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+ text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box; /* 1 */
+ color: inherit; /* 2 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ white-space: normal; /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/* Misc
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+ display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+ display: none;
+}
diff --git a/Demo/Playground/Playground.Avatar.css b/demo/html/css/playground-avatars.css
old mode 100644
new mode 100755
similarity index 91%
rename from Demo/Playground/Playground.Avatar.css
rename to demo/html/css/playground-avatars.css
index bc1f8f6..a4eb2bf
--- a/Demo/Playground/Playground.Avatar.css
+++ b/demo/html/css/playground-avatars.css
@@ -1,6 +1,10 @@
+.AvatarsModal .jBox-footer {
+ display: flex;
+}
.AvatarsModal .jBox-footer button {
width: 50%;
+ flex-shrink: 0;
height: 50px;
border: 0;
padding: 0;
@@ -73,7 +77,7 @@
color: #999;
}
-#AvatarsComplete.AvatarsModal .jBox-content > div {
+#AvatarsComplete.AvatarsModal .jBox-content>div {
position: absolute;
top: calc(50% - 23px);
left: 25px;
@@ -131,39 +135,39 @@
right: 4px;
}
-.AvatarsCollection > div {
+.AvatarsCollection>div {
width: 47px;
height: 45px;
padding: 0 1px;
}
-.AvatarsCollection#DislikedAvatars > div {
+.AvatarsCollection#DislikedAvatars>div {
float: left;
}
-.AvatarsCollection#LikedAvatars > div {
+.AvatarsCollection#LikedAvatars>div {
float: right;
}
-.AvatarsCollection > div > div {
+.AvatarsCollection>div>div {
position: relative;
overflow: hidden;
width: 45px;
height: 45px;
- border: 2px solid red;
+ border: 2px solid;
border-radius: 50%;
background: #000;
}
-.AvatarsCollection#DislikedAvatars > div > div {
+.AvatarsCollection#DislikedAvatars>div>div {
border-color: #e33;
}
-.AvatarsCollection#LikedAvatars > div > div {
+.AvatarsCollection#LikedAvatars>div>div {
border-color: #7d0;
}
-.AvatarsCollection > div > div > img {
+.AvatarsCollection>div>div>img {
position: absolute;
top: 50%;
left: 50%;
diff --git a/demo/html/css/playground-inception.css b/demo/html/css/playground-inception.css
new file mode 100755
index 0000000..d4e1ed6
--- /dev/null
+++ b/demo/html/css/playground-inception.css
@@ -0,0 +1,16 @@
+.inception-overlay {
+ background-color: rgba(0, 0, 0, .35);
+}
+
+.inception-modal button {
+ cursor: pointer;
+ border: 0;
+ margin: 0;
+ display: block;
+ width: 100%;
+ color: #fff;
+ background: #000;
+ height: 40px;
+ text-align: center;
+ border-radius: 4px;
+}
diff --git a/demo/html/css/playground-login.css b/demo/html/css/playground-login.css
new file mode 100755
index 0000000..55c5288
--- /dev/null
+++ b/demo/html/css/playground-login.css
@@ -0,0 +1,204 @@
+/* Restyle jBoxes */
+
+#jBoxLogin .jBox-content {
+ padding: 0;
+}
+
+#jBoxLogin .jBox-title {
+ text-align: center;
+ line-height: 1.6;
+ padding: 15px 0;
+ font-size: 20px;
+}
+
+.jBox-TooltipSmall.LoginTooltipSmall .jBox-content,
+.jBox-TooltipError.LoginTooltipError .jBox-content {
+ font-size: 13px;
+ padding: 5px 10px;
+ line-height: 18px;
+}
+
+.jBox-TooltipSmall.LoginTooltipSmall .jBox-container,
+.jBox-TooltipError.LoginTooltipError .jBox-container {
+ border-radius: 2px;
+ font-weight: bold;
+ color: #fff;
+}
+
+.jBox-TooltipSmall.LoginTooltipError .jBox-container {
+ background: #d00;
+}
+
+.jBox-TooltipSmall.LoginTooltipSmall .jBox-container {
+ background: #246bb3;
+}
+
+.jBox-TooltipSmall.LoginTooltipSmall .jBox-pointer:after {
+ background: #246bb3;
+}
+
+/* Content */
+
+.login-container {
+ display: none;
+}
+
+.login-container.active {
+ display: block;
+}
+
+.login-body {
+ padding: 0 25px;
+}
+
+.login-container button {
+ margin: 25px 0 0;
+}
+
+.login-textfield-wrapper {
+ position: relative;
+}
+
+.login-remember {
+ margin: 25px 0 0;
+ height: 20px;
+}
+
+#LoginWrapper.request-running .login-footer a,
+#LoginWrapper.request-running .login-footer span {
+ cursor: default !important;
+ text-decoration: none !important;
+}
+
+/* Form elements */
+
+.login-textfield {
+ width: 100%;
+ border: 0;
+ border-bottom: 2px solid #ddd;
+ padding: 6px 2px;
+ font-size: 18px;
+ margin-top: 25px;
+ transition: border-color .2s;
+}
+
+.login-textfield:hover {
+ border-bottom-color: #ccc;
+}
+
+.login-textfield:focus {
+ border-bottom-color: #246bb3;
+}
+
+.login-textfield.textfield-error {
+ border-bottom-color: #d00;
+}
+
+.login-checkbox {
+ float: left;
+ position: relative;
+ cursor: pointer;
+ width: 20px;
+ height: 20px;
+ border-radius: 3px;
+ background: #eee;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .05);
+ transition: background-color .2s;
+}
+
+.login-checkbox.login-checkbox-active {
+ box-shadow: none;
+ background: #7d0;
+}
+
+.login-checkbox-check {
+ opacity: 0;
+ background: no-repeat center center;
+ background-size: 14px;
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MjQuNTMgMzE1LjczIj4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTQ2NS4wNywxNTMuNmExMC4zMSwxMC4zMSwwLDAsMCwwLTE0LjkzTDQyOC44LDEwMi40YTEwLjMxLDEwLjMxLDAsMCwwLTE0LjkzLDBMMjAwLjUzLDMxNS43Myw5OC4xMywyMTMuMzNhMTAuMzEsMTAuMzEsMCwwLDAtMTQuOTMsMEw0Ni45MywyNDkuNmExMC4zMSwxMC4zMSwwLDAsMCwwLDE0LjkzbDE0Ny4yLDE0Ny4yYTEwLjMxLDEwLjMxLDAsMCwwLDE0LjkzLDBsMjU2LTI1OC4xM1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00My43MyAtOTkuMikiLz4KPC9zdmc+);
+ width: 20px;
+ height: 20px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -10px;
+ margin-left: -10px;
+ transition: opacity .2s;
+}
+
+.login-checkbox.login-checkbox-active .login-checkbox-check {
+ opacity: 1;
+}
+
+.login-checkbox-label {
+ float: left;
+ cursor: pointer;
+ width: calc(100% - 20px);
+ line-height: 20px;
+ font-size: 17px;
+ padding: 0 0 0 12px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.login-button {
+ width: 100%;
+ border: 0;
+ color: #fff;
+ background: #246bb3;
+ border-radius: 4px;
+ height: 40px;
+ line-height: 40px;
+ font-size: 20px;
+ padding: 0;
+ transition: background-color .2s;
+}
+
+.login-button:hover {
+ background: #3878c1;
+}
+
+.login-button:active {
+ background: #246bb3;
+}
+
+.login-button[disabled] {
+ cursor: default !important;
+ color: #ccc !important;
+ background: #eee !important;
+}
+
+.loading-bar,
+.login-button[disabled].loading-bar {
+ background-image: linear-gradient(-45deg, rgba(255, 255, 255, .4) 25%, rgba(255, 255, 255, .0) 25%, rgba(255, 255, 255, .0) 50%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .4) 75%, rgba(255, 255, 255, .0) 75%, rgba(255, 255, 255, .0)) !important;
+ background-size: 32px 32px !important;
+ background-repeat: repeat !important;
+ transition: background-position 60000s linear !important;
+ background-position: 4000000px !important;
+}
+
+/* Footer */
+
+.login-footer {
+ background: #fafafa;
+ border-top: 1px solid #eee;
+ border-radius: 0 0 4px 4px;
+ font-size: 17px;
+ line-height: 1.6;
+ padding: 15px 0 15px 25px;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
+.login-footer span {
+ cursor: pointer;
+ color: #297acc;
+}
+
+.login-footer span:hover {
+ text-decoration: underline;
+}
diff --git a/demo/html/index.html b/demo/html/index.html
new file mode 100755
index 0000000..7cda68b
--- /dev/null
+++ b/demo/html/index.html
@@ -0,0 +1,89 @@
+
+
+
+ jBox HTML demos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tooltip
+
+
+
Hover me
+
Hover me
+
Hover me
+
Hover me
+
Hover me
+
Hover me
+
Click me
+
Click me
+
+
+ Modal
+
+
+
Click me
+
Click me
+
Click me
+
Click me
+
+
+ Notice
+
+
+
Click me
+
Click me
+
Click me
+
Click me
+
+
+ Image
+
+
+
+ Playground
+
+
+
Inception
+
Avatars
+
Login
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/html/js/demo.js b/demo/html/js/demo.js
new file mode 100755
index 0000000..6ceb2c6
--- /dev/null
+++ b/demo/html/js/demo.js
@@ -0,0 +1,272 @@
+jQuery(function () {
+ // Tooltip
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-1',
+ content: 'This is a basic jBox tooltip'
+ });
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-2',
+ theme: 'TooltipBorderThick',
+ width: 200,
+ position: {
+ x: 'left',
+ y: 'center'
+ },
+ outside: 'x',
+ pointer: 'top:15',
+ content: 'You have many options to position and animate your jBoxes',
+ animation: 'move'
+ });
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-3',
+ theme: 'TooltipDark',
+ animation: 'zoomOut',
+ content: 'Use themes to change appearance'
+ });
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-4',
+ width: 300,
+ pointer: 'right:80',
+ animation: 'move',
+ delayOpen: 1000,
+ delayClose: 2000,
+ content: 'This tooltip waits 1 second to open and closes after 2 seconds',
+ onOpen: function () {
+ this.source.removeClass('active').html('Hover me');
+ },
+ onClose: function () {
+ this.source.removeClass('active').html('Hover me');
+ }
+ });
+
+ new jBox('Mouse', {
+ attach: '#Tooltip-5',
+ position: {
+ x: 'right',
+ y: 'bottom'
+ },
+ content: 'I will follow you!'
+ });
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-6',
+ width: 280,
+ closeOnMouseleave: true,
+ animation: 'zoomIn',
+ content: "I won't close when you move your mouse over me"
+ });
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-7',
+ target: '#Tooltip-1',
+ theme: 'TooltipBorder',
+ trigger: 'click',
+ adjustTracker: true,
+ closeOnClick: 'body',
+ closeButton: 'box',
+ animation: 'move',
+ position: {
+ x: 'left',
+ y: 'top'
+ },
+ outside: 'y',
+ pointer: 'left:20',
+ offset: {
+ x: 25
+ },
+ content:
+ 'You can position your tooltips at any element. Scroll up and down to see this tooltip flip position!',
+ onOpen: function () {
+ this.source.addClass('active').html('Now scroll');
+ },
+ onClose: function () {
+ this.source.removeClass('active').html('Click me');
+ }
+ });
+
+ new jBox('Tooltip', {
+ attach: '#Tooltip-8',
+ theme: 'TooltipBorder',
+ trigger: 'click',
+ width: 200,
+ height: jQuery(window).height() - 160,
+ adjustTracker: true,
+ closeOnClick: 'body',
+ closeOnEsc: true,
+ animation: 'move',
+ position: {
+ x: 'right',
+ y: 'center'
+ },
+ outside: 'x',
+ content:
+ 'Scroll up and down or resize your browser, I will adjust my position! Press [ESC] or click anywhere to close.',
+ onOpen: function () {
+ this.source.addClass('active').html('Now scroll');
+ },
+ onClose: function () {
+ this.source.removeClass('active').html('Click me');
+ }
+ });
+
+ // Modal
+
+ new jBox('Modal', {
+ attach: '#Modal-1',
+ height: 200,
+ title: "I'm a basic jBox modal window",
+ content:
+ 'Try to scroll ...it\'s blocked. Press [ESC] or click anywhere to close.
'
+ });
+
+ new jBox('Modal', {
+ attach: '#Modal-2',
+ width: 350,
+ height: 200,
+ blockScroll: false,
+ animation: 'zoomIn',
+ draggable: 'title',
+ closeButton: true,
+ content: 'You can move this modal window',
+ title: 'Click here to drag me around',
+ overlay: false,
+ reposition: false,
+ repositionOnOpen: false
+ });
+
+ new jBox('Modal', {
+ attach: '#Modal-3',
+ width: 450,
+ height: 250,
+ closeButton: 'title',
+ animation: false,
+ title: 'AJAX request',
+ ajax: {
+ url: 'https://reqres.in/api/users?delay=2',
+ data: {
+ id: '1982',
+ name: 'Stephan Wagner'
+ },
+ method: 'post',
+ reload: 'strict',
+ setContent: false,
+ beforeSend: function () {
+ this.setContent('');
+ this.setTitle(
+ 'Sending AJAX request...
'
+ );
+ },
+ complete: function () {
+ this.setTitle('AJAX request complete
');
+ },
+ success: function (response) {
+ this.setContent(
+ 'Response:' +
+ JSON.stringify(response) +
+ '
'
+ );
+ },
+ error: function () {
+ this.setContent(
+ 'Oops, something went wrong
'
+ );
+ }
+ }
+ });
+
+ // Confirm
+
+ new jBox('Confirm', {
+ content: 'Do you really want to do this?',
+ cancelButton: 'Nope',
+ confirmButton: 'Sure do!'
+ });
+
+ // Notice
+
+ jQuery('#Notice-1').on('click', function () {
+ new jBox('Notice', {
+ content: "Hello, I'm a notice",
+ color: 'black'
+ });
+ });
+
+ jQuery('#Notice-2').on('click', function () {
+ new jBox('Notice', {
+ animation: 'flip',
+ color: getColor(),
+ content: 'Oooh! They also come in colors',
+ delayOnHover: true,
+ showCountdown: true
+ });
+ });
+
+ jQuery('#Notice-3').on('click', function () {
+ new jBox('Notice', {
+ theme: 'NoticeFancy',
+ attributes: {
+ x: 'left',
+ y: 'bottom'
+ },
+ color: getColor(),
+ content: "Hello, I'm down here",
+ audio: '../../assets/audio/bling2',
+ volume: 80,
+ animation: {
+ open: 'slide:bottom',
+ close: 'slide:left'
+ }
+ });
+ });
+
+ jQuery('#Notice-4').on('click', function () {
+ new jBox('Notice', {
+ attributes: {
+ x: 'right',
+ y: 'bottom'
+ },
+ stack: false,
+ animation: {
+ open: 'tada',
+ close: 'zoomIn'
+ },
+ color: getColor(),
+ title: "Tadaaa! I'm single",
+ content: "Open another notice, I won't stack"
+ });
+ });
+
+ // Image
+
+ new jBox('Image', {
+ imageCounter: true,
+ imageCounterSeparator: ' of '
+ });
+
+ // Additional JS for demo purposes
+
+ jQuery('#Tooltip-4').on('mouseenter mouseleave', function () {
+ jQuery('#Tooltip-4').addClass('active').html('Wait...');
+ });
+
+ jQuery('.target-notice')
+ .on('click', function () {
+ jQuery(this).addClass('active').html('Click me again');
+ })
+ .on('mouseleave', function () {
+ jQuery(this).removeClass('active').html('Click me');
+ });
+
+ var colors = ['red', 'green', 'blue', 'yellow'];
+ var index = 0;
+ var getColor = function () {
+ if (index >= colors.length) {
+ index = 0;
+ }
+ return colors[index++];
+ };
+});
diff --git a/Demo/Playground/Playground.Avatar.js b/demo/html/js/playground-avatars.js
old mode 100644
new mode 100755
similarity index 80%
rename from Demo/Playground/Playground.Avatar.js
rename to demo/html/js/playground-avatars.js
index ffc262d..c96105e
--- a/Demo/Playground/Playground.Avatar.js
+++ b/demo/html/js/playground-avatars.js
@@ -1,6 +1,4 @@
-
-/* Playground Demo: Avatars */
-
+// Playground Demo: Avatars
// All data we are using for this demo we will store in the variable DemoAvatars
@@ -9,48 +7,43 @@ var DemoAvatars = {
Modals: {}
};
-
// All the magic happens in the function generateAvatarJBox
-function generateAvatarJBox(initial)
-{
+function generateAvatarJBox(initial) {
// We only need to initialize the tooltips for the avatar collection once
// We can later refer to this jBox instance with DemoAvatars.AvatarsTooltip
-
+
!DemoAvatars.AvatarsTooltip && (DemoAvatars.AvatarsTooltip = new jBox('Tooltip', {
- theme: 'TooltipBorder', // We are using the border theme...
- addClass: 'AvatarsTooltip', // ...and add a class so we can adjust the theme with CSS
- attach: '[data-avatar-tooltip]', // We attach the tooltip to the elements with the attribute data-avatar-tooltip...
- getContent: 'data-avatar-tooltip', // ... and also get the content from the same attribute
- zIndex: 12000, // These tooltips have the highest z-index
+ theme: 'TooltipBorder', // We are using the border theme...
+ addClass: 'AvatarsTooltip', // ...and add a class so we can adjust the theme with CSS
+ attach: '[data-avatar-tooltip]', // We attach the tooltip to the elements with the attribute data-avatar-tooltip...
+ getContent: 'data-avatar-tooltip', // ... and also get the content from the same attribute
+ zIndex: 12000, // These tooltips have the highest z-index
animation: 'move',
-
+
// Adding the liked or disliked class depending on the container the avatar is in
onOpen: function () {
this.wrapper.removeClass('AvatarsTooltipLike AvatarsTooltipDislike').addClass('AvatarsTooltip' + (this.source.parent().attr('id') == 'LikedAvatars' ? 'Like' : 'Dislike'));
}
}));
-
-
+
// When we are creating the initial jBox, reset global variables
-
+
if (initial) {
DemoAvatars.clicked = false;
DemoAvatars.current = -1;
}
-
-
+
// Increase current avatar index
-
+
DemoAvatars.current++;
-
-
+
// When we looped through all the avatars, show a jBox Modal with a hint that there are no more avatars nearby
-
+
if (DemoAvatars.current >= DemoAvatars.Avatars.length) {
-
+
DemoAvatars.Modals.AvatarsComplete = new jBox('Modal', {
-
+
// We use similar options to our Avatar modal so they look similar
id: 'AvatarsComplete',
addClass: 'AvatarsModal',
@@ -71,7 +64,7 @@ function generateAvatarJBox(initial)
title: 'Whoops',
content: 'There are currently no more avatars near you
',
zIndex: 10000,
-
+
// Once this jBox is created, we tel the close button to close the initial avatar modal
onCreated: function () {
this.footer.find('button').on('click', function () {
@@ -79,21 +72,20 @@ function generateAvatarJBox(initial)
});
}
}).open();
-
+
// Nothing more to do, abort here
return null;
}
-
-
+
// We are creating a new jBox Modal with the avatars each time this function gets called
-
+
var jBoxAvatar = new jBox('Modal', {
addClass: 'AvatarsModal',
width: 300,
height: 250,
animation: 'zoomIn',
zIndex: 10000,
-
+
// Adjusting the distance to the viewport so we have space for the avatar collection at the bottom and the close button of the modal at the top
adjustDistance: {
top: 40,
@@ -101,98 +93,100 @@ function generateAvatarJBox(initial)
bottom: 55,
left: 5
},
-
+
// We are setting these options differently for the initial and the following jBoxes
id: initial ? 'AvatarsInitial' : 'AvatarsModal' + DemoAvatars.current,
- overlay: initial ? true : false, // Only one overlay is needed
- blockScroll: initial ? true : false, // The initial jBox will block scrolling, no need for the others to o the same
- closeButton: initial ? 'overlay' : false, // The initial jBox will have the close button in the overlay, the others won't need one
- closeOnEsc: initial ? true : false, // Only the inital jBox can be closed with [ESC] button
-
+ overlay: initial ? true : false, // Only one overlay is needed
+ blockScroll: initial ? true : false, // The initial jBox will block scrolling, no need for the others to o the same
+ closeButton: initial ? 'overlay' : false, // The initial jBox will have the close button in the overlay, the others won't need one
+ closeOnEsc: initial ? true : false, // Only the initial jBox can be closed with [ESC] button
+
// Placing the buttons in the footer area
- footer: '
',
-
+ footer: ' ',
+
// Open this jBox when it is being initialized
onInit: function () {
this.open();
-
+
// Here we store the index we used for this jBox
this.AvatarIndex = DemoAvatars.current;
},
-
+
// When the jBox is created, add the click events to the buttons
onCreated: function () {
-
+
// Create the containers for the liked or disliked avatars
if (initial) {
$('
').appendTo($('body'));
$('
').appendTo($('body'));
}
-
+
$.each(this.footer.find('button'), function (index, el) {
-
+
// Adding the click events for the buttons in the footer
$(el).on('click', function () {
-
+
// Storing a global var that the user clicked on a button
DemoAvatars.clicked = true;
-
+
// When a user clicks a button close the tooltips
DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.close();
DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.close();
-
+
// When we click a button, the jBox disappears, let's tell this jBox that we removed it
this.AvatarRemoved = true;
-
+
// Did we like or dislike the avatar?
var liked = $(el).hasClass('button-heart');
-
+
// Slide the jBox to the left or right depending on which button the user clicked
this.animate('slide' + (liked ? 'Right' : 'Left'), {
-
+
// Once the jBox is removed, hide it and show the avatar in the collection
complete: function () {
this.wrapper.css('display', 'none');
-
+
// Which container to use
var collectionContainer = liked ? $('#LikedAvatars') : $('#DislikedAvatars');
-
+
// If there if not enough space for the avatars to show in one line remove the first one
if (collectionContainer.find('div[data-avatar-tooltip]').length && ((collectionContainer.find('div[data-avatar-tooltip]').length + 1) * $(collectionContainer.find('div[data-avatar-tooltip]')[0]).outerWidth(true) > collectionContainer.outerWidth())) {
$(collectionContainer.find('div[data-avatar-tooltip]')[0]).remove();
}
-
+
// Add the avatar to the collection
this.animate('popIn', {
element: $('
').append($('
').html(' ')).appendTo(collectionContainer)
});
-
+
// Attach the avatar tooltip
DemoAvatars.AvatarsTooltip && DemoAvatars.AvatarsTooltip.attach();
-
+
}.bind(this)
});
-
+
// Open another Avatar jBox
generateAvatarJBox();
-
+
}.bind(this));
}.bind(this));
},
-
+
// When we open the jBox, set the new content and show the tooltips if it's the initial jBox
onOpen: function () {
-
+
// Set title and content depending on current index
this.setTitle(DemoAvatars.Avatars[DemoAvatars.current]);
- this.content.css({backgroundImage: 'url(https://stephanwagner.me/img/jBox/avatar/' + DemoAvatars.Avatars[DemoAvatars.current] + '.svg)'});
-
- // If it's the inital jBox, show the tooltips after a short delay
+ this.content.css({
+ backgroundImage: 'url(https://stephanwagner.me/img/jBox/avatar/' + DemoAvatars.Avatars[DemoAvatars.current] + '.svg)'
+ });
+
+ // If it's the initial jBox, show the tooltips after a short delay
initial && setTimeout(function () {
-
+
// We are creating the two tooltips in a loop as they are very similar
$.each(['Dislike', 'Like'], function (index, item) {
-
+
// We store the tooltips in the global var so we can refer to them later
DemoAvatars['AvatarsTooltip' + item] = new jBox('Tooltip', {
theme: 'TooltipBorder',
@@ -208,27 +202,26 @@ function generateAvatarJBox(initial)
target: '#AvatarsInitial .jBox-footer .button-' + (item == 'Like' ? 'heart' : 'cross'),
animation: 'move',
zIndex: 11000,
-
+
// Abort opening the tooltips when we clicked on a like or dislike button already
onOpen: function () {
DemoAvatars.clicked && this.close();
}
}).open();
-
+
});
-
+
}, 500);
}
});
-
- // If it's the inital jBox add onClose events
- initial && (jBoxAvatar.options.onClose = function ()
- {
+
+ // If it's the initial jBox add onClose events
+ initial && (jBoxAvatar.options.onClose = function () {
// Loop through all avatar jBoxes and close them if they are not removed yet
$.each(DemoAvatars.Modals, function (index, jBox) {
jBox.id != 'AvatarsInitial' && !jBox.AvatarRemoved && jBox.close();
}.bind(this));
-
+
// Remove the collection containers with a sliding animation
$.each(['Liked', 'Disliked'], function (index, item) {
this.animate('slide' + (item == 'Liked' ? 'Right' : 'Left'), {
@@ -238,35 +231,35 @@ function generateAvatarJBox(initial)
}
});
}.bind(this));
-
+
// Close the tooltips
DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.close();
DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.close();
});
-
- // If it's the inital jBox add onCloseComplete events
- initial && (jBoxAvatar.options.onCloseComplete = function ()
- {
+
+ // If it's the initial jBox add onCloseComplete events
+ initial && (jBoxAvatar.options.onCloseComplete = function () {
// Loop through all modal jBoxes and remove them from DOM
$.each(DemoAvatars.Modals, function (index, jBox) {
jBox.destroy();
delete DemoAvatars.Modals[jBox.id];
});
-
+
// Remove the tooltips from DOM
DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.destroy();
DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.destroy();
});
-
+
// Store the jBox in the modal collection
DemoAvatars.Modals[jBoxAvatar.id] = jBoxAvatar;
}
-
// On domready, add the click event to the button
-$(document).ready(function() {
-
- $('#DemoAvatars').click(function () { generateAvatarJBox(true); });
-
+$(function () {
+
+ $('#DemoAvatars').on('click', function () {
+ generateAvatarJBox(true);
+ });
+
});
diff --git a/demo/html/js/playground-inception.js b/demo/html/js/playground-inception.js
new file mode 100644
index 0000000..9db663b
--- /dev/null
+++ b/demo/html/js/playground-inception.js
@@ -0,0 +1,57 @@
+$(function () {
+
+ $('#DemoInception').on('click', function () {
+ openInceptionModal();
+ });
+
+});
+
+var inceptionLevel = 1;
+var offsetLevel = 0;
+
+function openInceptionModal() {
+ if (offsetLevel > 5) {
+ offsetLevel = 0;
+ }
+
+ new jBox('Modal', {
+ width: 360,
+ addClass: 'inception-modal',
+ overlayClass: 'inception-overlay',
+ zIndex: 'auto',
+ draggable: 'title',
+ closeOnClick: false,
+ closeButton: 'title',
+ title: 'Inception level ' + inceptionLevel++,
+ offset: {
+ x: offsetLevel * 15,
+ y: offsetLevel * 15
+ },
+ content: (
+ 'You can open new modal windows within this modal window.
' +
+ 'Open new modal window
'
+ ),
+ onCreated: function () {
+ // Add tooltip
+ this.tooltip = new jBox('Tooltip', {
+ theme: 'TooltipBorder',
+ attach: '[data-inception-tooltip]',
+ getContent: 'data-inception-tooltip',
+ zIndex: 'auto',
+ delayOpen: 600
+ });
+
+ // Add button event
+ this.content.find('.inception-modal-button').on('click', function () {
+ openInceptionModal();
+ });
+ },
+ // Remove modal from DOM when it's closed
+ onCloseComplete: function () {
+ this.destroy();
+ this.tooltip && this.tooltip.destroy();
+ }
+ }).open();
+
+ offsetLevel++;
+}
diff --git a/demo/html/js/playground-login.js b/demo/html/js/playground-login.js
new file mode 100755
index 0000000..9626117
--- /dev/null
+++ b/demo/html/js/playground-login.js
@@ -0,0 +1,355 @@
+// Playground Demo: Login
+
+// We are setting up a global variable where we can adjust html and texts
+
+var jBoxLogin = {
+ jBox: null,
+
+ // The html of each of the content containers
+
+ html: {
+ login: '',
+ register: ''
+ },
+
+ // Corresponding titles for content elements
+
+ title: {
+ login: 'Login',
+ register: 'Create new account'
+ },
+
+ // These tooltips will show when a textelemet gets focus
+
+ textfieldTooltips: {
+ loginUsername: 'For this demo the username is "username"',
+ loginPassword: 'For this demo the password is "password"',
+ registerUsername: 'Choose a unique username',
+ registerEmail: 'Your email address',
+ registerPassword: 'Be tricky, use numbers and special characters'
+ }
+};
+
+$(function () {
+
+ if (!$('#DemoLogin').length) {
+ return;
+ }
+
+ // On domready create the login modal
+
+ jBoxLogin.jBox = new jBox('Modal', {
+
+ // Unique id for CSS access
+ id: 'jBoxLogin',
+
+ // Dimensions
+ width: 320,
+ height: 350,
+
+ // Attach to elements
+ attach: '#DemoLogin',
+
+ // Create the content with the html provided in global var
+ content: '' + jBoxLogin.html.login + jBoxLogin.html.register + '
',
+
+ // Adjust header when scroll is blocked
+ blockScrollAdjust: ['header'],
+
+ // When the jBox is being initialized add internal functions
+ onInit: function () {
+
+ // Internal function to show content
+ this.showContent = function (id, force) {
+
+ // Abort if an ajax call is loading
+ if (!force && $('#LoginWrapper').hasClass('request-running')) return null;
+
+ // Set the title depending on id
+ this.setTitle(jBoxLogin.title[id]);
+
+ // Show content depending on id
+ $('.login-container.active').removeClass('active');
+ $('#LoginContainer-' + id).addClass('active');
+
+ // Remove error tooltips
+ $.each(jBoxLogin.textfieldTooltips, function (id, tt) {
+ $('#' + id).data('jBoxTextfieldError') && $('#' + id).data('jBoxTextfieldError').close();
+ });
+
+ };
+
+ // Initially show content for login
+ this.showContent('login', true);
+
+ // Add focus and blur events to textfields
+ $.each(jBoxLogin.textfieldTooltips, function (id, tt) {
+
+ // Focus an textelement
+ $('#' + id).on('focus', function () {
+
+ // When there is an error tooltip close it
+ $(this).data('jBoxTextfieldError') && $(this).data('jBoxTextfieldError').close();
+
+ // Remove the error state from the textfield
+ $(this).removeClass('textfield-error');
+
+ // Store the tooltip jBox in the elements data
+ if (!$(this).data('jBoxTextfieldTooltip')) {
+ $(this).data('jBoxTextfieldTooltip', new jBox('Tooltip', {
+ width: 310,
+ theme: 'TooltipSmall',
+ addClass: 'LoginTooltipSmall',
+ target: $(this),
+ position: {
+ x: 'left',
+ y: 'top'
+ },
+ outside: 'y',
+ offset: {
+ y: 6,
+ x: 8
+ },
+ pointer: 'left:17',
+ content: tt,
+ animation: 'move'
+ }));
+ }
+
+ $(this).data('jBoxTextfieldTooltip').open();
+
+ // Loose focus of textelement
+ }).on('blur', function () {
+ $(this).data('jBoxTextfieldTooltip').close();
+ });
+ });
+
+ // Internal function to show errors
+ this.showError = function (element, message) {
+
+ if (!element.data('errorTooltip')) {
+ element.data('errorTooltip', new jBox('Tooltip', {
+ width: 310,
+ theme: 'TooltipError',
+ addClass: 'LoginTooltipError',
+ target: element,
+ position: {
+ x: 'left',
+ y: 'top'
+ },
+ outside: 'y',
+ offset: {
+ y: 6
+ },
+ pointer: 'left:9',
+ content: message,
+ animation: 'move'
+ }));
+ }
+
+ element.data('errorTooltip').open();
+ };
+
+ // Internal function to change checkbox state
+ this.toggleCheckbox = function () {
+ // Abort if an ajax call is loading
+ if ($('#LoginWrapper').hasClass('request-running')) return null;
+
+ $('.login-checkbox').toggleClass('login-checkbox-active');
+ };
+
+ // Add checkbox events to checkbox and label
+ $('.login-checkbox, .login-checkbox-label').on('click', function () {
+ this.toggleCheckbox();
+ }.bind(this));
+
+ // Parse an ajax repsonse
+ this.parseResponse = function (response) {
+ try {
+ response = JSON.parse(response.responseText || response);
+ } catch (e) {}
+ return response;
+ };
+
+ // Show a global error
+ this.globalError = function () {
+ new jBox('Notice', {
+ color: 'red',
+ content: 'Oops, something went wrong.',
+ attributes: {
+ x: 'right',
+ y: 'bottom'
+ }
+ });
+ };
+
+ // Internal function to disable or enable the form while request is running
+ this.startRequest = function () {
+ this.toggleRequest();
+ }.bind(this);
+
+ this.completeRequest = function () {
+ this.toggleRequest(true);
+ }.bind(this);
+
+ this.toggleRequest = function (enable) {
+ $('#LoginWrapper')[enable ? 'removeClass' : 'addClass']('request-running');
+ $('#LoginWrapper button')[enable ? 'removeClass' : 'addClass']('loading-bar');
+ $('#LoginWrapper input, #LoginWrapper button').attr('disabled', enable ? false : 'disabled');
+ }.bind(this);
+
+ // Bind ajax login function to login button
+ $('#LoginContainer-login button').on('click', function () {
+ $.ajax({
+ url: 'https://stephanwagner.me/PlaygroundLogin/login',
+ data: {
+ username: $('#loginUsername').val(),
+ password: $('#loginPassword').val(),
+ remember: $('.login-checkbox').hasClass('login-checkbox-active') ? 1 : 0
+ },
+ method: 'get',
+ beforeSend: function () {
+ this.startRequest();
+ }.bind(this),
+
+ // Ajax call successfull
+ success: function (response) {
+ this.completeRequest();
+ response = this.parseResponse(response);
+
+ // Login successfull
+ if (response.success) {
+ this.close();
+ new jBox('Notice', {
+ color: 'green',
+ content: 'You are now logged in',
+ attributes: {
+ x: 'right',
+ y: 'bottom'
+ }
+ });
+ // Login failed
+ } else {
+ // Shake submit button
+ this.animate('shake', {
+ element: $('#LoginContainer-login button')
+ });
+
+ if (response.errors) {
+ // Show error on textfields, for login no error tooltips neccessary, username or password is wrong
+ $('#loginUsername, #loginPassword').addClass('textfield-error');
+ } else {
+ // Backend error
+ this.globalError();
+ }
+ }
+ }.bind(this),
+
+ // Ajax call failed
+ error: function () {
+ this.completeRequest();
+ this.animate('shake', {
+ element: $('#LoginContainer-login button')
+ });
+ this.globalError();
+ }.bind(this)
+ });
+
+ }.bind(this));
+
+ // Bind ajax register function to register button
+ $('#LoginContainer-register button').on('click', function () {
+ $.ajax({
+ url: 'https://stephanwagner.me/PlaygroundLogin/register',
+ data: {
+ username: $('#registerUsername').val(),
+ email: $('#registerEmail').val(),
+ password: $('#registerPassword').val()
+ },
+ method: 'get',
+ beforeSend: function () {
+ this.startRequest();
+ }.bind(this),
+
+ success: function (response) {
+ this.completeRequest();
+ response = this.parseResponse(response);
+
+ // Registration successfull
+ if (response.success) {
+ this.close();
+ new jBox('Notice', {
+ color: 'green',
+ content: 'Your account was created',
+ attributes: {
+ x: 'right',
+ y: 'bottom'
+ }
+ });
+
+ // Registration failed
+ } else {
+ // Shake submit button
+ this.animate('shake', {
+ element: $('#LoginContainer-register button')
+ });
+
+ if (response.errors) {
+ // Loop through errors and open tooltips
+ $.each(response.errors, function (id, error) {
+ var id_selector = 'register' + (id).substr(0, 1).toUpperCase() + (id).substr(1);
+ $('#' + id_selector).addClass('textfield-error');
+
+ if (!$('#' + id_selector).data('jBoxTextfieldError')) {
+ $('#' + id_selector).data('jBoxTextfieldError', new jBox('Tooltip', {
+ width: 310,
+ theme: 'TooltipError',
+ addClass: 'LoginTooltipError',
+ target: $('#' + id_selector),
+ position: {
+ x: 'left',
+ y: 'top'
+ },
+ outside: 'y',
+ offset: {
+ y: 6,
+ x: 8
+ },
+ pointer: 'left:17',
+ //content: error,
+ animation: 'move'
+ }));
+ }
+ $('#' + id_selector).data('jBoxTextfieldError').setContent(error).open();
+ });
+
+ // Backend error
+ } else {
+ this.globalError();
+ }
+ }
+ }.bind(this),
+
+ // Ajax call failed
+ error: function () {
+ this.completeRequest();
+ this.animate('shake', {
+ element: $('#RegisterContainer-login button')
+ });
+ this.globalError();
+ }.bind(this)
+ });
+ }.bind(this));
+ },
+ onOpen: function () {
+ // Go back to login when we open the modal
+ this.showContent('login', true);
+ },
+ onClose: function () {
+ // Remove error tooltips
+ $.each(jBoxLogin.textfieldTooltips, function (id, tt) {
+ $('#' + id).data('jBoxTextfieldError') && $('#' + id).data('jBoxTextfieldError').close();
+ });
+ }
+ });
+});
diff --git a/dist/jBox.all.css b/dist/jBox.all.css
new file mode 100755
index 0000000..8602347
--- /dev/null
+++ b/dist/jBox.all.css
@@ -0,0 +1,1251 @@
+.jBox-wrapper {
+ text-align: left;
+ box-sizing: border-box;
+}
+
+.jBox-title,
+.jBox-content,
+.jBox-container {
+ position: relative;
+ word-break: break-word;
+ box-sizing: border-box;
+}
+
+.jBox-container {
+ background: #fff;
+}
+
+.jBox-content {
+ padding: 8px 12px;
+ overflow-x: hidden;
+ overflow-y: auto;
+ transition: opacity .2s;
+}
+
+.jBox-footer {
+ box-sizing: border-box;
+}
+
+.jBox-Tooltip .jBox-container,
+.jBox-Mouse .jBox-container {
+ border-radius: 4px;
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
+}
+
+.jBox-Tooltip .jBox-title,
+.jBox-Mouse .jBox-title {
+ padding: 8px 10px 0;
+ font-weight: bold;
+}
+
+.jBox-Tooltip.jBox-hasTitle .jBox-content,
+.jBox-Mouse.jBox-hasTitle .jBox-content {
+ padding-top: 5px;
+}
+
+.jBox-Mouse {
+ pointer-events: none;
+}
+
+.jBox-pointer {
+ position: absolute;
+ overflow: hidden;
+ box-sizing: border-box;
+}
+
+.jBox-pointer:after {
+ content: '';
+ width: 20px;
+ height: 20px;
+ position: absolute;
+ background: #fff;
+ transform: rotate(45deg);
+ box-sizing: border-box;
+}
+
+.jBox-pointer-top {
+ top: 0;
+}
+
+.jBox-pointer-top:after {
+ left: 5px;
+ top: 6px;
+ box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-right {
+ right: 0;
+}
+
+.jBox-pointer-right:after {
+ top: 5px;
+ right: 6px;
+ box-shadow: 1px -1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-left {
+ left: 0;
+}
+
+.jBox-pointer-left:after {
+ top: 5px;
+ left: 6px;
+ box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-bottom {
+ bottom: 0;
+}
+
+.jBox-pointer-bottom:after {
+ left: 5px;
+ bottom: 6px;
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-top, .jBox-pointer-bottom {
+ width: 30px;
+ height: 12px;
+}
+
+.jBox-pointer-left, .jBox-pointer-right {
+ width: 12px;
+ height: 30px;
+}
+
+.jBox-Modal .jBox-container {
+ border-radius: 4px;
+}
+
+.jBox-Modal .jBox-container, .jBox-Modal.jBox-closeButton-box:before {
+ box-shadow: 0 3px 15px rgba(0, 0, 0, 0.4), 0 0 5px rgba(0, 0, 0, 0.4);
+}
+
+.jBox-Modal .jBox-content {
+ padding: 15px 20px;
+}
+
+.jBox-Modal .jBox-title {
+ border-radius: 4px 4px 0 0;
+ padding: 15px 20px;
+ background: #fafafa;
+ border-bottom: 1px solid #eee;
+}
+
+.jBox-Modal.jBox-closeButton-title .jBox-title {
+ padding-right: 65px;
+}
+
+.jBox-Modal .jBox-footer {
+ border-radius: 0 0 4px 4px;
+}
+
+.jBox-closeButton {
+ z-index: 1;
+ cursor: pointer;
+ position: absolute;
+ box-sizing: border-box;
+}
+
+.jBox-closeButton svg {
+ position: absolute;
+ top: 50%;
+ right: 50%;
+}
+
+.jBox-closeButton path {
+ fill: #aaa;
+ transition: fill .2s;
+}
+
+.jBox-closeButton:hover path {
+ fill: #888;
+}
+
+.jBox-overlay .jBox-closeButton {
+ top: 0;
+ right: 0;
+ width: 40px;
+ height: 40px;
+}
+
+.jBox-overlay .jBox-closeButton svg {
+ width: 20px;
+ height: 20px;
+ margin-top: -10px;
+ margin-right: -10px;
+}
+
+.jBox-overlay .jBox-closeButton path {
+ fill: #ddd;
+}
+
+.jBox-overlay .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-closeButton-title .jBox-closeButton {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ width: 50px;
+}
+
+.jBox-closeButton-title svg {
+ width: 12px;
+ height: 12px;
+ margin-top: -6px;
+ margin-right: -6px;
+}
+
+.jBox-closeButton-box {
+ box-sizing: border-box;
+}
+
+.jBox-closeButton-box .jBox-closeButton {
+ top: -8px;
+ right: -10px;
+ width: 24px;
+ height: 24px;
+ background: #fff;
+ border-radius: 50%;
+}
+
+.jBox-closeButton-box .jBox-closeButton svg {
+ width: 10px;
+ height: 10px;
+ margin-top: -5px;
+ margin-right: -5px;
+}
+
+.jBox-closeButton-box:before {
+ content: '';
+ position: absolute;
+ top: -8px;
+ right: -10px;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+
+.jBox-closeButton-box.jBox-pointerPosition-top:before {
+ top: 5px;
+}
+
+.jBox-closeButton-box.jBox-pointerPosition-right:before {
+ right: 2px;
+}
+
+.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton {
+ background: #fafafa;
+}
+
+.jBox-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.82);
+}
+
+.jBox-footer {
+ background: #fafafa;
+ border-top: 1px solid #eee;
+ padding: 8px 10px;
+ border-radius: 0 0 3px 3px;
+}
+
+body[class^="jBox-blockScroll-"],
+body[class*=" jBox-blockScroll-"] {
+ overflow: hidden;
+}
+
+.jBox-draggable {
+ cursor: move;
+}
+
+@keyframes jBoxLoading {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.jBox-loading .jBox-content {
+ opacity: .2;
+}
+
+.jBox-loading-spinner .jBox-content {
+ min-height: 38px !important;
+ min-width: 38px !important;
+ opacity: 0;
+}
+
+.jBox-spinner {
+ box-sizing: border-box;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 24px;
+ height: 24px;
+ margin-top: -12px;
+ margin-left: -12px;
+}
+
+.jBox-spinner:before {
+ display: block;
+ box-sizing: border-box;
+ content: '';
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ border: 2px solid rgba(0, 0, 0, 0.2);
+ border-top-color: rgba(0, 0, 0, 0.8);
+ animation: jBoxLoading .6s linear infinite;
+}
+
+.jBox-countdown {
+ border-radius: 4px 4px 0 0;
+ z-index: 0;
+ background: #000;
+ opacity: .2;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ overflow: hidden;
+}
+
+.jBox-countdown-inner {
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 3px;
+ position: absolute;
+ background: #fff;
+}
+
+[class^="jBox-animated-"],
+[class*=" jBox-animated-"] {
+ animation-fill-mode: both;
+}
+
+@keyframes jBox-tada {
+ 0% {
+ transform: scale(1);
+ }
+ 10%,
+ 20% {
+ transform: scale(0.8) rotate(-4deg);
+ }
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: scale(1.2) rotate(4deg);
+ }
+ 40%,
+ 60%,
+ 80% {
+ transform: scale(1.2) rotate(-4deg);
+ }
+ 100% {
+ transform: scale(1) rotate(0);
+ }
+}
+
+.jBox-animated-tada {
+ animation: jBox-tada 1s;
+}
+
+@keyframes jBox-tadaSmall {
+ 0% {
+ transform: scale(1);
+ }
+ 10%,
+ 20% {
+ transform: scale(0.9) rotate(-2deg);
+ }
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: scale(1.1) rotate(2deg);
+ }
+ 40%,
+ 60%,
+ 80% {
+ transform: scale(1.1) rotate(-2deg);
+ }
+ 100% {
+ transform: scale(1) rotate(0);
+ }
+}
+
+.jBox-animated-tadaSmall {
+ animation: jBox-tadaSmall 1s;
+}
+
+@keyframes jBox-flash {
+ 0%,
+ 50%,
+ 100% {
+ opacity: 1;
+ }
+ 25%,
+ 75% {
+ opacity: 0;
+ }
+}
+
+.jBox-animated-flash {
+ animation: jBox-flash .5s;
+}
+
+@keyframes jBox-shake {
+ 0%,
+ 100% {
+ transform: translateX(0);
+ }
+ 20%,
+ 60% {
+ transform: translateX(-6px);
+ }
+ 40%,
+ 80% {
+ transform: translateX(6px);
+ }
+}
+
+.jBox-animated-shake {
+ animation: jBox-shake .4s;
+}
+
+@keyframes jBox-pulseUp {
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.15);
+ }
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jBox-animated-pulseUp {
+ animation: jBox-pulseUp .25s;
+}
+
+@keyframes jBox-pulseDown {
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(0.85);
+ }
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jBox-animated-pulseDown {
+ animation: jBox-pulseDown .25s;
+}
+
+@keyframes jBox-popIn {
+ 0% {
+ transform: scale(0);
+ }
+ 50% {
+ transform: scale(1.1);
+ }
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jBox-animated-popIn {
+ animation: jBox-popIn .25s;
+}
+
+@keyframes jBox-popOut {
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.1);
+ }
+ 100% {
+ transform: scale(0);
+ }
+}
+
+.jBox-animated-popOut {
+ animation: jBox-popOut .25s;
+}
+
+@keyframes jBox-fadeIn {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+
+.jBox-animated-fadeIn {
+ animation: jBox-fadeIn .2s;
+}
+
+@keyframes jBox-fadeOut {
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
+
+.jBox-animated-fadeOut {
+ animation: jBox-fadeOut .2s;
+}
+
+@keyframes jBox-slideUp {
+ 0% {
+ transform: translateY(0);
+ }
+ 100% {
+ transform: translateY(-300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideUp {
+ animation: jBox-slideUp .4s;
+}
+
+@keyframes jBox-slideRight {
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideRight {
+ animation: jBox-slideRight .4s;
+}
+
+@keyframes jBox-slideDown {
+ 0% {
+ transform: translateY(0);
+ }
+ 100% {
+ transform: translateY(300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideDown {
+ animation: jBox-slideDown .4s;
+}
+
+@keyframes jBox-slideLeft {
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(-300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideLeft {
+ animation: jBox-slideLeft .4s;
+}
+
+.jBox-Confirm .jBox-content {
+ text-align: center;
+ padding: 46px 35px;
+}
+
+@media (max-width: 500px) {
+ .jBox-Confirm .jBox-content {
+ padding: 32px 20px;
+ }
+}
+
+.jBox-Confirm-footer {
+ height: 46px;
+}
+
+.jBox-Confirm-button {
+ display: block;
+ float: left;
+ cursor: pointer;
+ text-align: center;
+ width: 50%;
+ line-height: 46px;
+ height: 46px;
+ overflow: hidden;
+ padding: 0 10px;
+ transition: color .2s, background-color .2s;
+ box-sizing: border-box;
+}
+
+.jBox-Confirm-button-cancel {
+ border-bottom-left-radius: 4px;
+ background: #ddd;
+ color: #666;
+}
+
+.jBox-Confirm-button-cancel:hover, .jBox-Confirm-button-cancel:active {
+ background: #ccc;
+}
+
+.jBox-Confirm-button-cancel:active {
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
+}
+
+.jBox-Confirm-button-submit {
+ border-bottom-right-radius: 4px;
+ background: #7d0;
+ color: #fff;
+}
+
+.jBox-Confirm-button-submit:hover, .jBox-Confirm-button-submit:active {
+ background: #6c0;
+}
+
+.jBox-Confirm-button-submit:active {
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
+}
+
+.jBox-Image .jBox-container {
+ background-color: transparent;
+}
+
+.jBox-Image .jBox-content {
+ padding: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.jBox-image-container {
+ background: center center no-repeat;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+}
+
+.jBox-image-label-wrapper {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ height: 40px;
+ z-index: 100;
+ display: flex;
+}
+
+.jBox-image-label-container {
+ position: relative;
+ flex: 1;
+}
+
+.jBox-image-label {
+ box-sizing: border-box;
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ text-align: center;
+ color: #fff;
+ padding: 8px 12px;
+ font-size: 15px;
+ line-height: 24px;
+ transition: opacity .36s;
+ opacity: 0;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.jBox-image-label.expanded {
+ background: #000;
+}
+
+.jBox-image-label:not(.expanded) {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.jBox-image-label.active {
+ opacity: 1;
+ pointer-events: all;
+}
+
+@media (max-width: 600px) {
+ .jBox-image-label {
+ font-size: 13px;
+ }
+}
+
+.jBox-image-pointer-next,
+.jBox-image-pointer-prev {
+ flex-shrink: 0;
+ width: 40px;
+ height: 40px;
+ cursor: pointer;
+ opacity: .8;
+ transition: opacity .2s;
+ background: no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);
+ background-size: 11px auto;
+ user-select: none;
+ z-index: 1;
+}
+
+.jBox-image-pointer-next:hover,
+.jBox-image-pointer-prev:hover {
+ opacity: 1;
+}
+
+.jBox-image-pointer-next {
+ transform: scaleX(-1);
+}
+
+.jBox-image-counter-container {
+ flex-shrink: 0;
+ white-space: nowrap;
+ height: 40px;
+ line-height: 40px;
+ font-size: 13px;
+ color: #fff;
+ text-align: right;
+ display: none;
+}
+
+.jBox-image-has-counter .jBox-image-counter-container {
+ display: block;
+}
+
+.jBox-overlay.jBox-overlay-Image {
+ background: #000;
+}
+
+.jBox-image-not-found {
+ background: #000;
+}
+
+.jBox-image-not-found:before {
+ content: '';
+ box-sizing: border-box;
+ display: block;
+ width: 80px;
+ height: 80px;
+ margin-top: -40px;
+ margin-left: -40px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ border: 5px solid #222;
+ border-radius: 50%;
+}
+
+.jBox-image-not-found:after {
+ content: '';
+ display: block;
+ box-sizing: content-box;
+ z-index: auto;
+ width: 6px;
+ height: 74px;
+ margin-top: -37px;
+ margin-left: -3px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ background: #222;
+ transform: rotateZ(45deg);
+ transform-origin: 50% 50% 0;
+}
+
+.jBox-image-download-button-wrapper {
+ position: absolute;
+ top: -40px;
+ right: 35px;
+ height: 40px;
+ display: flex;
+ cursor: pointer;
+ opacity: .8;
+ transition: opacity .2s;
+}
+
+.jBox-image-download-button-wrapper:hover {
+ opacity: 1;
+}
+
+.jBox-image-download-button-icon {
+ width: 40px;
+ height: 40px;
+ background: center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);
+ background-size: 60%;
+}
+
+.jBox-image-download-button-text {
+ white-space: nowrap;
+ line-height: 40px;
+ padding: 0 10px 0 0;
+ color: #fff;
+ font-size: 14px;
+}
+
+@keyframes jBoxImageLoading {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.jBox-image-loading:before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 32px;
+ height: 32px;
+ margin-top: -16px;
+ margin-left: -16px;
+ border: 4px solid #333;
+ border-bottom-color: #666;
+ animation: jBoxImageLoading 1.2s linear infinite;
+ border-radius: 50%;
+}
+
+.jBox-Notice {
+ transition: margin .2s;
+}
+
+.jBox-Notice .jBox-container {
+ border-radius: 4px;
+ box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.25), inset -1px -1px 0 0 rgba(0, 0, 0, 0.1);
+}
+
+.jBox-Notice .jBox-content {
+ border-radius: 4px;
+ padding: 12px 20px;
+}
+
+@media (max-width: 768px) {
+ .jBox-Notice .jBox-content {
+ padding: 10px 15px;
+ }
+}
+
+@media (max-width: 500px) {
+ .jBox-Notice .jBox-content {
+ padding: 8px 10px;
+ }
+}
+
+.jBox-Notice.jBox-hasTitle .jBox-content {
+ padding-top: 5px;
+}
+
+@media (max-width: 500px) {
+ .jBox-Notice.jBox-hasTitle .jBox-content {
+ padding-top: 0;
+ }
+}
+
+.jBox-Notice.jBox-hasTitle .jBox-title {
+ padding: 12px 20px 0;
+ font-weight: bold;
+}
+
+@media (max-width: 768px) {
+ .jBox-Notice.jBox-hasTitle .jBox-title {
+ padding: 10px 15px 0;
+ }
+}
+
+@media (max-width: 500px) {
+ .jBox-Notice.jBox-hasTitle .jBox-title {
+ padding: 8px 10px 0;
+ }
+}
+
+.jBox-Notice.jBox-closeButton-title .jBox-title {
+ padding-right: 55px;
+}
+
+.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+ width: 40px;
+}
+
+.jBox-Notice.jBox-Notice-black .jBox-container {
+ color: #fff;
+ background: #000;
+}
+
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-gray .jBox-container {
+ color: #222;
+ background: #f6f6f6;
+}
+
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #222;
+}
+
+.jBox-Notice.jBox-Notice-red .jBox-container {
+ color: #fff;
+ background: #d00;
+}
+
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-green .jBox-container {
+ color: #fff;
+ background: #5d0;
+}
+
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-blue .jBox-container {
+ color: #fff;
+ background: #49d;
+}
+
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-yellow .jBox-container {
+ color: #000;
+ background: #fd0;
+}
+
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-NoticeFancy .jBox-content,
+.jBox-NoticeFancy .jBox-title {
+ padding-left: 25px;
+}
+
+.jBox-NoticeFancy.jBox-Notice-color .jBox-container {
+ color: #fff;
+ background: #000;
+}
+
+.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 8px;
+ border-radius: 4px 0 0 4px;
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
+ background-size: 14px 14px;
+}
+
+.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,
+.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after {
+ background-color: #888;
+}
+
+.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after {
+ background-color: #e00;
+}
+
+.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after {
+ background-color: #6c0;
+}
+
+.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after {
+ background-color: #49d;
+}
+
+.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after {
+ background-color: #fb0;
+}
+
+.jBox-NoticeFancy .jBox-countdown {
+ left: 8px;
+ border-radius: 0 4px 0 0;
+}
+
+.jBox-TooltipBorder .jBox-container,
+.jBox-TooltipBorder .jBox-pointer:after {
+ border: 2px solid #49d;
+}
+
+.jBox-TooltipBorder .jBox-pointer:after {
+ width: 22px;
+ height: 22px;
+}
+
+.jBox-TooltipBorder .jBox-pointer-top,
+.jBox-TooltipBorder .jBox-pointer-bottom {
+ width: 34px;
+ height: 13px;
+}
+
+.jBox-TooltipBorder .jBox-pointer-top:after,
+.jBox-TooltipBorder .jBox-pointer-bottom:after {
+ left: 6px;
+}
+
+.jBox-TooltipBorder .jBox-pointer-left,
+.jBox-TooltipBorder .jBox-pointer-right {
+ width: 13px;
+ height: 34px;
+}
+
+.jBox-TooltipBorder .jBox-pointer-left:after,
+.jBox-TooltipBorder .jBox-pointer-right:after {
+ top: 6px;
+}
+
+.jBox-TooltipBorder.jBox-closeButton-box:before {
+ width: 28px;
+ height: 28px;
+ background: #49d;
+}
+
+.jBox-TooltipBorderThick .jBox-container {
+ box-shadow: none;
+ border-radius: 8px;
+ border: 4px solid #ccc;
+}
+
+.jBox-TooltipBorderThick .jBox-pointer:after {
+ box-shadow: none;
+ border: 4px solid #ccc;
+ width: 24px;
+ height: 24px;
+}
+
+.jBox-TooltipBorderThick .jBox-pointer-top,
+.jBox-TooltipBorderThick .jBox-pointer-bottom {
+ width: 38px;
+ height: 13px;
+}
+
+.jBox-TooltipBorderThick .jBox-pointer-left,
+.jBox-TooltipBorderThick .jBox-pointer-right {
+ width: 13px;
+ height: 38px;
+}
+
+.jBox-TooltipBorderThick.jBox-closeButton-box:before {
+ width: 32px;
+ height: 32px;
+ background: #ccc;
+}
+
+.jBox-TooltipDark .jBox-container {
+ border-radius: 4px;
+ background: #000;
+ color: #fff;
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
+}
+
+.jBox-TooltipDark .jBox-pointer:after {
+ background: #000;
+}
+
+.jBox-TooltipDark .jBox-closeButton {
+ background: #000;
+}
+
+.jBox-TooltipDark.jBox-closeButton-box:before {
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
+}
+
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path {
+ fill: #ddd;
+}
+
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path {
+ fill: #bbb;
+}
+
+.jBox-TooltipError {
+ pointer-events: none;
+}
+
+.jBox-TooltipError .jBox-container {
+ border-radius: 2px;
+ background: #d00;
+ color: #fff;
+ font-weight: bold;
+ font-size: 13px;
+}
+
+.jBox-TooltipError .jBox-content {
+ padding: 0 10px;
+ line-height: 28px;
+}
+
+.jBox-TooltipError .jBox-pointer:after {
+ background: #d00;
+ width: 20px;
+ height: 20px;
+}
+
+.jBox-TooltipError .jBox-pointer-top, .jBox-TooltipError .jBox-pointer-bottom {
+ width: 22px;
+ height: 8px;
+}
+
+.jBox-TooltipError .jBox-pointer-right, .jBox-TooltipError .jBox-pointer-left {
+ width: 8px;
+ height: 22px;
+}
+
+.jBox-TooltipError .jBox-pointer-top:after {
+ left: 1px;
+ top: 6px;
+}
+
+.jBox-TooltipError .jBox-pointer-right:after {
+ top: 1px;
+ right: 6px;
+}
+
+.jBox-TooltipError .jBox-pointer-bottom:after {
+ left: 1px;
+ bottom: 6px;
+}
+
+.jBox-TooltipError .jBox-pointer-left:after {
+ top: 1px;
+ left: 6px;
+}
+
+.jBox-TooltipSmall {
+ pointer-events: none;
+}
+
+.jBox-TooltipSmall .jBox-container {
+ border-radius: 2px;
+}
+
+.jBox-TooltipSmall .jBox-content {
+ padding: 0 10px;
+ line-height: 28px;
+}
+
+.jBox-TooltipSmall .jBox-pointer:after {
+ width: 20px;
+ height: 20px;
+}
+
+.jBox-TooltipSmall .jBox-pointer-top, .jBox-TooltipSmall .jBox-pointer-bottom {
+ width: 22px;
+ height: 8px;
+}
+
+.jBox-TooltipSmall .jBox-pointer-right, .jBox-TooltipSmall .jBox-pointer-left {
+ width: 8px;
+ height: 22px;
+}
+
+.jBox-TooltipSmall .jBox-pointer-top:after {
+ left: 1px;
+ top: 6px;
+}
+
+.jBox-TooltipSmall .jBox-pointer-right:after {
+ top: 1px;
+ right: 6px;
+}
+
+.jBox-TooltipSmall .jBox-pointer-bottom:after {
+ left: 1px;
+ bottom: 6px;
+}
+
+.jBox-TooltipSmall .jBox-pointer-left:after {
+ top: 1px;
+ left: 6px;
+}
+
+.jBox-TooltipSmallGray {
+ pointer-events: none;
+}
+
+.jBox-TooltipSmallGray .jBox-container {
+ font-size: 13px;
+ line-height: 24px;
+ border-radius: 12px;
+ background-image: linear-gradient(to bottom, #fafafa, #f2f2f2);
+}
+
+.jBox-TooltipSmallGray .jBox-content {
+ padding: 0 10px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer:after {
+ width: 20px;
+ height: 20px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-top, .jBox-TooltipSmallGray .jBox-pointer-bottom {
+ width: 22px;
+ height: 8px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-left, .jBox-TooltipSmallGray .jBox-pointer-right {
+ width: 8px;
+ height: 22px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-top:after {
+ background: #fafafa;
+ left: 1px;
+ top: 6px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-right:after {
+ top: 1px;
+ right: 6px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-bottom:after {
+ background: #f2f2f2;
+ left: 1px;
+ bottom: 6px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-left:after {
+ top: 1px;
+ left: 6px;
+}
+
+/*# sourceMappingURL=jBox.all.css.map */
diff --git a/dist/jBox.all.js b/dist/jBox.all.js
new file mode 100755
index 0000000..bb81b40
--- /dev/null
+++ b/dist/jBox.all.js
@@ -0,0 +1,2953 @@
+/**
+ * jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jQuery 3.5.0 (https://code.jquery.com/jquery-3.5.0.min.js)
+ *
+ * Documentation: https://stephanwagner.me/jBox/documentation
+ *
+ * Demos: https://stephanwagner.me/jBox/demos
+ */
+
+function jBoxWrapper(jQuery) {
+
+
+ var jBox = function jBox(type, options) {
+
+
+ // Options (https://stephanwagner.me/jBox/options)
+
+ this.options = {
+
+ // jBox ID
+ id: null, // Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...)
+
+ // Dimensions
+ width: 'auto', // The width of the content area, e.g. 'auto', 200, '80%'
+ height: 'auto', // The height of the content area
+ minWidth: null, // Minimal width
+ minHeight: null, // Minimal height
+ maxWidth: null, // Maximal width
+ maxHeight: null, // Maximal height
+
+ // Responsive dimensions
+ responsiveWidth: true, // Adjusts the width to fit the viewport
+ responsiveHeight: true, // Adjusts the height to fit the viewport
+ responsiveMinWidth: 100, // Don't adjust width below this value (in pixel)
+ responsiveMinHeight: 100, // Don't adjust height below this value (in pixel)
+
+ // Attach
+ attach: null, // A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip'
+ trigger: 'click', // The event to open or close your jBox, use 'click', 'touchclick' or 'mouseenter'
+ preventDefault: false, // Prevent the default event when opening jBox, e.g. don't follow the href in a link
+
+ // Content
+ content: null, // You can use HTML or a jQuery element, e.g. jQuery('#jBox-content'). The elements will be appended to the content element and then made visible, so hide them with style="display: none" beforehand
+ getContent: null, // Get the content from an attribute when jBox opens, e.g. getContent: 'data-content'. Use 'html' to get the attached elements HTML as content
+ title: null, // Adds a title to your jBox
+ getTitle: null, // Get the title from an attribute when jBox opens, e.g. getTitle: 'data-title'
+ footer: null, // Adds a footer to your jBox
+ isolateScroll: true, // Isolates scrolling to the content container
+
+ // AJAX
+ ajax: { // Setting an URL will make an AJAX request when jBox opens. Optional you can add any jQuery AJAX option (http://api.jquery.com/jquery.ajax/)
+ url: null, // The URL to send the AJAX request to
+ data: '', // Data to send with your AJAX request, e.g. {id: 82, limit: 10}
+ reload: false, // Resend the AJAX request when jBox opens. Use true to send the AJAX request only once for every attached element or 'strict' to resend every time jBox opens
+ getURL: 'data-url', // The attribute in the source element where the AJAX request will look for the URL, e.g. data-url="https://reqres.in/api/users"
+ getData: 'data-ajax', // The attribute in the source element where the AJAX request will look for the data, e.g. data-ajax="id=82&limit=10"
+ setContent: true, // Automatically set the response as new content when the AJAX request is finished
+ loadingClass: true, // Add a class to the wrapper when jBox is loading, set to class name or true to use the default class name 'jBox-loading'
+ spinner: true, // Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '
'
+ spinnerDelay: 300, // Milliseconds to wait until spinner appears
+ spinnerReposition: true // Repositions jBox when the spinner is added or removed
+ },
+ cancelAjaxOnClose: true, // Cancels the ajax call when jBox closes and it hasn't finished loading yet
+
+ // Position
+ target: null, // The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target
+ position: {
+ x: 'center', // Horizontal position, use a number, 'left', 'right' or 'center'
+ y: 'center' // Vertical position, use a number, 'top', 'bottom' or 'center'
+ },
+ outside: null, // Use 'x', 'y', or 'xy' to move your jBox outside of the target element
+ offset: 0, // Offset to final position, you can set different values for x and y with an object, e.g. {x: 20, y: 10}
+ attributes: { // Note that attributes can only be 'left' or 'right' when using numbers for position, e.g. {x: 300, y: 20}
+ x: 'left', // Horizontal position, use 'left' or 'right'
+ y: 'top' // Vertical position, use 'top' or 'bottom'
+ },
+ fixed: false, // Your jBox will stay on position when scrolling
+ adjustPosition: true, // Adjusts your jBoxes position if there is not enough space, use 'flip', 'move' or true for both. This option overrides the reposition options
+ adjustTracker: false, // By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling
+ adjustDistance: 5, // The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5}
+ reposition: true, // Calculates new position when the window-size changes
+ repositionOnOpen: true, // Calculates new position each time jBox opens (rather than only when it opens the first time)
+ repositionOnContent: true, // Calculates new position when the content changes with .setContent() or .setTitle()
+ holdPosition: true, // Keeps current position if space permits. Applies only to 'Modal' type.
+
+ // Pointer
+ pointer: false, // Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20'
+ pointTo: 'target', // Setting something else than 'target' will add a pointer even if there is no target element set or found. Use 'top', 'right', 'bottom' or 'left'
+
+ // Animations
+ fade: 180, // Fade duration in ms, set to 0 or false to disable
+ animation: null, // Animation when opening or closing, use 'pulse', 'zoomIn', 'zoomOut', 'move', 'slide', 'flip', 'tada' (CSS inspired from Daniel Edens Animate.css: http://daneden.me/animate)
+
+ // Appearance
+ theme: 'Default', // Set a jBox theme class
+ addClass: null, // Adds classes to the wrapper
+ overlay: false, // Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS)
+ overlayClass: null, // Add a class name to the overlay
+ zIndex: 10000, // Use a high z-index, or set to 'auto' to bring to front on open
+
+ // Delays
+ delayOpen: 0, // Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing
+ delayClose: 0, // Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away
+
+ // Closing
+ closeOnEsc: false, // Close jBox when pressing [esc] key
+ closeOnClick: false, // Close jBox with mouseclick. Use true (click anywhere), 'box' (click on jBox itself), 'overlay' (click on the overlay), 'body' (click anywhere but jBox)
+ closeOnMouseleave: false, // Close jBox when the mouse leaves the jBox area or the area of the attached element
+ closeButton: false, // Adds a close button to your jBox. Use 'title', 'box', 'overlay' or true (true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found)
+
+ // Other options
+ appendTo: jQuery('body'), // The element your jBox will be appended to. Any other element than jQuery('body') is only useful for fixed positions or when position values are numbers
+ createOnInit: false, // Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time
+ blockScroll: false, // Blocks scrolling when jBox is open
+ blockScrollAdjust: true, // Adjust page elements to avoid content jumps when scrolling is blocked. See more here: https://github.com/StephanWagner/unscroll
+ draggable: false, // Make your jBox draggable (use 'true', 'title' or provide an element as handle) (inspired from Chris Coyiers CSS-Tricks http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/)
+ dragOver: true, // When you have multiple draggable jBoxes, the one you select will always move over the other ones
+ autoClose: false, // Time in ms when jBox will close automatically after it was opened
+ delayOnHover: false, // Delay auto-closing while mouse is hovered
+ showCountdown: false, // Display a nice progress-indicator when autoClose is enabled
+
+ // Audio // You can use the integrated audio function whenever you'd like to play an audio file, e.g. onInit: function () { this.audio('url_to_audio_file_without_file_extension', 75); }
+ preloadAudio: true, // Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg']
+ audio: null, // The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'}
+ volume: 100, // The volume in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100}
+
+ // Events // Note that you can use 'this' in all event functions, it refers to your jBox object (e.g. onInit: function () { this.open(); })
+ onInit: null, // Fired when jBox is initialized
+ onAttach: null, // Fired when jBox attached itself to elements, the attached element will be passed as a parameter, e.g. onAttach: function (element) { element.css({color: 'red'}); }
+ onPosition: null, // Fired when jBox is positioned
+ onCreated: null, // Fired when jBox is created and availible in DOM
+ onOpen: null, // Fired when jBox opens
+ onOpenComplete: null, // Fired when jBox is completely open (when fading is finished)
+ onClose: null, // Fired when jBox closes
+ onCloseComplete: null, // Fired when jBox is completely closed (when fading is finished)
+ onDragStart: null, // Fired when dragging starts
+ onDragEnd: null // Fired when dragging finished
+ };
+
+
+ // Default plugin options
+
+ this._pluginOptions = {
+
+ // Default options for tooltips
+ 'Tooltip': {
+ getContent: 'title',
+ trigger: 'mouseenter',
+ position: {
+ x: 'center',
+ y: 'top'
+ },
+ outside: 'y',
+ pointer: true
+ },
+
+ // Default options for mouse tooltips
+ 'Mouse': {
+ responsiveWidth: false,
+ responsiveHeight: false,
+ adjustPosition: 'flip',
+ target: 'mouse',
+ trigger: 'mouseenter',
+ position: {
+ x: 'right',
+ y: 'bottom'
+ },
+ outside: 'xy',
+ offset: 5
+ },
+
+ // Default options for modal windows
+ 'Modal': {
+ target: jQuery(window),
+ fixed: true,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: 'overlay',
+ closeButton: true,
+ overlay: true,
+ animation: 'zoomIn'
+ },
+ };
+
+
+ // Merge options
+
+ this.options = jQuery.extend(true, this.options, this._pluginOptions[type] ? this._pluginOptions[type] : jBox._pluginOptions[type], options);
+
+
+ // Set the jBox type
+
+ jQuery.type(type) == 'string' && (this.type = type);
+
+
+ // Checks if the user is on a touch device, borrowed from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
+
+ this.isTouchDevice = (function () {
+ var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
+ var mq = function (query) {
+ return window.matchMedia(query).matches;
+ }
+
+ if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
+ return true;
+ }
+
+ var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
+ return mq(query);
+ })();
+
+
+ // Add close event for body click when we are on touch device and jBox triggers on mouseenter
+
+ if (this.isTouchDevice && this.options.trigger === 'mouseenter' && this.options.closeOnClick === false) {
+ this.options.closeOnClick = 'body';
+ }
+
+
+ // Local function to fire events
+
+ this._fireEvent = function (event, pass)
+ {
+ this.options['_' + event] && (this.options['_' + event].bind(this))(pass);
+ this.options[event] && (this.options[event].bind(this))(pass);
+ };
+
+
+ // Get a unique jBox ID
+
+ this.options.id === null && (this.options.id = 'jBox' + jBox._getUniqueID());
+ this.id = this.options.id;
+
+
+ // Correct impossible options
+
+ ((this.options.position.x == 'center' && this.options.outside == 'x') || (this.options.position.y == 'center' && this.options.outside == 'y')) && (this.options.outside = null);
+ this.options.pointTo == 'target' && (!this.options.outside || this.options.outside == 'xy') && (this.options.pointer = false);
+
+
+ // Correct multiple choice options
+
+ jQuery.type(this.options.offset) != 'object' ? (this.options.offset = {x: this.options.offset, y: this.options.offset}) : (this.options.offset = jQuery.extend({x: 0, y: 0}, this.options.offset));
+ jQuery.type(this.options.adjustDistance) != 'object' ? (this.options.adjustDistance = {top: this.options.adjustDistance, right: this.options.adjustDistance, bottom: this.options.adjustDistance, left: this.options.adjustDistance}) : (this.options.adjustDistance = jQuery.extend({top: 5, left: 5, right: 5, bottom: 5}, this.options.adjustDistance));
+
+
+ // Save default outside position
+
+ this.outside = this.options.outside && this.options.outside != 'xy' ? this.options.position[this.options.outside] : false;
+
+
+ // Save where the jBox is aligned to
+
+ this.align = this.outside ? this.outside : (this.options.position.y != 'center' && jQuery.type(this.options.position.y) != 'number' ? this.options.position.x : (this.options.position.x != 'center' && jQuery.type(this.options.position.x) != 'number' ? this.options.position.y : this.options.attributes.x));
+
+
+ // Adjust option zIndex
+
+ jBox.zIndexMax = Math.max(jBox.zIndexMax || 0, this.options.zIndex === 'auto' ? 10000 : this.options.zIndex);
+ if (this.options.zIndex === 'auto') {
+ this.adjustZIndexOnOpen = true;
+ jBox.zIndexMax += 2;
+ this.options.zIndex = jBox.zIndexMax;
+ this.trueModal = this.options.overlay;
+ }
+
+ // Internal positioning functions
+
+ this._getOpp = function (opp) { return {left: 'right', right: 'left', top: 'bottom', bottom: 'top', x: 'y', y: 'x'}[opp]; };
+ this._getXY = function (xy) { return {left: 'x', right: 'x', top: 'y', bottom: 'y', center: 'x'}[xy]; };
+ this._getTL = function (tl) { return {left: 'left', right: 'left', top: 'top', bottom: 'top', center: 'left', x: 'left', y: 'top'}[tl]; };
+
+
+ // Get a dimension value in integer pixel dependent on appended element
+
+ this._getInt = function (value, dimension) {
+ if (value == 'auto') return 'auto';
+ if (value && jQuery.type(value) == 'string' && value.slice(-1) == '%') {
+ return jQuery(window)[dimension == 'height' ? 'innerHeight' : 'innerWidth']() * parseInt(value.replace('%', '')) / 100;
+ }
+ return value;
+ };
+
+
+ // Create an svg element
+
+ this._createSVG = function (type, options)
+ {
+ var svg = document.createElementNS('http://www.w3.org/2000/svg', type);
+ jQuery.each(options, function (index, item) {
+ svg.setAttribute(item[0], (item[1] || ''));
+ });
+ return svg;
+ };
+
+
+ // Isolate scrolling in a container
+
+ this._isolateScroll = function (el)
+ {
+ // Abort if element not found
+ if (!el || !el.length) return;
+
+ el.on('DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll', function (ev) {
+ var delta = ev.wheelDelta || (ev.originalEvent && ev.originalEvent.wheelDelta) || -ev.detail;
+ var overflowBottom = this.scrollTop + el.outerHeight() - this.scrollHeight >= 0;
+ var overflowTop = this.scrollTop <= 0;
+ ((delta < 0 && overflowBottom) || (delta > 0 && overflowTop)) && ev.preventDefault();
+ });
+ };
+
+
+ // Set the title width to content width
+
+ this._setTitleWidth = function ()
+ {
+ // Abort if there is no title or width of content is auto
+ if (!this.titleContainer || (this.content[0].style.width == 'auto' && !this.content[0].style.maxWidth)) return null;
+
+ // Expose wrapper to get actual width
+ if (this.wrapper.css('display') == 'none') {
+ this.wrapper.css('display', 'block');
+ var contentWidth = this.content.outerWidth();
+ this.wrapper.css('display', 'none');
+ } else {
+ var contentWidth = this.content.outerWidth();
+ }
+
+ // Set max-width only
+ this.titleContainer.css({maxWidth: (Math.max(contentWidth, parseInt(this.content[0].style.maxWidth)) || null)});
+ }
+
+
+ // Make jBox draggable
+
+ this._draggable = function ()
+ {
+ // Abort if jBox is not draggable
+ if (!this.options.draggable) return false;
+
+ // Get the handle where jBox will be dragged with
+ var handle = this.options.draggable == 'title' ? this.titleContainer : (this.options.draggable instanceof jQuery ? this.options.draggable : (jQuery.type(this.options.draggable) == 'string' ? jQuery(this.options.draggable) : this.wrapper));
+
+ // Abort if no handle or if draggable was set already
+ if (!handle || !(handle instanceof jQuery) || !handle.length || handle.data('jBox-draggable')) {
+ return false;
+ }
+
+ // Add mouse events
+ handle.addClass('jBox-draggable').data('jBox-draggable', true).on('touchstart mousedown', function (ev)
+ {
+ if (ev.button == 2 || jQuery(ev.target).hasClass('jBox-noDrag') || jQuery(ev.target).parents('.jBox-noDrag').length) {
+ // Hacky fix for jBox not closing on mobile devices when using draggable
+ if (ev.type == 'touchstart' && (jQuery(ev.target).hasClass('jBox-closeButton') || jQuery(ev.target).parents('.jBox-closeButton').length)) {
+ this.close({ignoreDelay: true});
+ }
+ return;
+ }
+
+ var pageX;
+ var pageY;
+
+ if (ev.type == 'touchstart' && ev.touches && ev.touches[0]) {
+ pageX = ev.touches[0].pageX;
+ pageY = ev.touches[0].pageY;
+ } else {
+ pageX = ev.pageX;
+ pageY = ev.pageY;
+ }
+
+ // Store current mouse position
+ this.draggingStartX = pageX;
+ this.draggingStartY = pageY;
+
+ // Adjust z-index when dragging jBox over another draggable jBox
+ if (this.options.dragOver && !this.trueModal && parseInt(this.wrapper.css('zIndex'), 10) <= jBox.zIndexMaxDragover) {
+ jBox.zIndexMaxDragover += 1;
+ this.wrapper.css('zIndex', jBox.zIndexMaxDragover);
+ }
+
+ var drg_h = this.wrapper.outerHeight();
+ var drg_w = this.wrapper.outerWidth();
+ var pos_y = this.wrapper.offset().top + drg_h - pageY;
+ var pos_x = this.wrapper.offset().left + drg_w - pageX;
+
+ jQuery(document).on('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id, function (ev) {
+
+ var movingPageX;
+ var movingPageY;
+
+ if (ev.type == 'touchmove' && ev.touches && ev.touches[0]) {
+ movingPageX = ev.touches[0].pageX;
+ movingPageY = ev.touches[0].pageY;
+ } else {
+ movingPageX = ev.pageX;
+ movingPageY = ev.pageY;
+ }
+
+ // Fire onDragStart event when jBox moves
+ if (!this.dragging && this.draggingStartX != movingPageX && this.draggingStartY != movingPageY) {
+ this._fireEvent('onDragStart');
+ this.dragging = true;
+ }
+
+ // Adjust position
+ this.wrapper.offset({
+ top: movingPageY + pos_y - drg_h,
+ left: movingPageX + pos_x - drg_w
+ });
+ }.bind(this));
+ ev.preventDefault();
+
+ }.bind(this)).on('touchend mouseup', function () {
+ // Remove drag event
+ jQuery(document).off('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id);
+
+ // Fire onDragEnd event
+ this.dragging && this._fireEvent('onDragEnd');
+
+ // Reset dragging reference
+ this.dragging = false;
+
+ if ((this.type == 'Modal' || this.type == 'Confirm') && this.options.holdPosition) {
+ // Drag end captures new position
+ var jBoxOffset = jQuery('#' + this.id).offset(),
+ pos = {
+ x: jBoxOffset.left - jQuery(document).scrollLeft(),
+ y: jBoxOffset.top - jQuery(document).scrollTop()
+ };
+ this.position({position: pos, offset: {x: 0, y: 0}});
+ }
+ }.bind(this));
+
+ // Get highest z-index
+ if (!this.trueModal) {
+ jBox.zIndexMaxDragover = !jBox.zIndexMaxDragover ? this.options.zIndex : Math.max(jBox.zIndexMaxDragover, this.options.zIndex);
+ }
+
+ return this;
+ };
+
+ // Create jBox
+
+ this._create = function ()
+ {
+ // Abort if jBox was created already
+ if (this.wrapper) return;
+
+ // Create wrapper
+ this.wrapper = jQuery('
', {
+ id: this.id,
+ 'class': 'jBox-wrapper' + (this.type ? ' jBox-' + this.type : '') + (this.options.theme ? ' jBox-' + this.options.theme : '') + (this.options.addClass ? ' ' + this.options.addClass : '')
+ }).css({
+ position: (this.options.fixed ? 'fixed' : 'absolute'),
+ display: 'none',
+ opacity: 0,
+ zIndex: this.options.zIndex
+
+ // Save the jBox instance in the wrapper, so you can get access to your jBox when you only have the element
+ }).data('jBox', this);
+
+ // Add mouseleave event, only close jBox when the new target is not the source element
+ this.options.closeOnMouseleave && this.wrapper.on('mouseleave', function (ev) {
+ !this.source || !(ev.relatedTarget == this.source[0] || jQuery.inArray(this.source[0], jQuery(ev.relatedTarget).parents('*')) !== -1) && this.close();
+ }.bind(this));
+
+ // Add closeOnClick: 'box' events
+ (this.options.closeOnClick == 'box') && this.wrapper.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
+
+ // Create container
+ this.container = jQuery('
').appendTo(this.wrapper);
+
+ // Create content
+ this.content = jQuery('
').appendTo(this.container);
+
+ // Create footer
+ this.options.footer && (this.footer = jQuery('').append(this.options.footer).appendTo(this.container));
+
+ // Isolate scrolling
+ this.options.isolateScroll && this._isolateScroll(this.content);
+
+ // Create close button
+ if (this.options.closeButton) {
+ var closeButtonSVG = this._createSVG('svg', [['viewBox', '0 0 24 24']]);
+ closeButtonSVG.appendChild(this._createSVG('path', [['d', 'M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z']]));
+ this.closeButton = jQuery('
').on('click tap', function (ev) { this.close({ignoreDelay: true}); }.bind(this)).append(closeButtonSVG);
+
+ // Add close button to jBox container
+ if (this.options.closeButton == 'box' || (this.options.closeButton === true && !this.options.overlay && !this.options.title && !this.options.getTitle)) {
+ this.wrapper.addClass('jBox-closeButton-box');
+ this.closeButton.appendTo(this.container);
+ }
+ }
+
+ // Append jBox to DOM
+ this.wrapper.appendTo(this.options.appendTo);
+
+ // Fix adjustDistance if there is a close button in the box
+ this.wrapper.find('.jBox-closeButton').length && jQuery.each(['top', 'right', 'bottom', 'left'], function (index, pos) {
+ this.wrapper.find('.jBox-closeButton').css(pos) && this.wrapper.find('.jBox-closeButton').css(pos) != 'auto' && (this.options.adjustDistance[pos] = Math.max(this.options.adjustDistance[pos], this.options.adjustDistance[pos] + (((parseInt(this.wrapper.find('.jBox-closeButton').css(pos)) || 0) + (parseInt(this.container.css('border-' + pos + '-width')) || 0)) * -1)));
+ }.bind(this));
+
+ // Create pointer
+ if (this.options.pointer) {
+
+ // Get pointer vars and save globally
+ this.pointer = {
+ position: (this.options.pointTo != 'target') ? this.options.pointTo : this._getOpp(this.outside),
+ xy: (this.options.pointTo != 'target') ? this._getXY(this.options.pointTo) : this._getXY(this.outside),
+ align: 'center',
+ offset: 0
+ };
+
+ this.pointer.element = jQuery('
').appendTo(this.wrapper);
+ this.pointer.dimensions = {
+ x: this.pointer.element.outerWidth(),
+ y: this.pointer.element.outerHeight()
+ };
+
+ if (jQuery.type(this.options.pointer) == 'string') {
+ var split = this.options.pointer.split(':');
+ split[0] && (this.pointer.align = split[0]);
+ split[1] && (this.pointer.offset = parseInt(split[1]));
+ }
+ this.pointer.alignAttribute = (this.pointer.xy == 'x' ? (this.pointer.align == 'bottom' ? 'bottom' : 'top') : (this.pointer.align == 'right' ? 'right' : 'left'));
+
+ // Set wrapper CSS
+ this.wrapper.css('padding-' + this.pointer.position, this.pointer.dimensions[this.pointer.xy]);
+
+ // Set pointer CSS
+ this.pointer.element.css(this.pointer.alignAttribute, (this.pointer.align == 'center' ? '50%' : 0)).css('margin-' + this.pointer.alignAttribute, this.pointer.offset);
+ this.pointer.margin = {};
+ this.pointer.margin['margin-' + this.pointer.alignAttribute] = this.pointer.offset;
+
+ // Add a transform to fix centered position
+ (this.pointer.align == 'center') && this.pointer.element.css('transform', 'translate(' + (this.pointer.xy == 'y' ? (this.pointer.dimensions.x * -0.5 + 'px') : 0) + ', ' + (this.pointer.xy == 'x' ? (this.pointer.dimensions.y * -0.5 + 'px') : 0) + ')');
+
+ this.pointer.element.css((this.pointer.xy == 'x' ? 'width' : 'height'), parseInt(this.pointer.dimensions[this.pointer.xy]) + parseInt(this.container.css('border-' + this.pointer.alignAttribute + '-width')));
+
+ // Add class to wrapper for CSS access
+ this.wrapper.addClass('jBox-pointerPosition-' + this.pointer.position);
+ }
+
+ // Set title and content
+ this.setContent(this.options.content, true);
+ this.setTitle(this.options.title, true);
+
+ this.options.draggable && this._draggable();
+
+ // Fire onCreated event
+ this._fireEvent('onCreated');
+ };
+
+
+ // Create jBox onInit
+
+ this.options.createOnInit && this._create();
+
+
+ // Attach jBox
+
+ this.options.attach && this.attach();
+
+
+ // Attach document and window events
+
+ this._attachEvents = function ()
+ {
+ // Cancel countdown on mouseenter if delayOnHover
+ this.options.delayOnHover && jQuery('#' + this.id).on('mouseenter', function (ev) { this.isHovered = true; }.bind(this));
+
+ // Resume countdown on mouseleave if delayOnHover
+ this.options.delayOnHover && jQuery('#' + this.id).on('mouseleave', function (ev) { this.isHovered = false; }.bind(this));
+
+ // Positioning events
+ if ((this.options.adjustPosition || this.options.reposition) && !this.fixed && this.outside) {
+
+ // Trigger position events when scrolling
+ this.options.adjustTracker && jQuery(window).on('scroll.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
+
+ // Trigger position events when resizing
+ (this.options.adjustPosition || this.options.reposition) && jQuery(window).on('resize.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
+ }
+
+ // Mousemove events
+ this.options.target == 'mouse' && jQuery('body').on('mousemove.jBox-' + this.id, function (ev) { this.position({mouseTarget: {top: ev.pageY, left: ev.pageX}}); }.bind(this));
+ };
+
+
+ // Detach document and window events
+
+ this._detachEvents = function ()
+ {
+ // Closing event: closeOnEsc
+ this.options.closeOnEsc && jQuery(document).off('keyup.jBox-' + this.id);
+
+ // Closing event: closeOnClick
+ (this.options.closeOnClick === true || this.options.closeOnClick == 'body') && jQuery(document).off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+
+ // Positioning events
+ this.options.adjustTracker && jQuery(window).off('scroll.jBox-' + this.id);
+ (this.options.adjustPosition || this.options.reposition) && jQuery(window).off('resize.jBox-' + this.id);
+
+ // Mousemove events
+ this.options.target == 'mouse' && jQuery('body').off('mousemove.jBox-' + this.id);
+ };
+
+
+ // Show overlay
+
+ this._showOverlay = function ()
+ {
+ // Create the overlay if wasn't created already
+ if (!this.overlay) {
+
+ // Create element and append to the element where jBox is appended to
+ this.overlay = jQuery('
').addClass('jBox-overlay' + (this.type ? ' jBox-overlay-' + this.type : '')).css({
+ display: 'none',
+ opacity: 0,
+ zIndex: this.options.zIndex - 1
+ }).appendTo(this.options.appendTo);
+
+ // Add a class name to the overlay
+ this.options.overlayClass && this.overlay.addClass(this.options.overlayClass);
+
+ // Add close button to overlay
+ (this.options.closeButton == 'overlay' || this.options.closeButton === true) && this.overlay.append(this.closeButton);
+
+ // Add closeOnClick: 'overlay' events
+ this.options.closeOnClick == 'overlay' && this.overlay.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
+
+ // Adjust option adjustDistance if there is a close button in the overlay
+ jQuery('#' + this.id + '-overlay .jBox-closeButton').length && (this.options.adjustDistance.top = Math.max(jQuery('#' + this.id + '-overlay .jBox-closeButton').outerHeight(), this.options.adjustDistance.top));
+ }
+
+ // Adjust zIndex
+ if (this.adjustZIndexOnOpen === true) {
+ this.overlay.css('zIndex', parseInt(this.wrapper.css('zIndex'), 10) - 1);
+ }
+
+ // Abort if overlay is already visible
+ if (this.overlay.css('display') == 'block') return;
+
+ // Show overlay
+ this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 1}, {
+ queue: false,
+ duration: this.options.fade,
+ start: function () { this.overlay.css({display: 'block'}); }.bind(this)
+ })) : this.overlay.css({display: 'block', opacity: 1});
+ };
+
+
+ // Hide overlay
+
+ this._hideOverlay = function ()
+ {
+ // Abort if the overlay wasn't created yet
+ if (!this.overlay) return;
+
+ // Hide overlay if no other jBox needs it
+ this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 0}, {
+ queue: false,
+ duration: this.options.fade,
+ complete: function () { this.overlay.css({display: 'none'}); }.bind(this)
+ })) : this.overlay.css({display: 'none', opacity: 0});
+ };
+
+
+ // Get the correct jBox dimensions by moving jBox out of viewport
+
+ this._exposeDimensions = function ()
+ {
+ // Move wrapper out of viewport
+ this.wrapper.css({
+ top: -10000,
+ left: -10000,
+ right: 'auto',
+ bottom: 'auto'
+ });
+
+ // Get jBox dimensions
+ var jBoxDimensions = {
+ x: this.wrapper.outerWidth(),
+ y: this.wrapper.outerHeight()
+ };
+
+ // Reset position to viewport
+ this.wrapper.css({
+ top: 'auto',
+ left: 'auto'
+ });
+
+ return jBoxDimensions;
+ };
+
+
+ // Generate CSS for animations and append to header
+
+ this._generateAnimationCSS = function ()
+ {
+ // Get open and close animations if none provided
+ (jQuery.type(this.options.animation) != 'object') && (this.options.animation = {
+ pulse: {open: 'pulse', close: 'zoomOut'},
+ zoomIn: {open: 'zoomIn', close: 'zoomIn'},
+ zoomOut: {open: 'zoomOut', close: 'zoomOut'},
+ move: {open: 'move', close: 'move'},
+ slide: {open: 'slide', close: 'slide'},
+ flip: {open: 'flip', close: 'flip'},
+ tada: {open: 'tada', close: 'zoomOut'}
+ }[this.options.animation]);
+
+ // Abort if animation not found
+ if (!this.options.animation) return null;
+
+ // Get direction var
+ this.options.animation.open && (this.options.animation.open = this.options.animation.open.split(':'));
+ this.options.animation.close && (this.options.animation.close = this.options.animation.close.split(':'));
+ this.options.animation.openDirection = this.options.animation.open[1] ? this.options.animation.open[1] : null;
+ this.options.animation.closeDirection = this.options.animation.close[1] ? this.options.animation.close[1] : null;
+ this.options.animation.open && (this.options.animation.open = this.options.animation.open[0]);
+ this.options.animation.close && (this.options.animation.close = this.options.animation.close[0]);
+
+ // Add 'Open' and 'Close' to animation names
+ this.options.animation.open && (this.options.animation.open += 'Open');
+ this.options.animation.close && (this.options.animation.close += 'Close');
+
+ // All animations
+ var animations = {
+ pulse: {
+ duration: 350,
+ css: [['0%', 'scale(1)'], ['50%', 'scale(1.1)'], ['100%', 'scale(1)']]
+ },
+ zoomInOpen: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(0.9)'], ['100%', 'scale(1)']]
+ },
+ zoomInClose: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1)'], ['100%', 'scale(0.9)']]
+ },
+ zoomOutOpen: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1.1)'], ['100%', 'scale(1)']]
+ },
+ zoomOutClose: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1)'], ['100%', 'scale(1.1)']]
+ },
+ moveOpen: {
+ duration: (this.options.fade || 180),
+ positions: {top: {'0%': -12}, right: {'0%': 12}, bottom: {'0%': 12}, left: {'0%': -12}},
+ css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
+ },
+ moveClose: {
+ duration: (this.options.fade || 180),
+ timing: 'ease-in',
+ positions: {top: {'100%': -12}, right: {'100%': 12}, bottom: {'100%': 12}, left: {'100%': -12}},
+ css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
+ },
+ slideOpen: {
+ duration: 400,
+ positions: {top: {'0%': -400}, right: {'0%': 400}, bottom: {'0%': 400}, left: {'0%': -400}},
+ css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
+ },
+ slideClose: {
+ duration: 400,
+ timing: 'ease-in',
+ positions: {top: {'100%': -400}, right: {'100%': 400}, bottom: {'100%': 400}, left: {'100%': -400}},
+ css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
+ },
+ flipOpen: {
+ duration: 600,
+ css: [['0%', 'perspective(400px) rotateX(90deg)'], ['40%', 'perspective(400px) rotateX(-15deg)'], ['70%', 'perspective(400px) rotateX(15deg)'], ['100%', 'perspective(400px) rotateX(0deg)']]
+ },
+ flipClose: {
+ duration: (this.options.fade || 300),
+ css: [['0%', 'perspective(400px) rotateX(0deg)'], ['100%', 'perspective(400px) rotateX(90deg)']]
+ },
+ tada: {
+ duration: 800,
+ css: [['0%', 'scale(1)'], ['10%, 20%', 'scale(0.9) rotate(-3deg)'], ['30%, 50%, 70%, 90%', 'scale(1.1) rotate(3deg)'], ['40%, 60%, 80%', 'scale(1.1) rotate(-3deg)'], ['100%', 'scale(1) rotate(0)']]
+ }
+ };
+
+ // Set Open and Close names for standalone animations
+ jQuery.each(['pulse', 'tada'], function (index, item) { animations[item + 'Open'] = animations[item + 'Close'] = animations[item]; });
+
+ // Function to generate the CSS for the keyframes
+ var generateKeyframeCSS = function (ev, position)
+ {
+ // Generate keyframes CSS
+ var keyframe_css = '@keyframes jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
+ jQuery.each(animations[this.options.animation[ev]].css, function (index, item) {
+ var translate = position ? item[1].replace('%XY', this._getXY(position).toUpperCase()) : item[1];
+ animations[this.options.animation[ev]].positions && (translate = translate.replace('%V', animations[this.options.animation[ev]].positions[position][item[0]]));
+ keyframe_css += item[0] + ' {transform:' + translate + ';}';
+
+ }.bind(this));
+ keyframe_css += '}';
+
+ // Generate class CSS
+ keyframe_css += '.jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
+ keyframe_css += 'animation-duration: ' + animations[this.options.animation[ev]].duration + 'ms;';
+ keyframe_css += 'animation-name: jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ';';
+ keyframe_css += animations[this.options.animation[ev]].timing ? ('animation-timing-function: ' + animations[this.options.animation[ev]].timing + ';') : '';
+ keyframe_css += '}';
+
+ return keyframe_css;
+ }.bind(this);
+
+ // Generate css for each event and positions
+ this._animationCSS = '';
+ jQuery.each(['open', 'close'], function (index, ev)
+ {
+ // No CSS needed for closing with no fade
+ if (!this.options.animation[ev] || !animations[this.options.animation[ev]] || (ev == 'close' && !this.options.fade)) return '';
+
+ // Generate CSS
+ animations[this.options.animation[ev]].positions ?
+ jQuery.each(['top', 'right', 'bottom', 'left'], function (index2, position) { this._animationCSS += generateKeyframeCSS(ev, position); }.bind(this)) :
+ this._animationCSS += generateKeyframeCSS(ev);
+ }.bind(this));
+
+ };
+
+
+ // Add css for animations
+
+ this.options.animation && this._generateAnimationCSS();
+
+
+ // Block body clicks for 10ms to prevent extra event triggering
+
+ this._blockBodyClick = function ()
+ {
+ this.blockBodyClick = true;
+ setTimeout(function () { this.blockBodyClick = false; }.bind(this), 10);
+ };
+
+
+ // Animations
+
+ this._animate = function (ev)
+ {
+ // The event which triggers the animation
+ !ev && (ev = this.isOpen ? 'open' : 'close');
+
+ // Don't animate when closing with no fade duration
+ if (!this.options.fade && ev == 'close') return null;
+
+ // Get the current position, use opposite if jBox is flipped
+ var animationDirection = (this.options.animation[ev + 'Direction'] || ((this.align != 'center') ? this.align : this.options.attributes.x));
+ this.flipped && this._getXY(animationDirection) == (this._getXY(this.align)) && (animationDirection = this._getOpp(animationDirection));
+
+ // Add event and position classes
+ var classnames = 'jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + ' jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + '-' + animationDirection;
+ this.wrapper.addClass(classnames);
+
+ // Get duration of animation
+ var animationDuration = parseFloat(this.wrapper.css('animation-duration')) * 1000;
+ ev == 'close' && (animationDuration = Math.min(animationDuration, this.options.fade));
+
+ // Remove animation classes when animation is finished
+ setTimeout(function () {
+ this.wrapper && this.wrapper.removeClass(classnames);
+ }.bind(this), animationDuration);
+ };
+
+
+ // Abort an animation
+
+ this._abortAnimation = function ()
+ {
+ // Remove all animation classes
+ var classes = this.wrapper.attr('class').split(' ').filter(function (c) {
+ return c.lastIndexOf('jBox-' + this.id + '-animation', 0) !== 0;
+ }.bind(this));
+ this.wrapper.attr('class', classes.join(' '));
+ };
+
+
+ // Adjust dimensions when browser is resized
+
+ if (this.options.responsiveWidth || this.options.responsiveHeight)
+ {
+ // Responsive positioning overrides options adjustPosition and reposition
+ // TODO: Only add this resize event when the other one from adjustPosition and reposition was not set
+ jQuery(window).on('resize.responsivejBox-' + this.id, function (ev) { if (this.isOpen) { this.position(); } }.bind(this));
+ }
+
+
+ // Fix audio options
+
+ jQuery.type(this.options.preloadAudio) === 'string' && (this.options.preloadAudio = [this.options.preloadAudio]);
+ jQuery.type(this.options.audio) === 'string' && (this.options.audio = {open: this.options.audio});
+ jQuery.type(this.options.volume) === 'number' && (this.options.volume = {open: this.options.volume, close: this.options.volume});
+
+ if (this.options.preloadAudio === true && this.options.audio) {
+ this.options.preloadAudio = [];
+ jQuery.each(this.options.audio, function (index, url) {
+ this.options.preloadAudio.push(url + '.mp3');
+ this.options.preloadAudio.push(url + '.ogg');
+ }.bind(this));
+ }
+
+
+ // Preload audio files
+
+ this.options.preloadAudio.length && jQuery.each(this.options.preloadAudio, function (index, url) {
+ var audio = new Audio();
+ audio.src = url;
+ audio.preload = 'auto';
+ });
+
+
+ // Fire onInit event
+
+ this._fireEvent('onInit');
+
+
+ return this;
+ };
+
+
+ // Attach jBox to elements
+
+ jBox.prototype.attach = function (elements, trigger)
+ {
+ // Get elements from options if none passed
+ !elements && (elements = this.options.attach);
+
+ // Convert selectors to jQuery objects
+ jQuery.type(elements) == 'string' && (elements = jQuery(elements));
+
+ // Get trigger event from options if not passed
+ !trigger && (trigger = this.options.trigger);
+
+ // Loop through elements and attach jBox
+ elements && elements.length && jQuery.each(elements, function (index, el) {
+ el = jQuery(el);
+
+ // Only attach if the element wasn't attached to this jBox already
+ if (!el.data('jBox-attached-' + this.id)) {
+
+ // Remove title attribute and store content on element
+ (this.options.getContent == 'title' && el.attr('title') != undefined) && el.data('jBox-getContent', el.attr('title')).removeAttr('title');
+
+ // Add Element to collection
+ this.attachedElements || (this.attachedElements = []);
+ this.attachedElements.push(el[0]);
+
+ // Add click or mouseenter event, click events can prevent default as well
+ el.on(trigger + '.jBox-attach-' + this.id, function (ev)
+ {
+ // Clear timer
+ this.timer && clearTimeout(this.timer);
+
+ // Block opening when jbox is open and the source element is triggering
+ if (trigger == 'mouseenter' && this.isOpen && this.source[0] == el[0]) return;
+
+ // Only close jBox if you click the current target element, otherwise open at new target
+ if (this.isOpen && this.source && this.source[0] != el[0]) var forceOpen = true;
+
+ // Set new source element
+ this.source = el;
+
+ // Set new target
+ !this.options.target && (this.target = el);
+
+ // Prevent default action on click
+ trigger == 'click' && this.options.preventDefault && ev.preventDefault();
+
+ // Toggle or open jBox
+ this[trigger == 'click' && !forceOpen ? 'toggle' : 'open']();
+
+ }.bind(this));
+
+ // Add close event for trigger event mouseenter
+ (this.options.trigger == 'mouseenter') && el.on('mouseleave', function (ev)
+ {
+ // Abort if jBox wasn't created yet
+ if (!this.wrapper) return null;
+
+ // If we have set closeOnMouseleave, do not close jBox when leaving attached element and mouse is over jBox
+ if (!this.options.closeOnMouseleave || !(ev.relatedTarget == this.wrapper[0] || jQuery(ev.relatedTarget).parents('#' + this.id).length)) this.close();
+ }.bind(this));
+
+ // Store
+ el.data('jBox-attached-' + this.id, trigger);
+
+ // Fire onAttach event
+ this._fireEvent('onAttach', el);
+ }
+
+ }.bind(this));
+
+ return this;
+ };
+
+
+ // Detach jBox from elements
+
+ jBox.prototype.detach = function (elements)
+ {
+ // Get elements from stores elements if none passed
+ !elements && (elements = this.attachedElements || []);
+
+ elements && elements.length && jQuery.each(elements, function (index, el) {
+ el = jQuery(el);
+
+ // Remove events
+ if (el.data('jBox-attached-' + this.id)) {
+ el.off(el.data('jBox-attached-' + this.id) + '.jBox-attach-' + this.id);
+ el.data('jBox-attached-' + this.id, null);
+ }
+ // Remove element from collection
+ this.attachedElements = jQuery.grep(this.attachedElements, function (value) {
+ return value != el[0];
+ });
+ }.bind(this));
+
+ return this;
+ };
+
+
+ // Set title
+
+ jBox.prototype.setTitle = function (title, ignore_positioning)
+ {
+ // Abort if title to set
+ if (title == null || title == undefined) return this;
+
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Get the width and height of wrapper, only if they change we need to reposition
+ var wrapperHeight = this.wrapper.outerHeight();
+ var wrapperWidth = this.wrapper.outerWidth();
+
+ // Create title elements if they weren't created already
+ if (!this.title) {
+ this.titleContainer = jQuery('
');
+ this.title = jQuery('
').appendTo(this.titleContainer);
+ if (this.options.closeButton == 'title' || (this.options.closeButton === true && !this.options.overlay)) {
+ this.wrapper.addClass('jBox-closeButton-title');
+ this.closeButton.appendTo(this.titleContainer);
+ }
+ this.titleContainer.insertBefore(this.content);
+ this._setTitleWidth();
+ }
+
+ // Add or remove wrapper class
+ this.wrapper[title ? 'addClass' : 'removeClass']('jBox-hasTitle');
+
+ // Set title html
+ this.title.html(title);
+
+ // Adjust width of title
+ wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
+
+ // Make jBox draggable
+ this.options.draggable && this._draggable();
+
+ // Reposition if dimensions changed
+ !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
+
+ return this;
+ };
+
+
+ // Set content
+
+ jBox.prototype.setContent = function (content, ignore_positioning)
+ {
+ // Abort if no content to set
+ if (content == null || content == undefined) return this;
+
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Get the width and height of wrapper, only if they change we need to reposition
+ var wrapperHeight = this.wrapper.outerHeight();
+ var wrapperWidth = this.wrapper.outerWidth();
+
+ // Move all appended containers to body
+ this.content.children('[data-jbox-content-appended]').appendTo('body').css({display: 'none'});
+
+ // Set the new content
+ switch (jQuery.type(content)) {
+ case 'string':
+ this.content.html(content);
+ break;
+ case 'object':
+ if (content && (content instanceof jQuery || content.constructor.prototype.jquery)) {
+ this.content.html('');
+ content.attr('data-jbox-content-appended', 1).appendTo(this.content).css({display: 'block'});
+ } else {
+ this.content.html(JSON.stringify(content));
+ }
+ break;
+ }
+
+ // Adjust title width
+ wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
+
+ // Make jBox draggable
+ this.options.draggable && this._draggable();
+
+ // Reposition if dimensions changed
+ !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
+
+ return this;
+ };
+
+
+ // Set jBox dimensions
+
+ jBox.prototype.setDimensions = function (type, value, pos)
+ {
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Default value is 'auto'
+ value == undefined && (value = 'auto');
+
+ // Set CSS of content and title
+ this.content.css(type, this._getInt(value));
+
+ // Adjust title width
+ type == 'width' && this._setTitleWidth();
+
+ // Update options
+ this.options[type] = value;
+
+ // Reposition by default
+ (pos == undefined || pos) && this.position();
+ };
+
+
+ // Set jBox width or height
+
+ jBox.prototype.setWidth = function (value, pos) { this.setDimensions('width', value, pos); };
+ jBox.prototype.setHeight = function (value, pos) { this.setDimensions('height', value, pos); };
+
+
+ // Position jBox
+
+ jBox.prototype.position = function (options)
+ {
+ // Options are required
+ !options && (options = {});
+
+ // Combine passed options with jBox options
+ options = jQuery.extend(true, this.options, options);
+
+ // Get the target
+ this.target = options.target || this.target || jQuery(window);
+
+ // Make sure target is a jQuery element
+ !(this.target instanceof jQuery || this.target == 'mouse') && (this.target = jQuery(this.target));
+
+ // Abort if target is missing
+ if (!this.target.length) return this;
+
+ // Reset content css to get original dimensions
+ this.content.css({
+ width: this._getInt(options.width, 'width'),
+ height: this._getInt(options.height, 'height'),
+ minWidth: this._getInt(options.minWidth, 'width'),
+ minHeight: this._getInt(options.minHeight, 'height'),
+ maxWidth: this._getInt(options.maxWidth, 'width'),
+ maxHeight: this._getInt(options.maxHeight, 'height'),
+ });
+
+ // Reset width of title
+ this._setTitleWidth();
+
+ // Get jBox dimensions
+ var jBoxDimensions = this._exposeDimensions();
+
+ // Check if target has fixed position, store in elements data
+ this.target != 'mouse' && !this.target.data('jBox-' + this.id + '-fixed') && this.target.data('jBox-' + this.id + '-fixed', (this.target[0] != jQuery(window)[0] && (this.target.css('position') == 'fixed' || this.target.parents().filter(function () { return jQuery(this).css('position') == 'fixed'; }).length > 0)) ? 'fixed' : 'static');
+
+ // Get the window dimensions
+ var windowDimensions = {
+ x: jQuery(window).outerWidth(),
+ y: jQuery(window).outerHeight(),
+ top: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollTop()),
+ left: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollLeft())
+ };
+ windowDimensions.bottom = windowDimensions.top + windowDimensions.y;
+ windowDimensions.right = windowDimensions.left + windowDimensions.x;
+
+ // Get target offset
+ try { var targetOffset = this.target.offset(); } catch (e) { var targetOffset = {top: 0, left: 0}; };
+
+ // When the target is fixed and jBox is fixed, remove scroll offset
+ if (this.target != 'mouse' && this.target.data('jBox-' + this.id + '-fixed') == 'fixed' && options.fixed) {
+ targetOffset.top = targetOffset.top - jQuery(window).scrollTop();
+ targetOffset.left = targetOffset.left - jQuery(window).scrollLeft();
+ }
+
+ // Get target dimensions
+ var targetDimensions = {
+ x: this.target == 'mouse' ? 12 : this.target.outerWidth(),
+ y: this.target == 'mouse' ? 20 : this.target.outerHeight(),
+ top: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.top : (targetOffset ? targetOffset.top : 0),
+ left: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.left : (targetOffset ? targetOffset.left : 0)
+ };
+
+ // Check if jBox is outside
+ var outside = options.outside && !(options.position.x == 'center' && options.position.y == 'center');
+
+ // Get the available space on all sides
+ var availableSpace = {
+ x: windowDimensions.x - options.adjustDistance.left - options.adjustDistance.right, // TODO: substract position.x when they are numbers
+ y: windowDimensions.y - options.adjustDistance.top - options.adjustDistance.bottom, // TODO: substract position.x when they are numbers
+ left: !outside ? 0 : (targetDimensions.left - jQuery(window).scrollLeft() - options.adjustDistance.left),
+ right: !outside ? 0 : (windowDimensions.x - targetDimensions.left + jQuery(window).scrollLeft() - targetDimensions.x - options.adjustDistance.right),
+ top: !outside ? 0 : (targetDimensions.top - jQuery(window).scrollTop() - this.options.adjustDistance.top),
+ bottom: !outside ? 0 : (windowDimensions.y - targetDimensions.top + jQuery(window).scrollTop() - targetDimensions.y - options.adjustDistance.bottom),
+ };
+
+ // Get the default outside position, check if box will be flipped
+ var jBoxOutsidePosition = {
+ x: (options.outside == 'x' || options.outside == 'xy') && jQuery.type(options.position.x) != 'number' ? options.position.x : null,
+ y: (options.outside == 'y' || options.outside == 'xy') && jQuery.type(options.position.y) != 'number' ? options.position.y : null
+ };
+ var flip = {x: false, y: false};
+ (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
+ (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
+
+ // Adjust responsive dimensions
+ if (options.responsiveWidth || options.responsiveHeight) {
+
+ // Adjust width and height according to default outside position
+ var adjustResponsiveWidth = function ()
+ {
+ if (options.responsiveWidth && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x || 'x']) {
+ var contentWidth = availableSpace[jBoxOutsidePosition.x || 'x'] - (this.pointer && outside && options.outside == 'x' ? this.pointer.dimensions.x : 0) - parseInt(this.container.css('border-left-width')) - parseInt(this.container.css('border-right-width'));
+ this.content.css({
+ width: contentWidth > this.options.responsiveMinWidth ? contentWidth : null,
+ minWidth: contentWidth < parseInt(this.content.css('minWidth')) ? 0 : null
+ });
+ this._setTitleWidth();
+ }
+ jBoxDimensions = this._exposeDimensions();
+
+ }.bind(this);
+ options.responsiveWidth && adjustResponsiveWidth();
+
+ // After adjusting width, check if jBox will be flipped for y
+ options.responsiveWidth && !flip.y && (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
+
+ // Adjust width and height according to default outside position
+ var adjustResponsiveHeight = function ()
+ {
+ if (options.responsiveHeight && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y || 'y']) {
+
+ // Expose wrapper to get correct title height
+ var exposeTitleFooterHeight = function () {
+ if (!this.titleContainer && !this.footer) return 0;
+ if (this.wrapper.css('display') == 'none') {
+ this.wrapper.css('display', 'block');
+ var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
+ this.wrapper.css('display', 'none');
+ } else {
+ var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
+ }
+ return height || 0;
+ }.bind(this);
+
+ var contentHeight = availableSpace[jBoxOutsidePosition.y || 'y'] - (this.pointer && outside && options.outside == 'y' ? this.pointer.dimensions.y : 0) - exposeTitleFooterHeight() - parseInt(this.container.css('border-top-width')) - parseInt(this.container.css('border-bottom-width'));
+ this.content.css({height: contentHeight > this.options.responsiveMinHeight ? contentHeight : null});
+ this._setTitleWidth();
+ }
+ jBoxDimensions = this._exposeDimensions();
+
+ }.bind(this);
+ options.responsiveHeight && adjustResponsiveHeight();
+
+ // After adjusting height, check if jBox will be flipped for x
+ options.responsiveHeight && !flip.x && (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
+
+ // Adjust width and height if jBox will be flipped
+ if (options.adjustPosition && options.adjustPosition != 'move') {
+ flip.x && adjustResponsiveWidth();
+ flip.y && adjustResponsiveHeight();
+ }
+ }
+
+ // Store new positioning vars in local var
+ var pos = {};
+
+ // Calculate positions
+ var setPosition = function (p)
+ {
+ // Set number positions
+ if (jQuery.type(options.position[p]) == 'number') {
+ pos[options.attributes[p]] = options.position[p];
+ return;
+ }
+
+ // We have a target, so use 'left' or 'top' as attributes
+ var a = options.attributes[p] = (p == 'x' ? 'left' : 'top');
+
+ // Start at target position
+ pos[a] = targetDimensions[a];
+
+ // Set centered position
+ if (options.position[p] == 'center') {
+ pos[a] += Math.ceil((targetDimensions[p] - jBoxDimensions[p]) / 2);
+
+ // If the target is the window, adjust centered position depending on adjustDistance
+ (this.target != 'mouse' && this.target[0] && this.target[0] == jQuery(window)[0]) && (pos[a] += (options.adjustDistance[a] - options.adjustDistance[this._getOpp(a)]) * 0.5);
+ return;
+ }
+
+ // Move inside
+ (a != options.position[p]) && (pos[a] += targetDimensions[p] - jBoxDimensions[p]);
+
+ // Move outside
+ (options.outside == p || options.outside == 'xy') && (pos[a] += jBoxDimensions[p] * (a != options.position[p] ? 1 : -1));
+
+ }.bind(this);
+
+ // Set position including offset
+ setPosition('x');
+ setPosition('y');
+
+ // Adjust position depending on pointer align
+ if (this.pointer && options.pointTo == 'target' && jQuery.type(options.position.x) != 'number' && jQuery.type(options.position.y) != 'number') {
+
+ var adjustWrapper = 0;
+
+ // Where is the pointer aligned? Add or substract accordingly
+ switch (this.pointer.align) {
+ case 'center':
+ if (options.position[this._getOpp(options.outside)] != 'center') {
+ adjustWrapper += (jBoxDimensions[this._getOpp(options.outside)] / 2);
+ }
+ break;
+ default:
+ switch (options.position[this._getOpp(options.outside)]) {
+ case 'center':
+ adjustWrapper += ((jBoxDimensions[this._getOpp(options.outside)] / 2) - (this.pointer.dimensions[this._getOpp(options.outside)] / 2)) * (this.pointer.align == this._getTL(this.pointer.align) ? 1 : -1);
+ break;
+ default:
+ adjustWrapper += (this.pointer.align != options.position[this._getOpp(options.outside)]) ?
+
+ // If pointer align is different to position align
+ (jBoxDimensions[this._getOpp(options.outside)] * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1)) + ((this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? -1 : 1)) :
+
+ // If pointer align is same as position align
+ (this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1);
+ break;
+ }
+ break;
+ }
+
+ adjustWrapper *= (options.position[this._getOpp(options.outside)] == this.pointer.alignAttribute ? -1 : 1);
+ adjustWrapper += this.pointer.offset * (this.pointer.align == this._getOpp(this._getTL(this.pointer.align)) ? 1 : -1);
+
+ pos[this._getTL(this._getOpp(this.pointer.xy))] += adjustWrapper;
+ }
+
+ // Add final offset
+ pos[options.attributes.x] += options.offset.x;
+ pos[options.attributes.y] += options.offset.y;
+
+ // Set CSS
+ this.wrapper.css(pos);
+
+ // Adjust position
+ if (options.adjustPosition) {
+
+ // Reset cached pointer position
+ if (this.positionAdjusted) {
+ this.pointer && this.wrapper.css('padding', 0).css('padding-' + this._getOpp(this.outside), this.pointer.dimensions[this._getXY(this.outside)]).removeClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).addClass('jBox-pointerPosition-' + this.pointer.position);
+ this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + this._getOpp(this.outside)).css(this.pointer.margin);
+ this.positionAdjusted = false;
+ this.flipped = false;
+ }
+
+ // Find out where the jBox is out of view area
+ var outYT = (windowDimensions.top > pos.top - (options.adjustDistance.top || 0)),
+ outXR = (windowDimensions.right < pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0)),
+ outYB = (windowDimensions.bottom < pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0)),
+ outXL = (windowDimensions.left > pos.left - (options.adjustDistance.left || 0)),
+ outX = outXL ? 'left' : (outXR ? 'right' : null),
+ outY = outYT ? 'top' : (outYB ? 'bottom' : null),
+ out = outX || outY;
+
+ // Only continue if jBox is out of view area
+ if (out) {
+
+ if ((this.type == 'Modal' || this.type == 'Confirm')
+ && jQuery.type(this.options.position.x) == 'number'
+ && jQuery.type(this.options.position.y) == 'number'
+ ) {
+ var diffX = 0, diffY = 0;
+ if (this.options.holdPosition) {
+
+ // Adjust left or right
+ if (outXL) {
+ diffX = windowDimensions.left - (pos.left - (options.adjustDistance.left || 0));
+ } else if (outXR) {
+ diffX = windowDimensions.right - (pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0));
+ }
+
+ // Adjust top or bottom
+ if (outYT) {
+ diffY = windowDimensions.top - (pos.top - (options.adjustDistance.top || 0));
+ } else if (outYB) {
+ diffY = windowDimensions.bottom - (pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0));
+ }
+
+ this.options.position.x = Math.max(windowDimensions.top, this.options.position.x + diffX);
+ this.options.position.y = Math.max(windowDimensions.left, this.options.position.y + diffY);
+
+ setPosition('x');
+ setPosition('y');
+ this.wrapper.css(pos);
+ }
+ // Fire onPosition event
+ this._fireEvent('onPosition');
+
+ return this;
+ }
+
+ // Function to flip position
+ if (options.adjustPosition === true || options.adjustPosition === 'flip') {
+ var flipJBox = function (xy) {
+ this.wrapper.css(this._getTL(xy), pos[this._getTL(xy)] + ((jBoxDimensions[this._getXY(xy)] + (options.offset[this._getXY(xy)] * (xy == 'top' || xy == 'left' ? -2 : 2)) + targetDimensions[this._getXY(xy)]) * (xy == 'top' || xy == 'left' ? 1 : -1)));
+ this.pointer && this.wrapper.removeClass('jBox-pointerPosition-' + this.pointer.position).addClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).css('padding', 0).css('padding-' + xy, this.pointer.dimensions[this._getXY(xy)]);
+ this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + xy);
+ this.positionAdjusted = true;
+ this.flipped = true;
+ }.bind(this);
+
+ // Flip jBox
+ flip.x && flipJBox(this.options.position.x);
+ flip.y && flipJBox(this.options.position.y);
+ }
+
+ // Move jBox (only possible with pointer)
+ var outMove = (this._getXY(this.outside) == 'x') ? outY : outX;
+
+ if (this.pointer && options.pointTo == 'target' && options.adjustPosition != 'flip' && this._getXY(outMove) == this._getOpp(this._getXY(this.outside))) {
+
+ // Get the maximum space we have availible to adjust
+ if (this.pointer.align == 'center') {
+ var spaceAvail = (jBoxDimensions[this._getXY(outMove)] / 2) - (this.pointer.dimensions[this._getOpp(this.pointer.xy)] / 2) - (parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) * (outMove != this._getTL(outMove) ? -1 : 1));
+ } else {
+ var spaceAvail = (outMove == this.pointer.alignAttribute) ?
+ parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) :
+ jBoxDimensions[this._getXY(outMove)] - parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - this.pointer.dimensions[this._getXY(outMove)];
+ }
+
+ // Get the overlapping space
+ var spaceDiff = (outMove == this._getTL(outMove)) ?
+ windowDimensions[this._getTL(outMove)] - pos[this._getTL(outMove)] + options.adjustDistance[outMove] :
+ (windowDimensions[this._getOpp(this._getTL(outMove))] - pos[this._getTL(outMove)] - options.adjustDistance[outMove] - jBoxDimensions[this._getXY(outMove)]) * -1;
+
+ // Add overlapping space on left or top window edge
+ if (outMove == this._getOpp(this._getTL(outMove)) && pos[this._getTL(outMove)] - spaceDiff < windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)]) {
+ spaceDiff -= windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)] - (pos[this._getTL(outMove)] - spaceDiff);
+ }
+
+ // Only adjust the maximum availible
+ spaceDiff = Math.min(spaceDiff, spaceAvail);
+
+ // Move jBox
+ if (spaceDiff <= spaceAvail && spaceDiff > 0) {
+ this.pointer.element.css('margin-' + this.pointer.alignAttribute, parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - (spaceDiff * (outMove != this.pointer.alignAttribute ? -1 : 1)));
+ this.wrapper.css(this._getTL(outMove), pos[this._getTL(outMove)] + (spaceDiff * (outMove != this._getTL(outMove) ? -1 : 1)));
+ this.positionAdjusted = true;
+ }
+ }
+ }
+ }
+
+ // Fire onPosition event
+ this._fireEvent('onPosition');
+
+ return this;
+ };
+
+
+ // Block scrolling
+ // Borrowed from https://github.com/StephanWagner/unscroll
+
+ jBox.prototype.unscroll = function (elements) {
+
+ // Store reusable vars
+ this.set = function (id, value) {
+ if (!window.unscrollStore) {
+ window.unscrollStore = {};
+ }
+ window.unscrollStore[id] = value;
+ };
+
+ // Get reusable vars
+ this.get = function (id) {
+ return window.unscrollStore ? window.unscrollStore[id] : null;
+ };
+
+ // Get the width of the scroll bar in pixel
+ this.getScrollbarWidth = function () {
+ if (this.get('scrollbarWidth')) {
+ return this.get('scrollbarWidth') + 'px';
+ }
+ var scrollElement = document.createElement('div');
+ scrollElement.style.width = '100px';
+ scrollElement.style.height = '100px';
+ scrollElement.style.overflow = 'scroll';
+ scrollElement.style.position = 'absolute';
+ scrollElement.style.top = '-10000';
+
+ document.body.appendChild(scrollElement);
+ var scrollbarWidth = scrollElement.offsetWidth - scrollElement.clientWidth;
+ document.body.removeChild(scrollElement);
+
+ this.set('scrollbarWidth', scrollbarWidth);
+ return scrollbarWidth + 'px';
+ }
+
+ // Add unscroll class to head
+ function addUnscrollClassName() {
+ if (document.getElementById('unscroll-class-name')) {
+ return;
+ }
+ var css = '.unscrollable { overflow: hidden !important; }',
+ head = document.head || document.getElementsByTagName('head')[0],
+ style = document.createElement('style');
+ style.type = 'text/css';
+ style.setAttribute('id', 'unscroll-class-name');
+ style.appendChild(document.createTextNode(css));
+ head.appendChild(style);
+ }
+
+ // Get the elements to adjust, force body element
+ this.getElementsToAdjust = function (elements) {
+ !elements && (elements = []);
+
+ if (typeof elements === 'string') {
+ elements = [
+ [elements, 'padding-right']
+ ];
+ }
+
+ elements.forEach(function (element, index) {
+ if (typeof element === 'string') {
+ elements[index] = [element, 'padding-right'];
+ }
+ });
+
+ var bodyFound = false;
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i][0].indexOf('body') !== -1) {
+ bodyFound = true;
+ }
+ };
+
+ if (bodyFound === false) {
+ elements.push(['body', 'padding-right']);
+ }
+
+ return elements;
+ }
+
+ this.pageHasScrollbar = function () {
+ return this.getScrollbarWidth() && document.body.offsetHeight > window.innerHeight;
+ }
+
+ // Clean up elements
+ if (this.pageHasScrollbar()) {
+ elements = this.getElementsToAdjust(elements);
+
+ // Loop through elements and adjust accordingly
+ for (var i = 0; i < elements.length; i++) {
+ var elementsDOM = document.querySelectorAll(elements[i][0]);
+ for (var j = 0; j < elementsDOM.length; j++) {
+ if (elementsDOM[j].getAttribute('data-unscroll')) {
+ return;
+ }
+ var attribute = elements[i][1];
+ var computedStyles = window.getComputedStyle(elementsDOM[j]);
+ var computedStyle = computedStyles.getPropertyValue(attribute);
+ elementsDOM[j].setAttribute('data-unscroll', attribute);
+ if (!computedStyle) {
+ computedStyle = '0px';
+ }
+ var operator = attribute == 'padding-right' || attribute == 'right' ? '+' : '-';
+ elementsDOM[j].style[attribute] = 'calc(' + computedStyle + ' ' + operator + ' ' + this.getScrollbarWidth() + ')';
+ }
+ }
+ }
+
+ // Make the page unscrollable
+ addUnscrollClassName();
+ document.body.classList.add('unscrollable');
+ }
+
+ jBox.prototype.unscroll.reset = function () {
+ var elements = document.querySelectorAll('[data-unscroll]');
+
+ for (var i = 0; i < elements.length; i++) {
+ var attribute = elements[i].getAttribute('data-unscroll');
+ elements[i].style[attribute] = null;
+ elements[i].removeAttribute('data-unscroll');
+ }
+ document.body.classList.remove('unscrollable');
+ }
+
+
+ // Open jBox
+
+ jBox.prototype.open = function (options)
+ {
+ // Create blank options if none passed
+ !options && (options = {});
+
+ // Abort if jBox was destroyed
+ if (this.isDestroyed) return this;
+
+ // Construct jBox if not already constructed
+ !this.wrapper && this._create();
+
+ // Add css to header if not added already
+ !this._styles && (this._styles = jQuery('
').append(this._animationCSS).appendTo(jQuery('head')));
+
+ // Abort any opening or closing timer
+ this.timer && clearTimeout(this.timer);
+
+ // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body'
+ this._blockBodyClick();
+
+ // Block opening
+ if (this.isDisabled) return this;
+
+ // Closing event: closeOnEsc
+ this.options.closeOnEsc && jQuery(document).on('keyup.jBox-' + this.id, function (ev) { if (ev.keyCode == 27) { this.close({ignoreDelay: true}); }}.bind(this));
+
+ // Closing event: closeOnClick
+ if (this.options.closeOnClick === true || this.options.closeOnClick === 'body') {
+ jQuery('body').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function (ev) {
+ if (this.blockBodyClick || (this.options.closeOnClick == 'body' && (ev.target == this.wrapper[0] || this.wrapper.has(ev.target).length))) return;
+ this.close({ignoreDelay: true});
+ }.bind(this));
+
+ // Fix for iOS event bubbling issue
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+ this.isTouchDevice && jQuery('body > *').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function () {
+ return true;
+ });
+ }
+
+ // Opening function
+ var open = function () {
+
+ // Adjust zIndex
+ if (this.adjustZIndexOnOpen === true) {
+ jBox.zIndexMax = Math.max(
+ parseInt(this.wrapper.css('zIndex'), 10),
+ this.options.zIndex,
+ jBox.zIndexMax || 0,
+ jBox.zIndexMaxDragover || 0
+ ) + 2;
+ this.wrapper.css('zIndex', jBox.zIndexMax);
+ this.options.zIndex = jBox.zIndexMax;
+ }
+
+ // Set title from source element
+ this.source && this.options.getTitle && (this.source.attr(this.options.getTitle) && this.setTitle(this.source.attr(this.options.getTitle), true));
+
+ // Set content from source element
+ this.source && this.options.getContent && (this.source.data('jBox-getContent') ? this.setContent(this.source.data('jBox-getContent'), true) : (this.source.attr(this.options.getContent) ? this.setContent(this.source.attr(this.options.getContent), true) : (this.options.getContent == 'html' ? this.setContent(this.source.html(), true) : null)));
+
+ // Fire onOpen event
+ this._fireEvent('onOpen');
+
+ // Get content from ajax
+ if ((this.options.ajax && (this.options.ajax.url || (this.source && this.source.attr(this.options.ajax.getURL))) && (!this.ajaxLoaded || this.options.ajax.reload)) || (options.ajax && (options.ajax.url || options.ajax.data))) {
+ // Send the content from stored data if there is any, otherwise load new data
+ (this.options.ajax.reload != 'strict' && this.source && this.source.data('jBox-ajax-data') && !(options.ajax && (options.ajax.url || options.ajax.data))) ? this.setContent(this.source.data('jBox-ajax-data')) : this.ajax((options.ajax || null), true);
+ }
+
+ // Set position
+ (!this.positionedOnOpen || this.options.repositionOnOpen) && this.position(options) && (this.positionedOnOpen = true);
+
+ // Abort closing
+ this.isClosing && this._abortAnimation();
+
+ // Open functions to call when jBox is closed
+ if (!this.isOpen) {
+
+ // jBox is open now
+ this.isOpen = true;
+
+ // Automatically close jBox after some time
+ this.options.autoClose && (this.options.delayClose = this.options.autoClose) && this.close();
+
+ // Attach events
+ this._attachEvents();
+
+ // Block scrolling
+ if (this.options.blockScroll) {
+ if (this.options.blockScrollAdjust) {
+ if (jBox.blockScrollScopes) {
+ jBox.blockScrollScopes++;
+ } else {
+ jBox.blockScrollScopes = 1;
+ this.unscroll(Array.isArray(this.options.blockScrollAdjust) || typeof this.options.blockScrollAdjust === 'string' ? this.options.blockScrollAdjust : null);
+ }
+ } else {
+ jQuery('body').addClass('jBox-blockScroll-' + this.id);
+ }
+ }
+
+ // Show overlay
+ if (this.options.overlay) {
+ this._showOverlay();
+
+ // TODO Optimize: We have to position here again, because if the overlay has a close button, the upper adjustDistance will be wrong
+ this.position();
+ }
+
+ // Only animate if jBox is completely closed
+ this.options.animation && !this.isClosing && this._animate('open');
+
+ // Play audio file
+ this.options.audio && this.options.audio.open && this.audio(this.options.audio.open, this.options.volume.open);
+
+ // Fading animation or show immediately
+ if (this.options.fade) {
+ this.wrapper.stop().animate({opacity: 1}, {
+ queue: false,
+ duration: this.options.fade,
+ start: function () {
+ this.isOpening = true;
+ this.wrapper.css({display: 'block'});
+ }.bind(this),
+ complete: function () {
+ this._fireEvent('onOpenComplete');
+ }.bind(this),
+ always: function () {
+ this.isOpening = false;
+
+ // Delay positioning for ajax to prevent positioning during animation
+ setTimeout(function () { this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false); }.bind(this), 10);
+ }.bind(this)
+ });
+ } else {
+ this.wrapper.css({display: 'block', opacity: 1});
+ this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false);
+ this._fireEvent('onOpenComplete');
+ }
+ }
+ }.bind(this);
+
+ // Open jBox
+ this.options.delayOpen && !this.isOpen && !this.isClosing && !options.ignoreDelay ? (this.timer = setTimeout(open, this.options.delayOpen)) : open();
+
+ return this;
+ };
+
+
+ // Close jBox
+
+ jBox.prototype.close = function (options)
+ {
+ // Create blank options if none passed
+ options || (options = {});
+
+ // Remove close events
+ jQuery('body').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+ this.isTouchDevice && jQuery('body > *').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+
+ // Abort if jBox was destroyed or is currently closing
+ if (this.isDestroyed || this.isClosing) return this;
+
+ // Abort opening
+ this.timer && clearTimeout(this.timer);
+
+ // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body' is true
+ this._blockBodyClick();
+
+ // Block closing
+ if (this.isDisabled) return this;
+
+ // Close function
+ var close = function () {
+
+ // Fire onClose event
+ this._fireEvent('onClose');
+
+ // Cancel the ajax call
+ if (this.options.cancelAjaxOnClose) {
+ this.cancelAjax();
+ }
+
+ // Only close if jBox is open
+ if (this.isOpen) {
+
+ // jBox is not open anymore
+ this.isOpen = false;
+
+ // Detach events
+ this._detachEvents();
+
+ // Unblock scrolling
+ if (this.options.blockScroll) {
+ if (this.options.blockScrollAdjust) {
+ jBox.blockScrollScopes = jBox.blockScrollScopes ? --jBox.blockScrollScopes : 0;
+ !jBox.blockScrollScopes && this.unscroll.reset();
+ } else {
+ jQuery('body').removeClass('jBox-blockScroll-' + this.id);
+ }
+ }
+
+ // Hide overlay
+ this.options.overlay && this._hideOverlay();
+
+ // Only animate if jBox is compleately closed
+ this.options.animation && !this.isOpening && this._animate('close');
+
+ // Play audio file
+ this.options.audio && this.options.audio.close && this.audio(this.options.audio.close, this.options.volume.close);
+
+ // Get fade duration
+ var fadeDuration = this.isTouchDevice && this.options.target == 'mouse' ? 0 : this.options.fade;
+
+ // Fading animation or show immediately
+ if (fadeDuration) {
+ this.wrapper.stop().animate({opacity: 0}, {
+ queue: false,
+ duration: fadeDuration,
+ start: function () {
+ this.isClosing = true;
+ }.bind(this),
+ complete: function () {
+ this.wrapper.css({display: 'none'});
+ this._fireEvent('onCloseComplete');
+ }.bind(this),
+ always: function () {
+ this.isClosing = false;
+ }.bind(this)
+ });
+ } else {
+ this.wrapper.css({display: 'none', opacity: 0});
+ this._fireEvent('onCloseComplete');
+ }
+ }
+ }.bind(this);
+
+ // Close jBox
+ if (options.ignoreDelay || (this.isTouchDevice && this.options.target == 'mouse')) {
+ close();
+ } else if ((this.options.delayOnHover || this.options.showCountdown) && this.options.delayClose > 10) {
+ var self = this;
+ var remaining = this.options.delayClose;
+ var prevFrame = Date.now();
+ if (this.options.showCountdown && !this.inner) {
+ var outer = jQuery('
');
+ this.inner = jQuery('
');
+ outer.prepend(this.inner);
+ jQuery('#' + this.id).append(outer);
+ }
+ this.countdown = function(){
+ var dateNow = Date.now();
+ if (!self.isHovered) {
+ remaining -= dateNow - prevFrame;
+ }
+ prevFrame = dateNow;
+ if (remaining > 0) {
+ if (self.options.showCountdown) {
+ self.inner.css('width', (remaining * 100 / self.options.delayClose) + '%');
+ }
+ window.requestAnimationFrame(self.countdown);
+ } else {
+ close();
+ }
+ };
+ window.requestAnimationFrame(this.countdown);
+ } else {
+ this.timer = setTimeout(close, Math.max(this.options.delayClose, 10));
+ }
+
+ return this;
+ };
+
+
+ // Open or close jBox
+
+ jBox.prototype.toggle = function (options)
+ {
+ this[this.isOpen ? 'close' : 'open'](options);
+ return this;
+ };
+
+
+ // Block opening and closing
+
+ jBox.prototype.disable = function ()
+ {
+ this.isDisabled = true;
+ return this;
+ };
+
+
+ // Unblock opening and closing
+
+ jBox.prototype.enable = function ()
+ {
+ this.isDisabled = false;
+ return this;
+ };
+
+
+ // Hide jBox
+
+ jBox.prototype.hide = function ()
+ {
+ this.disable();
+ if (this.wrapper) {
+ this.cacheWrapperDisplay = this.wrapper.css('display');
+ this.wrapper.css({display: 'none'});
+ }
+ if (this.overlay) {
+ this.cacheOverlayDisplay = this.overlay.css('display');
+ this.overlay.css({display: 'none'});
+ }
+ return this;
+ };
+
+
+ // Show jBox
+
+ jBox.prototype.show = function ()
+ {
+ this.enable();
+ if (this.wrapper && this.cacheWrapperDisplay) {
+ this.wrapper.css({display: this.cacheWrapperDisplay});
+ this.cacheWrapperDisplay = null;
+ }
+ if (this.overlay && this.cacheOverlayDisplay) {
+ this.overlay.css({display: this.cacheOverlayDisplay});
+ this.cacheOverlayDisplay = null;
+ }
+ return this;
+ };
+
+
+ // Get content from ajax
+
+ jBox.prototype.ajax = function (options, opening)
+ {
+ options || (options = {});
+
+ // Add data or url from source element if none set in options
+ jQuery.each([['getData', 'data'], ['getURL', 'url']], function (index, item) {
+ (this.options.ajax[item[0]] && !options[item[1]] && this.source && this.source.attr(this.options.ajax[item[0]]) != undefined) && (options[item[1]] = this.source.attr(this.options.ajax[item[0]]) || '');
+ }.bind(this));
+
+ // Clone the system options
+ var sysOptions = jQuery.extend(true, {}, this.options.ajax);
+
+ // Abort running ajax call
+ this.cancelAjax();
+
+ // Extract events
+ var beforeSend = options.beforeSend || sysOptions.beforeSend || function () {};
+ var complete = options.complete || sysOptions.complete || function () {};
+ var success = options.success || sysOptions.success || function () {};
+ var error = options.error || sysOptions.error || function () {};
+
+ // Merge options
+ var userOptions = jQuery.extend(true, sysOptions, options);
+
+ // Set new beforeSend event
+ userOptions.beforeSend = function (xhr)
+ {
+ // jBox is loading
+ userOptions.loadingClass && this.wrapper.addClass(userOptions.loadingClass === true ? 'jBox-loading' : userOptions.loadingClass);
+
+ // Add loading spinner
+ userOptions.spinner && (this.spinnerDelay = setTimeout(function ()
+ {
+ // Add class for loading spinner
+ this.wrapper.addClass('jBox-loading-spinner');
+
+ // Reposition jBox
+ // TODO: Only reposition if dimensions change
+ userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Add spinner to container
+ this.spinner = jQuery(userOptions.spinner !== true ? userOptions.spinner : '
').appendTo(this.container);
+
+ // Fix spinners position if there is a title
+ this.titleContainer && this.spinner.css('position') == 'absolute' && this.spinner.css({transform: 'translateY(' + (this.titleContainer.outerHeight() * 0.5) + 'px)'});
+
+ }.bind(this), (this.content.html() == '' ? 0 : (userOptions.spinnerDelay || 0))));
+
+ // Fire users beforeSend event
+ (beforeSend.bind(this))(xhr);
+
+ }.bind(this);
+
+ // Set up new complete event
+ userOptions.complete = function (response)
+ {
+ // Abort spinner timeout
+ this.spinnerDelay && clearTimeout(this.spinnerDelay);
+
+ // jBox finished loading
+ this.wrapper.removeClass('jBox-loading jBox-loading-spinner jBox-loading-spinner-delay');
+
+ // Remove spinner
+ this.spinner && this.spinner.length && this.spinner.remove() && userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Store that ajax loading finished
+ this.ajaxLoaded = true;
+
+ // Fire users complete event
+ (complete.bind(this))(response);
+
+ }.bind(this);
+
+ // Set up new success event
+ userOptions.success = function (response)
+ {
+ // Set content
+ userOptions.setContent && this.setContent(response, true) && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Store content in source element
+ userOptions.setContent && this.source && this.source.data('jBox-ajax-data', response);
+
+ // Fire users success event
+ (success.bind(this))(response);
+
+ }.bind(this);
+
+ // Add error event
+ userOptions.error = function (response) { (error.bind(this))(response); }.bind(this);
+
+ // Send new ajax request
+ this.ajaxRequest = jQuery.ajax(userOptions);
+
+ return this;
+ };
+
+
+ // Abort an ajax call
+
+ jBox.prototype.cancelAjax = function () {
+ if (this.ajaxRequest) {
+ this.ajaxRequest.abort();
+ this.ajaxLoaded = false;
+ }
+ };
+
+
+ // Play an audio file
+
+ jBox.prototype.audio = function (url, volume)
+ {
+ // URL is required
+ if (!url) return this;
+
+ // Create intern audio object if it wasn't created already
+ !jBox._audio && (jBox._audio = {});
+
+ // Create an audio element specific to this audio file if it doesn't exist already
+ if (!jBox._audio[url]) {
+ var audio = jQuery(' ');
+ jQuery(' ', {src: url + '.mp3'}).appendTo(audio);
+ jQuery(' ', {src: url + '.ogg'}).appendTo(audio);
+ jBox._audio[url] = audio[0];
+ }
+
+ // Set volume
+ jBox._audio[url].volume = Math.min(((volume != undefined ? volume : 100) / 100), 1);
+
+ // Try to pause current audio
+ try {
+ jBox._audio[url].pause();
+ jBox._audio[url].currentTime = 0;
+ } catch (e) {}
+
+ // Play audio
+ jBox._audio[url].play();
+
+ return this;
+ };
+
+ // Apply custom animations to jBox (being used in playground demos)
+
+ jBox._animationSpeeds = {
+ 'tada': 1000,
+ 'tadaSmall': 1000,
+ 'flash': 500,
+ 'shake': 400,
+ 'pulseUp': 250,
+ 'pulseDown': 250,
+ 'popIn': 250,
+ 'popOut': 250,
+ 'fadeIn': 200,
+ 'fadeOut': 200,
+ 'slideUp': 400,
+ 'slideRight': 400,
+ 'slideLeft': 400,
+ 'slideDown': 400
+ };
+
+ jBox.prototype.animate = function (animation, options)
+ {
+ // Options are required
+ !options && (options = {});
+
+ // Timout needs to be an object
+ !this.animationTimeout && (this.animationTimeout = {});
+
+ // Use jBox wrapper by default
+ !options.element && (options.element = this.wrapper);
+
+ // Give the element an unique id
+ !options.element.data('jBox-animating-id') && options.element.data('jBox-animating-id', jBox._getUniqueElementID());
+
+ // Abort if element is animating
+ if (options.element.data('jBox-animating')) {
+ options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null);
+ this.animationTimeout[options.element.data('jBox-animating-id')] && clearTimeout(this.animationTimeout[options.element.data('jBox-animating-id')]);
+ }
+
+ // Animate the element
+ options.element.addClass('jBox-animated-' + animation).data('jBox-animating', 'jBox-animated-' + animation);
+ this.animationTimeout[options.element.data('jBox-animating-id')] = setTimeout((function() { options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null); options.complete && options.complete(); }), jBox._animationSpeeds[animation]);
+ };
+
+ // https://gist.github.com/AlexEmashev/ee8302b5036b01362f63dab35948401f
+ jBox.prototype.swipeDetector = function (swipeTarget, options) {
+ // States: 0 - no swipe, 1 - swipe started, 2 - swipe released
+ var swipeState = 0;
+ // Coordinates when swipe started
+ var startX = 0;
+ var startY = 0;
+ // Distance of swipe
+ var pixelOffsetX = 0;
+ var pixelOffsetY = 0;
+
+ var defaultSettings = {
+ // Amount of pixels, when swipe don't count.
+ swipeThreshold: 70,
+ // Flag that indicates that plugin should react only on touch events.
+ // Not on mouse events too.
+ useOnlyTouch: false
+ };
+
+ // Initializer
+ (function init() {
+ options = jQuery.extend(defaultSettings, options);
+ // Support touch and mouse as well.
+ swipeTarget.on("mousedown touchstart", swipeStart);
+ jQuery("html").on("mouseup touchend", swipeEnd);
+ jQuery("html").on("mousemove touchmove", swiping);
+ })();
+
+ function swipeStart(event) {
+ if (options.useOnlyTouch && !event.originalEvent.touches) {
+ return;
+ }
+
+ if (event.originalEvent.touches) {
+ event = event.originalEvent.touches[0];
+ }
+
+ if (swipeState === 0) {
+ swipeState = 1;
+ startX = event.clientX;
+ startY = event.clientY;
+ }
+ }
+
+ function swipeEnd(event) {
+ if (swipeState === 2) {
+ swipeState = 0;
+
+ if (
+ Math.abs(pixelOffsetX) > Math.abs(pixelOffsetY) &&
+ Math.abs(pixelOffsetX) > options.swipeThreshold
+ ) {
+ // Horizontal Swipe
+ if (pixelOffsetX < 0) {
+ swipeTarget.trigger(jQuery.Event("swipeLeft.sd"));
+ } else {
+ swipeTarget.trigger(jQuery.Event("swipeRight.sd"));
+ }
+ } else if (Math.abs(pixelOffsetY) > options.swipeThreshold) {
+ // Vertical swipe
+ if (pixelOffsetY < 0) {
+ swipeTarget.trigger(jQuery.Event("swipeUp.sd"));
+ } else {
+ swipeTarget.trigger(jQuery.Event("swipeDown.sd"));
+ }
+ }
+ }
+ }
+
+ function swiping(event) {
+ // If swipe don't occuring, do nothing.
+ if (swipeState !== 1) return;
+
+ if (event.originalEvent.touches) {
+ event = event.originalEvent.touches[0];
+ }
+
+ var swipeOffsetX = event.clientX - startX;
+ var swipeOffsetY = event.clientY - startY;
+
+ if (
+ Math.abs(swipeOffsetX) > options.swipeThreshold ||
+ Math.abs(swipeOffsetY) > options.swipeThreshold
+ ) {
+ swipeState = 2;
+ pixelOffsetX = swipeOffsetX;
+ pixelOffsetY = swipeOffsetY;
+ }
+ }
+
+ return swipeTarget; // Return element available for chaining.
+ }
+
+
+ // Destroy jBox and remove it from DOM
+
+ jBox.prototype.destroy = function ()
+ {
+ // Detach from attached elements
+ this.detach();
+
+ // If jBox is open, close without delay
+ this.isOpen && this.close({ignoreDelay: true});
+
+ // Remove wrapper
+ this.wrapper && this.wrapper.remove();
+
+ // Remove overlay
+ this.overlay && this.overlay.remove();
+
+ // Remove styles
+ this._styles && this._styles.remove();
+
+ // Tell the jBox instance it is destroyed
+ this.isDestroyed = true;
+
+ return this;
+ };
+
+
+ // Get a unique ID for jBoxes
+
+ jBox._getUniqueID = (function ()
+ {
+ var i = 1;
+ return function () { return i++; };
+ }());
+
+
+ // Get a unique ID for animating elements
+
+ jBox._getUniqueElementID = (function ()
+ {
+ var i = 1;
+ return function () { return i++; };
+ }());
+
+
+ // Function to create jBox plugins
+
+ jBox._pluginOptions = {};
+ jBox.plugin = function (type, options)
+ {
+ jBox._pluginOptions[type] = options;
+ };
+
+
+ // Make jBox usable with jQuery selectors
+
+ jQuery.fn.jBox = function (type, options) {
+ // Variables type and object are required
+ !type && (type = {});
+ !options && (options = {});
+
+ // Return a new instance of jBox with the selector as attached element
+ return new jBox(type, jQuery.extend(options, {
+ attach: this
+ }));
+ };
+
+ return jBox;
+
+};
+
+/**
+ * jBox Confirm plugin: Add a confirm dialog to links, buttons, etc.
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxConfirmWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Confirm', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-confirm)
+
+ confirmButton: 'Submit', // Text for the submit button
+ cancelButton: 'Cancel', // Text for the cancel button
+ confirm: null, // Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found
+ cancel: null, // Function to execute when clicking the cancel button
+ closeOnConfirm: true, // Close jBox when the user clicks the confirm button
+ target: window,
+ fixed: true,
+ attach: '[data-confirm]',
+ getContent: 'data-confirm',
+ content: 'Do you really want to do this?',
+ minWidth: 360,
+ maxWidth: 500,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: false,
+ closeButton: false,
+ overlay: true,
+ animation: 'zoomIn',
+ preventDefault: true,
+
+
+ // Triggered when jBox is attached to the element
+
+ _onAttach: function (el)
+ {
+ // Extract the href or the onclick event if no submit event is passed
+ if (!this.options.confirm) {
+ var submit = el.attr('onclick') ? el.attr('onclick') : (
+ el.attr('href') ? (
+ el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");' : 'window.location.href = "' + el.attr('href') + '";'
+ ) : '');
+ el.prop('onclick', null).data('jBox-Confirm-submit', submit);
+ }
+ },
+
+
+ // Triggered when jBox was created
+
+ _onCreated: function ()
+ {
+ // Add modal class to mimic jBox modal
+ this.wrapper.addClass('jBox-Modal');
+
+ // Add a footer to the jBox container
+ this.footer = jQuery('');
+
+ jQuery('
')
+ .html(this.options.cancelButton)
+ .on('click tap', function () {
+ this.options.cancel && this.options.cancel(this.source);
+ this.close();
+ }.bind(this))
+ .appendTo(this.footer);
+
+ this.submitButton = jQuery('
')
+ .html(this.options.confirmButton)
+ .appendTo(this.footer);
+
+ this.footer.appendTo(this.container);
+ },
+
+
+ // Triggered when jBox is opened
+
+ _onOpen: function ()
+ {
+ // Set the new action for the submit button
+ this.submitButton
+ .off('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id)
+ .on('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id, function () {
+ this.options.confirm ? this.options.confirm(this.source) : eval(this.source.data('jBox-Confirm-submit'));
+ this.options.closeOnConfirm && this.close();
+ }.bind(this));
+ }
+
+ });
+
+};
+
+/**
+ * jBox Image plugin: Adds a lightbox to your images
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxImageWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Image', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-image)
+
+ src: 'href', // The attribute where jBox gets the image source from, e.g. href="/path_to_image/image.jpg"
+ gallery: 'data-jbox-image', // The attribute to set the galleries, e.g. data-jbox-image="gallery1"
+ imageLabel: 'title', // The attribute where jBox gets the image label from, e.g. title="My label"
+ imageFade: 360, // The fade duration for images in ms
+ imageSize: 'contain', // How to display the images. Use CSS background-position values, e.g. 'cover', 'contain', 'auto', 'initial', '50% 50%'
+ imageCounter: false, // Set to true to add an image counter, e.g. 4/20
+ imageCounterSeparator: '/', // HTML to separate the current image number from all image numbers, e.g. '/' or ' of '
+ downloadButton: false, // Adds a download button
+ downloadButtonText: null, // Text for the download button
+ downloadButtonUrl: null, // The attribute at the source element where to find the image to download, e.g. data-download="/path_to_image/image.jpg". If none provided, the currently active image will be downloaded
+ mobileImageAttr: null, // The attribute to look for an mobile version of the image
+ mobileImageBreakpoint: null, // The upper breakpoint to load the mobile image
+ preloadFirstImage: false, // Preload the first image when page is loaded
+ target: window,
+ attach: '[data-jbox-image]',
+ fixed: true,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: 'button',
+ closeButton: true,
+ overlay: true,
+ animation: 'zoomIn',
+ preventDefault: true,
+ width: '100%',
+ height: '100%',
+ adjustDistance: {
+ top: 40,
+ right: 0,
+ bottom: 40,
+ left: 0
+ },
+
+
+ // Triggered when jBox is initialized
+
+ _onInit: function ()
+ {
+ // Initial images and z-index
+ this.images = this.currentImage = {};
+ this.imageZIndex = 1;
+
+ this.initImage = function (item) {
+ item = jQuery(item);
+
+ // Abort if the item was added to a gallery already
+ if (item.data('jBox-image-gallery')) {
+ return;
+ }
+
+ // Get the image src
+ var src = item.attr(this.options.src);
+
+ // Update responsive image src
+ if (this.options.mobileImageAttr && this.options.mobileImageBreakpoint && item.attr(this.options.mobileImageAttr)) {
+ if (jQuery(window).width() <= this.options.mobileImageBreakpoint) {
+ src = item.attr(this.options.mobileImageAttr);
+ }
+ }
+
+ // Add item to a gallery
+ var gallery = item.attr(this.options.gallery) || 'default';
+ !this.images[gallery] && (this.images[gallery] = []);
+ this.images[gallery].push({
+ src: src,
+ label: (item.attr(this.options.imageLabel) || ''),
+ downloadUrl: this.options.downloadButtonUrl && item.attr(this.options.downloadButtonUrl) ? item.attr(this.options.downloadButtonUrl) : null
+ });
+
+ // Remove the title attribute so it won't show the browsers tooltip
+ this.options.imageLabel == 'title' && item.removeAttr('title');
+
+ // Store data in source element for easy access
+ item.data('jBox-image-gallery', gallery);
+ item.data('jBox-image-id', (this.images[gallery].length - 1));
+ }.bind(this);
+
+ // Loop through images, sort and save in global variable
+ this.attachedElements && this.attachedElements.length && jQuery.each(this.attachedElements, function (index, item) {
+ this.initImage(item);
+ }.bind(this));
+
+ // Helper to inject the image into content area
+ var appendImage = function (gallery, id, show, instant) {
+ // Abort if image was appended already
+ if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
+ return;
+ }
+
+ // Create image container
+ var image = jQuery('
', {
+ id: 'jBox-image-' + gallery + '-' + id,
+ 'class': 'jBox-image-container' + (show ? ' jBox-image-' + gallery + '-current' : '')
+ }).css({
+ backgroundSize: this.options.imageSize,
+ opacity: (instant ? 1 : 0),
+ zIndex: (show ? this.imageZIndex++ : 0)
+ }).appendTo(this.content);
+
+ // Add swipe events
+ this.swipeDetector(image)
+ .on("swipeLeft.sd swipeRight.sd", function (event) {
+ if (event.type === "swipeLeft") {
+ this.showImage('next');
+ } else if (event.type === "swipeRight") {
+ this.showImage('prev');
+ }
+ }.bind(this));
+
+ // Create labels
+ jQuery('
', {
+ id: 'jBox-image-label-' + gallery + '-' + id,
+ 'class': 'jBox-image-label' + (show ? ' active' : '')
+ })
+ .html(this.images[gallery][id].label)
+ .on('click tap', function () {
+ jQuery(this).toggleClass('expanded');
+ })
+ .appendTo(this.imageLabelContainer);
+
+ // Show image
+ show && image.animate({opacity: 1}, instant ? 0 : this.options.imageFade);
+
+ return image;
+ }.bind(this);
+
+ // Function to download an image
+ this.downloadImage = function (imageUrl) {
+ var link = document.createElement('a');
+ link.href = imageUrl;
+ link.setAttribute('download', imageUrl.substring(imageUrl.lastIndexOf('/')+1));
+ document.body.appendChild(link);
+ link.click();
+ };
+
+ // Helper to show new image label
+ var showLabel = function (gallery, id) {
+ jQuery('.jBox-image-label.active').removeClass('active expanded');
+ jQuery('#jBox-image-label-' + gallery + '-' + id).addClass('active');
+ };
+
+ // Helper to load image
+ var loadImage = function (gallery, id, show, instant) {
+ var imageContainer = appendImage(gallery, id, show, instant);
+ imageContainer.addClass('jBox-image-loading');
+
+ jQuery(' ').each(function () {
+ var tmpImg = new Image();
+ tmpImg.onload = function () {
+ imageContainer.removeClass('jBox-image-loading');
+ imageContainer.css({backgroundImage: 'url("' + this.images[gallery][id].src + '")'});
+ }.bind(this);
+
+ tmpImg.onerror = function () {
+ imageContainer.removeClass('jBox-image-loading');
+ imageContainer.addClass('jBox-image-not-found');
+ }.bind(this);
+
+ tmpImg.src = this.images[gallery][id].src;
+ }.bind(this));
+ }.bind(this);
+
+ // Show images when they are loaded or load them if not
+ this.showImage = function (img) {
+ // Get the gallery and the image id from the next or the previous image
+ var gallery;
+ var id;
+
+ if (img != 'open') {
+ gallery = this.currentImage.gallery;
+ id = this.currentImage.id + (1 * (img == 'prev') ? -1 : 1);
+ id = id > (this.images[gallery].length - 1) ? 0 : (id < 0 ? (this.images[gallery].length - 1) : id);
+
+ // Or get image data from source element
+ } else {
+ // Get gallery and image id from source element
+ if (this.source) {
+ gallery = this.source.data('jBox-image-gallery');
+ id = this.source.data('jBox-image-id');
+
+ // Get gallery and image id attached elements
+ } else if (this.attachedElements && this.attachedElements.length) {
+ gallery = jQuery(this.attachedElements[0]).data('jBox-image-gallery');
+ id = jQuery(this.attachedElements[0]).data('jBox-image-id');
+ } else {
+ return;
+ }
+
+ // Remove or show the next and prev buttons
+ if (this.images && this.images[gallery]) {
+ jQuery('.jBox-image-pointer-prev, .jBox-image-pointer-next').css({display: (this.images[gallery].length > 1 ? 'block' : 'none')});
+ }
+ }
+
+ // If there is a current image already shown, hide it
+ if (jQuery('.jBox-image-' + gallery + '-current').length) {
+ jQuery('.jBox-image-' + gallery + '-current').removeClass('jBox-image-' + gallery + '-current').animate({opacity: 0}, (img == 'open') ? 0 : this.options.imageFade);
+ }
+
+ // Set new current image
+ this.currentImage = {gallery: gallery, id: id};
+
+ // Show image if it already exists
+ if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
+ jQuery('#jBox-image-' + gallery + '-' + id).addClass('jBox-image-' + gallery + '-current').css({zIndex: this.imageZIndex++, opacity: 0}).animate({opacity: 1}, (img == 'open') ? 0 : this.options.imageFade);
+
+ // Load image
+ } else {
+ loadImage(gallery, id, true, (img === 'open'));
+ }
+
+ // Show label
+ showLabel(gallery, id);
+
+ // Update the image counter numbers
+ if (this.imageCounter) {
+ if (this.images[gallery] && this.images[gallery].length > 1) {
+ this.wrapper.addClass('jBox-image-has-counter');
+ this.imageCounter.find('.jBox-image-counter-all').html(this.images[gallery].length);
+ this.imageCounter.find('.jBox-image-counter-current').html(id + 1);
+ } else {
+ this.wrapper.removeClass('jBox-image-has-counter');
+ }
+ }
+
+ // Preload next image
+ if (this.images[gallery] && this.images[gallery].length - 1) {
+ var next_id = id + 1;
+ next_id = next_id > (this.images[gallery].length - 1) ? 0 : (next_id < 0 ? (this.images[gallery].length - 1) : next_id);
+
+ if (!jQuery('#jBox-image-' + gallery + '-' + next_id).length) {
+ loadImage(gallery, next_id, false, false);
+ }
+ }
+ };
+
+ // Preload image
+ if (this.options.preloadFirstImage) {
+ jQuery(window).on('load', function() {
+ this.showImage('open');
+ }.bind(this));
+ }
+ },
+
+
+ // Triggered when jBox attaches a new element
+
+ _onAttach: function (item) {
+ this.initImage && this.initImage(item);
+ },
+
+
+ // Triggered when jBox was created
+
+ _onCreated: function ()
+ {
+ // Create image label and navigation buttons
+ this.imageLabelWrapper = jQuery('
').appendTo(this.wrapper);
+
+ this.imagePrevButton = jQuery('
')
+ .on('click tap', function () {
+ this.showImage('prev');
+ }.bind(this));
+
+ this.imageNextButton = jQuery('
')
+ .on('click tap', function () {
+ this.showImage('next');
+ }.bind(this));
+
+ this.imageLabelContainer = jQuery('
');
+
+ this.imageLabelWrapper
+ .append(this.imagePrevButton)
+ .append(this.imageLabelContainer)
+ .append(this.imageNextButton);
+
+ // Append the download button
+ if (this.options.downloadButton) {
+ this.downloadButton = jQuery('
', {'class': 'jBox-image-download-button-wrapper'})
+ .appendTo(this.wrapper)
+ .append(
+ this.options.downloadButtonText ? jQuery('
', {'class': 'jBox-image-download-button-text'}).html(this.options.downloadButtonText) : null
+ )
+ .append(
+ jQuery('
', {'class': 'jBox-image-download-button-icon'})
+ ).on('click tap', function () {
+ if (this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl) {
+ var currentImageUrl = this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl;
+ } else {
+ var currentImage = this.wrapper.find('.jBox-image-' + this.currentImage.gallery + '-current');
+ var currentImageStyle = currentImage[0].style.backgroundImage;
+ var currentImageUrl = currentImageStyle.slice(4, -1).replace(/["']/g, '');
+ }
+ this.downloadImage(currentImageUrl);
+ }.bind(this));
+ }
+
+ // Creating the image counter containers
+ if (this.options.imageCounter) {
+ this.imageCounter = jQuery('
', {'class': 'jBox-image-counter-container'}).insertAfter(this.imageLabelContainer);
+ this.imageCounter.append(jQuery(' ', {'class': 'jBox-image-counter-current'})).append(jQuery(' ').html(this.options.imageCounterSeparator)).append(jQuery(' ', {'class': 'jBox-image-counter-all'}));
+ }
+ },
+
+
+ // Triggered when jBox opens
+
+ _onOpen: function ()
+ {
+ // Add key events
+ jQuery(document).on('keyup.jBox-Image-' + this.id, function (ev) {
+ (ev.keyCode == 37) && this.showImage('prev');
+ (ev.keyCode == 39) && this.showImage('next');
+ }.bind(this));
+
+ // Load the image from the attached element
+ this.showImage('open');
+ },
+
+
+ // Triggered when jBox closes
+
+ _onClose: function ()
+ {
+ // Remove key events
+ jQuery(document).off('keyup.jBox-Image-' + this.id);
+ },
+
+
+ // Triggered when jBox finished closing
+
+ _onCloseComplete: function ()
+ {
+ // Hide all image containers
+ this.wrapper.find('.jBox-image-container').css('opacity', 0);
+ }
+
+ });
+
+};
+
+/**
+ * jBox Notice plugin: Opens a popup notice
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxNoticeWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Notice', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-notice)
+
+ color: null, // Add a color to your notices, use 'gray' (default), 'black', 'red', 'green', 'blue' or 'yellow'
+ stack: true, // Set to false to disable notice-stacking
+ stackSpacing: 10, // Spacing between notices when they stack
+ autoClose: 6000, // Time in ms after which the notice will disappear
+ attributes: { // Defines where the notice will pop up
+ x: 'right', // 'left' or 'right'
+ y: 'top' // 'top' or 'bottom'
+ },
+ position: { // Defines the distance to the viewport boundary
+ x: 15,
+ y: 15
+ },
+ responsivePositions: { // Responsive positions
+ 500: { // The key defines the maximum width of the viewport, the values will replace the default position options
+ x: 5, // Start with the lowest viewport
+ y: 5
+ },
+ 768: {
+ x: 10,
+ y: 10
+ }
+ },
+ target: window,
+ fixed: true,
+ animation: 'zoomIn',
+ closeOnClick: 'box',
+ zIndex: 12000,
+
+
+ // Triggered when notice is initialized
+
+ _onInit: function ()
+ {
+ // Cache position values
+ this.defaultNoticePosition = jQuery.extend({}, this.options.position);
+
+ // Type Notice has its own adjust position function
+ this._adjustNoticePositon = function () {
+ var win = jQuery(window);
+ var windowDimensions = {
+ x: win.width(),
+ y: win.height()
+ };
+
+ // Reset default position
+ this.options.position = jQuery.extend({}, this.defaultNoticePosition);
+
+ // Adjust depending on viewport
+ jQuery.each(this.options.responsivePositions, function (viewport, position) {
+ if (windowDimensions.x <= viewport) {
+ this.options.position = position;
+ return false;
+ }
+ }.bind(this));
+
+ // Set new padding options
+ this.options.adjustDistance = {
+ top: this.options.position.y,
+ right: this.options.position.x,
+ bottom: this.options.position.y,
+ left: this.options.position.x
+ };
+ };
+
+ // If jBox grabs an element as content, crab a clone instead
+ this.options.content instanceof jQuery && (this.options.content = this.options.content.clone().attr('id', ''));
+
+ // Adjust paddings when window resizes
+ jQuery(window).on('resize.responsivejBoxNotice-' + this.id, function (ev) { if (this.isOpen) { this._adjustNoticePositon(); } }.bind(this));
+
+ this.open();
+ },
+
+
+ // Triggered when notice was created
+
+ _onCreated: function ()
+ {
+ // Add color class
+ this.wrapper.addClass('jBox-Notice-color jBox-Notice-' + (this.options.color || 'gray'));
+
+ // Store position in jBox wrapper
+ this.wrapper.data('jBox-Notice-position', this.options.attributes.x + '-' + this.options.attributes.y);
+ },
+
+
+ // Triggered when notice opens
+
+ _onOpen: function ()
+ {
+ // Bail if we're stacking
+ if (this.options.stack) {
+ return;
+ }
+
+ // Adjust position when opening
+ this._adjustNoticePositon();
+
+ // Loop through notices at same window corner destroy them
+ jQuery.each(jQuery('.jBox-Notice'), function (index, el)
+ {
+ el = jQuery(el);
+
+ // Abort if the element is this notice or when it's not at the same position
+ if (el.attr('id') == this.id || el.data('jBox-Notice-position') != this.options.attributes.x + '-' + this.options.attributes.y) {
+ return;
+ }
+
+ // Remove notice when we don't wont to stack them
+ if (!this.options.stack) {
+ el.data('jBox').close({ignoreDelay: true});
+ return;
+ }
+ }.bind(this));
+ },
+
+ // Triggered when resizing window etc.
+
+ _onPosition: function ()
+ {
+ var stacks = {};
+ jQuery.each(jQuery('.jBox-Notice'), function (index, el)
+ {
+ el = jQuery(el);
+ var pos = el.data('jBox-Notice-position');
+ if (!stacks[pos]) {
+ stacks[pos] = [];
+ }
+ stacks[pos].push(el);
+ });
+ for (var pos in stacks) {
+ var position = pos.split('-');
+ var direction = position[1];
+ stacks[pos].reverse();
+ var margin = 0;
+ for (var i in stacks[pos]) {
+ var el = jQuery(stacks[pos][i]);
+ el.css('margin-' + direction, margin);
+ margin += el.outerHeight() + this.options.stackSpacing;
+ }
+ }
+ },
+
+ // Remove notice from DOM and reposition other notices when closing finishes
+
+ _onCloseComplete: function ()
+ {
+ this.destroy();
+ this.options._onPosition.bind(this).call();
+ }
+
+ });
+
+};
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], function (jQuery) {
+ return (root.jBox = factory(jQuery));
+ });
+ } else if (typeof module === 'object' && module.exports) {
+ module.exports = (root.jBox = factory(require('jquery')));
+ } else {
+ root.jBox = factory(root.jQuery);
+ }
+}(this, function (jQuery) {
+ var jBox = jBoxWrapper(jQuery);
+ try { typeof jBoxConfirmWrapper !== 'undefined' && jBoxConfirmWrapper && jBoxConfirmWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ try { typeof jBoxImageWrapper !== 'undefined' && jBoxImageWrapper && jBoxImageWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ try { typeof jBoxNoticeWrapper !== 'undefined' && jBoxNoticeWrapper && jBoxNoticeWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ return jBox;
+}));
+
+//# sourceMappingURL=jBox.all.js.map
diff --git a/dist/jBox.all.min.css b/dist/jBox.all.min.css
new file mode 100755
index 0000000..850c56c
--- /dev/null
+++ b/dist/jBox.all.min.css
@@ -0,0 +1 @@
+.jBox-wrapper{text-align:left;box-sizing:border-box}.jBox-container,.jBox-content,.jBox-title{position:relative;word-break:break-word;box-sizing:border-box}.jBox-container{background:#fff}.jBox-content{padding:8px 12px;overflow-x:hidden;overflow-y:auto;transition:opacity .2s}.jBox-footer{box-sizing:border-box}.jBox-Mouse .jBox-container,.jBox-Tooltip .jBox-container{border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.25)}.jBox-Mouse .jBox-title,.jBox-Tooltip .jBox-title{padding:8px 10px 0;font-weight:700}.jBox-Mouse.jBox-hasTitle .jBox-content,.jBox-Tooltip.jBox-hasTitle .jBox-content{padding-top:5px}.jBox-Mouse{pointer-events:none}.jBox-pointer{position:absolute;overflow:hidden;box-sizing:border-box}.jBox-pointer:after{content:'';width:20px;height:20px;position:absolute;background:#fff;transform:rotate(45deg);box-sizing:border-box}.jBox-pointer-top{top:0}.jBox-pointer-top:after{left:5px;top:6px;box-shadow:-1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-right{right:0}.jBox-pointer-right:after{top:5px;right:6px;box-shadow:1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-left{left:0}.jBox-pointer-left:after{top:5px;left:6px;box-shadow:-1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom{bottom:0}.jBox-pointer-bottom:after{left:5px;bottom:6px;box-shadow:1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom,.jBox-pointer-top{width:30px;height:12px}.jBox-pointer-left,.jBox-pointer-right{width:12px;height:30px}.jBox-Modal .jBox-container{border-radius:4px}.jBox-Modal .jBox-container,.jBox-Modal.jBox-closeButton-box:before{box-shadow:0 3px 15px rgba(0,0,0,.4),0 0 5px rgba(0,0,0,.4)}.jBox-Modal .jBox-content{padding:15px 20px}.jBox-Modal .jBox-title{border-radius:4px 4px 0 0;padding:15px 20px;background:#fafafa;border-bottom:1px solid #eee}.jBox-Modal.jBox-closeButton-title .jBox-title{padding-right:65px}.jBox-Modal .jBox-footer{border-radius:0 0 4px 4px}.jBox-closeButton{z-index:1;cursor:pointer;position:absolute;box-sizing:border-box}.jBox-closeButton svg{position:absolute;top:50%;right:50%}.jBox-closeButton path{fill:#aaa;transition:fill .2s}.jBox-closeButton:hover path{fill:#888}.jBox-overlay .jBox-closeButton{top:0;right:0;width:40px;height:40px}.jBox-overlay .jBox-closeButton svg{width:20px;height:20px;margin-top:-10px;margin-right:-10px}.jBox-overlay .jBox-closeButton path{fill:#ddd}.jBox-overlay .jBox-closeButton:hover path{fill:#fff}.jBox-closeButton-title .jBox-closeButton{top:0;right:0;bottom:0;width:50px}.jBox-closeButton-title svg{width:12px;height:12px;margin-top:-6px;margin-right:-6px}.jBox-closeButton-box{box-sizing:border-box}.jBox-closeButton-box .jBox-closeButton{top:-8px;right:-10px;width:24px;height:24px;background:#fff;border-radius:50%}.jBox-closeButton-box .jBox-closeButton svg{width:10px;height:10px;margin-top:-5px;margin-right:-5px}.jBox-closeButton-box:before{content:'';position:absolute;top:-8px;right:-10px;width:24px;height:24px;border-radius:50%;box-shadow:0 0 5px rgba(0,0,0,.3)}.jBox-closeButton-box.jBox-pointerPosition-top:before{top:5px}.jBox-closeButton-box.jBox-pointerPosition-right:before{right:2px}.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton{background:#fafafa}.jBox-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.82)}.jBox-footer{background:#fafafa;border-top:1px solid #eee;padding:8px 10px;border-radius:0 0 3px 3px}body[class*=" jBox-blockScroll-"],body[class^=jBox-blockScroll-]{overflow:hidden}.jBox-draggable{cursor:move}@keyframes jBoxLoading{to{transform:rotate(360deg)}}.jBox-loading .jBox-content{opacity:.2}.jBox-loading-spinner .jBox-content{min-height:38px!important;min-width:38px!important;opacity:0}.jBox-spinner{box-sizing:border-box;position:absolute;top:50%;left:50%;width:24px;height:24px;margin-top:-12px;margin-left:-12px}.jBox-spinner:before{display:block;box-sizing:border-box;content:'';width:24px;height:24px;border-radius:50%;border:2px solid rgba(0,0,0,.2);border-top-color:rgba(0,0,0,.8);animation:jBoxLoading .6s linear infinite}.jBox-countdown{border-radius:4px 4px 0 0;z-index:0;background:#000;opacity:.2;position:absolute;top:0;left:0;right:0;height:3px;overflow:hidden}.jBox-countdown-inner{top:0;right:0;width:100%;height:3px;position:absolute;background:#fff}[class*=" jBox-animated-"],[class^=jBox-animated-]{animation-fill-mode:both}@keyframes jBox-tada{0%{transform:scale(1)}10%,20%{transform:scale(.8) rotate(-4deg)}30%,50%,70%,90%{transform:scale(1.2) rotate(4deg)}40%,60%,80%{transform:scale(1.2) rotate(-4deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tada{animation:jBox-tada 1s}@keyframes jBox-tadaSmall{0%{transform:scale(1)}10%,20%{transform:scale(.9) rotate(-2deg)}30%,50%,70%,90%{transform:scale(1.1) rotate(2deg)}40%,60%,80%{transform:scale(1.1) rotate(-2deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tadaSmall{animation:jBox-tadaSmall 1s}@keyframes jBox-flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.jBox-animated-flash{animation:jBox-flash .5s}@keyframes jBox-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-6px)}40%,80%{transform:translateX(6px)}}.jBox-animated-shake{animation:jBox-shake .4s}@keyframes jBox-pulseUp{0%{transform:scale(1)}50%{transform:scale(1.15)}100%{transform:scale(1)}}.jBox-animated-pulseUp{animation:jBox-pulseUp .25s}@keyframes jBox-pulseDown{0%{transform:scale(1)}50%{transform:scale(.85)}100%{transform:scale(1)}}.jBox-animated-pulseDown{animation:jBox-pulseDown .25s}@keyframes jBox-popIn{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.jBox-animated-popIn{animation:jBox-popIn .25s}@keyframes jBox-popOut{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(0)}}.jBox-animated-popOut{animation:jBox-popOut .25s}@keyframes jBox-fadeIn{0%{opacity:0}100%{opacity:1}}.jBox-animated-fadeIn{animation:jBox-fadeIn .2s}@keyframes jBox-fadeOut{0%{opacity:1}100%{opacity:0}}.jBox-animated-fadeOut{animation:jBox-fadeOut .2s}@keyframes jBox-slideUp{0%{transform:translateY(0)}100%{transform:translateY(-300px);opacity:0}}.jBox-animated-slideUp{animation:jBox-slideUp .4s}@keyframes jBox-slideRight{0%{transform:translateX(0)}100%{transform:translateX(300px);opacity:0}}.jBox-animated-slideRight{animation:jBox-slideRight .4s}@keyframes jBox-slideDown{0%{transform:translateY(0)}100%{transform:translateY(300px);opacity:0}}.jBox-animated-slideDown{animation:jBox-slideDown .4s}@keyframes jBox-slideLeft{0%{transform:translateX(0)}100%{transform:translateX(-300px);opacity:0}}.jBox-animated-slideLeft{animation:jBox-slideLeft .4s}.jBox-Confirm .jBox-content{text-align:center;padding:46px 35px}@media (max-width:500px){.jBox-Confirm .jBox-content{padding:32px 20px}}.jBox-Confirm-footer{height:46px}.jBox-Confirm-button{display:block;float:left;cursor:pointer;text-align:center;width:50%;line-height:46px;height:46px;overflow:hidden;padding:0 10px;transition:color .2s,background-color .2s;box-sizing:border-box}.jBox-Confirm-button-cancel{border-bottom-left-radius:4px;background:#ddd;color:#666}.jBox-Confirm-button-cancel:active,.jBox-Confirm-button-cancel:hover{background:#ccc}.jBox-Confirm-button-cancel:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.jBox-Confirm-button-submit{border-bottom-right-radius:4px;background:#7d0;color:#fff}.jBox-Confirm-button-submit:active,.jBox-Confirm-button-submit:hover{background:#6c0}.jBox-Confirm-button-submit:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.jBox-Image .jBox-container{background-color:transparent}.jBox-Image .jBox-content{padding:0;width:100%;height:100%}.jBox-image-container{background:center center no-repeat;position:absolute;width:100%;height:100%;opacity:0}.jBox-image-label-wrapper{position:absolute;top:100%;left:0;right:0;height:40px;z-index:100;display:flex}.jBox-image-label-container{position:relative;flex:1}.jBox-image-label{box-sizing:border-box;position:absolute;left:0;bottom:0;width:100%;text-align:center;color:#fff;padding:8px 12px;font-size:15px;line-height:24px;transition:opacity .36s;opacity:0;z-index:0;pointer-events:none}.jBox-image-label.expanded{background:#000}.jBox-image-label:not(.expanded){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jBox-image-label.active{opacity:1;pointer-events:all}@media (max-width:600px){.jBox-image-label{font-size:13px}}.jBox-image-pointer-next,.jBox-image-pointer-prev{flex-shrink:0;width:40px;height:40px;cursor:pointer;opacity:.8;transition:opacity .2s;background:no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);background-size:11px auto;user-select:none;z-index:1}.jBox-image-pointer-next:hover,.jBox-image-pointer-prev:hover{opacity:1}.jBox-image-pointer-next{transform:scaleX(-1)}.jBox-image-counter-container{flex-shrink:0;white-space:nowrap;height:40px;line-height:40px;font-size:13px;color:#fff;text-align:right;display:none}.jBox-image-has-counter .jBox-image-counter-container{display:block}.jBox-overlay.jBox-overlay-Image{background:#000}.jBox-image-not-found{background:#000}.jBox-image-not-found:before{content:'';box-sizing:border-box;display:block;width:80px;height:80px;margin-top:-40px;margin-left:-40px;position:absolute;top:50%;left:50%;border:5px solid #222;border-radius:50%}.jBox-image-not-found:after{content:'';display:block;box-sizing:content-box;z-index:auto;width:6px;height:74px;margin-top:-37px;margin-left:-3px;position:absolute;top:50%;left:50%;background:#222;transform:rotateZ(45deg);transform-origin:50% 50% 0}.jBox-image-download-button-wrapper{position:absolute;top:-40px;right:35px;height:40px;display:flex;cursor:pointer;opacity:.8;transition:opacity .2s}.jBox-image-download-button-wrapper:hover{opacity:1}.jBox-image-download-button-icon{width:40px;height:40px;background:center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);background-size:60%}.jBox-image-download-button-text{white-space:nowrap;line-height:40px;padding:0 10px 0 0;color:#fff;font-size:14px}@keyframes jBoxImageLoading{to{transform:rotate(360deg)}}.jBox-image-loading:before{content:'';position:absolute;top:50%;left:50%;width:32px;height:32px;margin-top:-16px;margin-left:-16px;border:4px solid #333;border-bottom-color:#666;animation:jBoxImageLoading 1.2s linear infinite;border-radius:50%}.jBox-Notice{transition:margin .2s}.jBox-Notice .jBox-container{border-radius:4px;box-shadow:inset 1px 1px 0 0 rgba(255,255,255,.25),inset -1px -1px 0 0 rgba(0,0,0,.1)}.jBox-Notice .jBox-content{border-radius:4px;padding:12px 20px}@media (max-width:768px){.jBox-Notice .jBox-content{padding:10px 15px}}@media (max-width:500px){.jBox-Notice .jBox-content{padding:8px 10px}}.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:5px}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:0}}.jBox-Notice.jBox-hasTitle .jBox-title{padding:12px 20px 0;font-weight:700}@media (max-width:768px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:10px 15px 0}}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:8px 10px 0}}.jBox-Notice.jBox-closeButton-title .jBox-title{padding-right:55px}.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton{width:40px}.jBox-Notice.jBox-Notice-black .jBox-container{color:#fff;background:#000}.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-gray .jBox-container{color:#222;background:#f6f6f6}.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#222}.jBox-Notice.jBox-Notice-red .jBox-container{color:#fff;background:#d00}.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-green .jBox-container{color:#fff;background:#5d0}.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-blue .jBox-container{color:#fff;background:#49d}.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-yellow .jBox-container{color:#000;background:#fd0}.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-NoticeFancy .jBox-content,.jBox-NoticeFancy .jBox-title{padding-left:25px}.jBox-NoticeFancy.jBox-Notice-color .jBox-container{color:#fff;background:#000}.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after{content:'';position:absolute;top:0;left:0;bottom:0;width:8px;border-radius:4px 0 0 4px;background-image:linear-gradient(45deg,rgba(255,255,255,.4) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.4) 75%,transparent 75%,transparent);background-size:14px 14px}.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after{background-color:#888}.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after{background-color:#e00}.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after{background-color:#6c0}.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after{background-color:#49d}.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after{background-color:#fb0}.jBox-NoticeFancy .jBox-countdown{left:8px;border-radius:0 4px 0 0}.jBox-TooltipBorder .jBox-container,.jBox-TooltipBorder .jBox-pointer:after{border:2px solid #49d}.jBox-TooltipBorder .jBox-pointer:after{width:22px;height:22px}.jBox-TooltipBorder .jBox-pointer-bottom,.jBox-TooltipBorder .jBox-pointer-top{width:34px;height:13px}.jBox-TooltipBorder .jBox-pointer-bottom:after,.jBox-TooltipBorder .jBox-pointer-top:after{left:6px}.jBox-TooltipBorder .jBox-pointer-left,.jBox-TooltipBorder .jBox-pointer-right{width:13px;height:34px}.jBox-TooltipBorder .jBox-pointer-left:after,.jBox-TooltipBorder .jBox-pointer-right:after{top:6px}.jBox-TooltipBorder.jBox-closeButton-box:before{width:28px;height:28px;background:#49d}.jBox-TooltipBorderThick .jBox-container{box-shadow:none;border-radius:8px;border:4px solid #ccc}.jBox-TooltipBorderThick .jBox-pointer:after{box-shadow:none;border:4px solid #ccc;width:24px;height:24px}.jBox-TooltipBorderThick .jBox-pointer-bottom,.jBox-TooltipBorderThick .jBox-pointer-top{width:38px;height:13px}.jBox-TooltipBorderThick .jBox-pointer-left,.jBox-TooltipBorderThick .jBox-pointer-right{width:13px;height:38px}.jBox-TooltipBorderThick.jBox-closeButton-box:before{width:32px;height:32px;background:#ccc}.jBox-TooltipDark .jBox-container{border-radius:4px;background:#000;color:#fff;box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark .jBox-pointer:after{background:#000}.jBox-TooltipDark .jBox-closeButton{background:#000}.jBox-TooltipDark.jBox-closeButton-box:before{box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path{fill:#ddd}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path{fill:#fff}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path{fill:#bbb}.jBox-TooltipError{pointer-events:none}.jBox-TooltipError .jBox-container{border-radius:2px;background:#d00;color:#fff;font-weight:700;font-size:13px}.jBox-TooltipError .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipError .jBox-pointer:after{background:#d00;width:20px;height:20px}.jBox-TooltipError .jBox-pointer-bottom,.jBox-TooltipError .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipError .jBox-pointer-left,.jBox-TooltipError .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipError .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipError .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipError .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipError .jBox-pointer-left:after{top:1px;left:6px}.jBox-TooltipSmall{pointer-events:none}.jBox-TooltipSmall .jBox-container{border-radius:2px}.jBox-TooltipSmall .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipSmall .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmall .jBox-pointer-bottom,.jBox-TooltipSmall .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmall .jBox-pointer-left,.jBox-TooltipSmall .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmall .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipSmall .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmall .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipSmall .jBox-pointer-left:after{top:1px;left:6px}.jBox-TooltipSmallGray{pointer-events:none}.jBox-TooltipSmallGray .jBox-container{font-size:13px;line-height:24px;border-radius:12px;background-image:linear-gradient(to bottom,#fafafa,#f2f2f2)}.jBox-TooltipSmallGray .jBox-content{padding:0 10px}.jBox-TooltipSmallGray .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmallGray .jBox-pointer-bottom,.jBox-TooltipSmallGray .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmallGray .jBox-pointer-left,.jBox-TooltipSmallGray .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmallGray .jBox-pointer-top:after{background:#fafafa;left:1px;top:6px}.jBox-TooltipSmallGray .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmallGray .jBox-pointer-bottom:after{background:#f2f2f2;left:1px;bottom:6px}.jBox-TooltipSmallGray .jBox-pointer-left:after{top:1px;left:6px}
\ No newline at end of file
diff --git a/dist/jBox.all.min.js b/dist/jBox.all.min.js
new file mode 100755
index 0000000..ad0eaee
--- /dev/null
+++ b/dist/jBox.all.min.js
@@ -0,0 +1 @@
+function jBoxWrapper(j){function h(t,i){return this.options={id:null,width:"auto",height:"auto",minWidth:null,minHeight:null,maxWidth:null,maxHeight:null,responsiveWidth:!0,responsiveHeight:!0,responsiveMinWidth:100,responsiveMinHeight:100,attach:null,trigger:"click",preventDefault:!1,content:null,getContent:null,title:null,getTitle:null,footer:null,isolateScroll:!0,ajax:{url:null,data:"",reload:!1,getURL:"data-url",getData:"data-ajax",setContent:!0,loadingClass:!0,spinner:!0,spinnerDelay:300,spinnerReposition:!0},cancelAjaxOnClose:!0,target:null,position:{x:"center",y:"center"},outside:null,offset:0,attributes:{x:"left",y:"top"},fixed:!1,adjustPosition:!0,adjustTracker:!1,adjustDistance:5,reposition:!0,repositionOnOpen:!0,repositionOnContent:!0,holdPosition:!0,pointer:!1,pointTo:"target",fade:180,animation:null,theme:"Default",addClass:null,overlay:!1,overlayClass:null,zIndex:1e4,delayOpen:0,delayClose:0,closeOnEsc:!1,closeOnClick:!1,closeOnMouseleave:!1,closeButton:!1,appendTo:j("body"),createOnInit:!1,blockScroll:!1,blockScrollAdjust:!0,draggable:!1,dragOver:!0,autoClose:!1,delayOnHover:!1,showCountdown:!1,preloadAudio:!0,audio:null,volume:100,onInit:null,onAttach:null,onPosition:null,onCreated:null,onOpen:null,onOpenComplete:null,onClose:null,onCloseComplete:null,onDragStart:null,onDragEnd:null},this._pluginOptions={Tooltip:{getContent:"title",trigger:"mouseenter",position:{x:"center",y:"top"},outside:"y",pointer:!0},Mouse:{responsiveWidth:!1,responsiveHeight:!1,adjustPosition:"flip",target:"mouse",trigger:"mouseenter",position:{x:"right",y:"bottom"},outside:"xy",offset:5},Modal:{target:j(window),fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"overlay",closeButton:!0,overlay:!0,animation:"zoomIn"}},this.options=j.extend(!0,this.options,this._pluginOptions[t]||h._pluginOptions[t],i),"string"==j.type(t)&&(this.type=t),this.isTouchDevice=function(){var t=" -webkit- -moz- -o- -ms- ".split(" ");if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)return!0;var i,t=["(",t.join("touch-enabled),("),"heartz",")"].join("");return i=t,window.matchMedia(i).matches}(),this.isTouchDevice&&"mouseenter"===this.options.trigger&&!1===this.options.closeOnClick&&(this.options.closeOnClick="body"),this._fireEvent=function(t,i){this.options["_"+t]&&this.options["_"+t].bind(this)(i),this.options[t]&&this.options[t].bind(this)(i)},null===this.options.id&&(this.options.id="jBox"+h._getUniqueID()),this.id=this.options.id,("center"==this.options.position.x&&"x"==this.options.outside||"center"==this.options.position.y&&"y"==this.options.outside)&&(this.options.outside=null),"target"!=this.options.pointTo||this.options.outside&&"xy"!=this.options.outside||(this.options.pointer=!1),"object"!=j.type(this.options.offset)?this.options.offset={x:this.options.offset,y:this.options.offset}:this.options.offset=j.extend({x:0,y:0},this.options.offset),"object"!=j.type(this.options.adjustDistance)?this.options.adjustDistance={top:this.options.adjustDistance,right:this.options.adjustDistance,bottom:this.options.adjustDistance,left:this.options.adjustDistance}:this.options.adjustDistance=j.extend({top:5,left:5,right:5,bottom:5},this.options.adjustDistance),this.outside=!(!this.options.outside||"xy"==this.options.outside)&&this.options.position[this.options.outside],this.align=this.outside||("center"!=this.options.position.y&&"number"!=j.type(this.options.position.y)?this.options.position.x:"center"!=this.options.position.x&&"number"!=j.type(this.options.position.x)?this.options.position.y:this.options.attributes.x),h.zIndexMax=Math.max(h.zIndexMax||0,"auto"===this.options.zIndex?1e4:this.options.zIndex),"auto"===this.options.zIndex&&(this.adjustZIndexOnOpen=!0,this.options.zIndex=h.zIndexMax+=2,this.trueModal=this.options.overlay),this._getOpp=function(t){return{left:"right",right:"left",top:"bottom",bottom:"top",x:"y",y:"x"}[t]},this._getXY=function(t){return{left:"x",right:"x",top:"y",bottom:"y",center:"x"}[t]},this._getTL=function(t){return{left:"left",right:"left",top:"top",bottom:"top",center:"left",x:"left",y:"top"}[t]},this._getInt=function(t,i){return"auto"==t?"auto":t&&"string"==j.type(t)&&"%"==t.slice(-1)?j(window)["height"==i?"innerHeight":"innerWidth"]()*parseInt(t.replace("%",""))/100:t},this._createSVG=function(t,i){var o=document.createElementNS("http://www.w3.org/2000/svg",t);return j.each(i,function(t,i){o.setAttribute(i[0],i[1]||"")}),o},this._isolateScroll=function(e){e&&e.length&&e.on("DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll",function(t){var i=t.wheelDelta||t.originalEvent&&t.originalEvent.wheelDelta||-t.detail,o=0<=this.scrollTop+e.outerHeight()-this.scrollHeight,s=this.scrollTop<=0;(i<0&&o||0",{id:this.id,class:"jBox-wrapper"+(this.type?" jBox-"+this.type:"")+(this.options.theme?" jBox-"+this.options.theme:"")+(this.options.addClass?" "+this.options.addClass:"")}).css({position:this.options.fixed?"fixed":"absolute",display:"none",opacity:0,zIndex:this.options.zIndex}).data("jBox",this),this.options.closeOnMouseleave&&this.wrapper.on("mouseleave",function(t){!this.source||t.relatedTarget!=this.source[0]&&-1===j.inArray(this.source[0],j(t.relatedTarget).parents("*"))&&this.close()}.bind(this)),"box"==this.options.closeOnClick&&this.wrapper.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),this.container=j('
').appendTo(this.wrapper),this.content=j('
').appendTo(this.container),this.options.footer&&(this.footer=j('').append(this.options.footer).appendTo(this.container)),this.options.isolateScroll&&this._isolateScroll(this.content),this.options.closeButton&&((t=this._createSVG("svg",[["viewBox","0 0 24 24"]])).appendChild(this._createSVG("path",[["d","M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z"]])),this.closeButton=j('
').on("click tap",function(t){this.close({ignoreDelay:!0})}.bind(this)).append(t),"box"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay||this.options.title||this.options.getTitle)||(this.wrapper.addClass("jBox-closeButton-box"),this.closeButton.appendTo(this.container))),this.wrapper.appendTo(this.options.appendTo),this.wrapper.find(".jBox-closeButton").length&&j.each(["top","right","bottom","left"],function(t,i){this.wrapper.find(".jBox-closeButton").css(i)&&"auto"!=this.wrapper.find(".jBox-closeButton").css(i)&&(this.options.adjustDistance[i]=Math.max(this.options.adjustDistance[i],this.options.adjustDistance[i]+-1*((parseInt(this.wrapper.find(".jBox-closeButton").css(i))||0)+(parseInt(this.container.css("border-"+i+"-width"))||0))))}.bind(this)),this.options.pointer&&(this.pointer={position:"target"!=this.options.pointTo?this.options.pointTo:this._getOpp(this.outside),xy:"target"!=this.options.pointTo?this._getXY(this.options.pointTo):this._getXY(this.outside),align:"center",offset:0},this.pointer.element=j('
').appendTo(this.wrapper),this.pointer.dimensions={x:this.pointer.element.outerWidth(),y:this.pointer.element.outerHeight()},"string"==j.type(this.options.pointer)&&((t=this.options.pointer.split(":"))[0]&&(this.pointer.align=t[0]),t[1]&&(this.pointer.offset=parseInt(t[1]))),this.pointer.alignAttribute="x"==this.pointer.xy?"bottom"==this.pointer.align?"bottom":"top":"right"==this.pointer.align?"right":"left",this.wrapper.css("padding-"+this.pointer.position,this.pointer.dimensions[this.pointer.xy]),this.pointer.element.css(this.pointer.alignAttribute,"center"==this.pointer.align?"50%":0).css("margin-"+this.pointer.alignAttribute,this.pointer.offset),this.pointer.margin={},this.pointer.margin["margin-"+this.pointer.alignAttribute]=this.pointer.offset,"center"==this.pointer.align&&this.pointer.element.css("transform","translate("+("y"==this.pointer.xy?-.5*this.pointer.dimensions.x+"px":0)+", "+("x"==this.pointer.xy?-.5*this.pointer.dimensions.y+"px":0)+")"),this.pointer.element.css("x"==this.pointer.xy?"width":"height",parseInt(this.pointer.dimensions[this.pointer.xy])+parseInt(this.container.css("border-"+this.pointer.alignAttribute+"-width"))),this.wrapper.addClass("jBox-pointerPosition-"+this.pointer.position)),this.setContent(this.options.content,!0),this.setTitle(this.options.title,!0),this.options.draggable&&this._draggable(),this._fireEvent("onCreated"))},this.options.createOnInit&&this._create(),this.options.attach&&this.attach(),this._attachEvents=function(){this.options.delayOnHover&&j("#"+this.id).on("mouseenter",function(t){this.isHovered=!0}.bind(this)),this.options.delayOnHover&&j("#"+this.id).on("mouseleave",function(t){this.isHovered=!1}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&!this.fixed&&this.outside&&(this.options.adjustTracker&&j(window).on("scroll.jBox-"+this.id,function(t){this.position()}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&j(window).on("resize.jBox-"+this.id,function(t){this.position()}.bind(this))),"mouse"==this.options.target&&j("body").on("mousemove.jBox-"+this.id,function(t){this.position({mouseTarget:{top:t.pageY,left:t.pageX}})}.bind(this))},this._detachEvents=function(){this.options.closeOnEsc&&j(document).off("keyup.jBox-"+this.id),!0!==this.options.closeOnClick&&"body"!=this.options.closeOnClick||j(document).off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.options.adjustTracker&&j(window).off("scroll.jBox-"+this.id),(this.options.adjustPosition||this.options.reposition)&&j(window).off("resize.jBox-"+this.id),"mouse"==this.options.target&&j("body").off("mousemove.jBox-"+this.id)},this._showOverlay=function(){this.overlay||(this.overlay=j('
').addClass("jBox-overlay"+(this.type?" jBox-overlay-"+this.type:"")).css({display:"none",opacity:0,zIndex:this.options.zIndex-1}).appendTo(this.options.appendTo),this.options.overlayClass&&this.overlay.addClass(this.options.overlayClass),"overlay"!=this.options.closeButton&&!0!==this.options.closeButton||this.overlay.append(this.closeButton),"overlay"==this.options.closeOnClick&&this.overlay.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),j("#"+this.id+"-overlay .jBox-closeButton").length&&(this.options.adjustDistance.top=Math.max(j("#"+this.id+"-overlay .jBox-closeButton").outerHeight(),this.options.adjustDistance.top))),!0===this.adjustZIndexOnOpen&&this.overlay.css("zIndex",parseInt(this.wrapper.css("zIndex"),10)-1),"block"!=this.overlay.css("display")&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.overlay.css({display:"block"})}.bind(this)}):this.overlay.css({display:"block",opacity:1}))},this._hideOverlay=function(){this.overlay&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:0},{queue:!1,duration:this.options.fade,complete:function(){this.overlay.css({display:"none"})}.bind(this)}):this.overlay.css({display:"none",opacity:0}))},this._exposeDimensions=function(){this.wrapper.css({top:-1e4,left:-1e4,right:"auto",bottom:"auto"});var t={x:this.wrapper.outerWidth(),y:this.wrapper.outerHeight()};return this.wrapper.css({top:"auto",left:"auto"}),t},this._generateAnimationCSS=function(){if("object"!=j.type(this.options.animation)&&(this.options.animation={pulse:{open:"pulse",close:"zoomOut"},zoomIn:{open:"zoomIn",close:"zoomIn"},zoomOut:{open:"zoomOut",close:"zoomOut"},move:{open:"move",close:"move"},slide:{open:"slide",close:"slide"},flip:{open:"flip",close:"flip"},tada:{open:"tada",close:"zoomOut"}}[this.options.animation]),!this.options.animation)return null;this.options.animation.open&&(this.options.animation.open=this.options.animation.open.split(":")),this.options.animation.close&&(this.options.animation.close=this.options.animation.close.split(":")),this.options.animation.openDirection=this.options.animation.open[1]||null,this.options.animation.closeDirection=this.options.animation.close[1]||null,this.options.animation.open&&(this.options.animation.open=this.options.animation.open[0]),this.options.animation.close&&(this.options.animation.close=this.options.animation.close[0]),this.options.animation.open&&(this.options.animation.open+="Open"),this.options.animation.close&&(this.options.animation.close+="Close");var a={pulse:{duration:350,css:[["0%","scale(1)"],["50%","scale(1.1)"],["100%","scale(1)"]]},zoomInOpen:{duration:this.options.fade||180,css:[["0%","scale(0.9)"],["100%","scale(1)"]]},zoomInClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(0.9)"]]},zoomOutOpen:{duration:this.options.fade||180,css:[["0%","scale(1.1)"],["100%","scale(1)"]]},zoomOutClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(1.1)"]]},moveOpen:{duration:this.options.fade||180,positions:{top:{"0%":-12},right:{"0%":12},bottom:{"0%":12},left:{"0%":-12}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},moveClose:{duration:this.options.fade||180,timing:"ease-in",positions:{top:{"100%":-12},right:{"100%":12},bottom:{"100%":12},left:{"100%":-12}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},slideOpen:{duration:400,positions:{top:{"0%":-400},right:{"0%":400},bottom:{"0%":400},left:{"0%":-400}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},slideClose:{duration:400,timing:"ease-in",positions:{top:{"100%":-400},right:{"100%":400},bottom:{"100%":400},left:{"100%":-400}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},flipOpen:{duration:600,css:[["0%","perspective(400px) rotateX(90deg)"],["40%","perspective(400px) rotateX(-15deg)"],["70%","perspective(400px) rotateX(15deg)"],["100%","perspective(400px) rotateX(0deg)"]]},flipClose:{duration:this.options.fade||300,css:[["0%","perspective(400px) rotateX(0deg)"],["100%","perspective(400px) rotateX(90deg)"]]},tada:{duration:800,css:[["0%","scale(1)"],["10%, 20%","scale(0.9) rotate(-3deg)"],["30%, 50%, 70%, 90%","scale(1.1) rotate(3deg)"],["40%, 60%, 80%","scale(1.1) rotate(-3deg)"],["100%","scale(1) rotate(0)"]]}};j.each(["pulse","tada"],function(t,i){a[i+"Open"]=a[i+"Close"]=a[i]});var s=function(s,e){var n="@keyframes jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {";return j.each(a[this.options.animation[s]].css,function(t,i){var o=e?i[1].replace("%XY",this._getXY(e).toUpperCase()):i[1];a[this.options.animation[s]].positions&&(o=o.replace("%V",a[this.options.animation[s]].positions[e][i[0]])),n+=i[0]+" {transform:"+o+";}"}.bind(this)),n+="}",n+=".jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {",n+="animation-duration: "+a[this.options.animation[s]].duration+"ms;",n+="animation-name: jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+";",n+=a[this.options.animation[s]].timing?"animation-timing-function: "+a[this.options.animation[s]].timing+";":"",n+="}"}.bind(this);this._animationCSS="",j.each(["open","close"],function(t,o){if(!this.options.animation[o]||!a[this.options.animation[o]]||"close"==o&&!this.options.fade)return"";a[this.options.animation[o]].positions?j.each(["top","right","bottom","left"],function(t,i){this._animationCSS+=s(o,i)}.bind(this)):this._animationCSS+=s(o)}.bind(this))},this.options.animation&&this._generateAnimationCSS(),this._blockBodyClick=function(){this.blockBodyClick=!0,setTimeout(function(){this.blockBodyClick=!1}.bind(this),10)},this._animate=function(t){if(t=t||(this.isOpen?"open":"close"),!this.options.fade&&"close"==t)return null;var i=this.options.animation[t+"Direction"]||("center"!=this.align?this.align:this.options.attributes.x);this.flipped&&this._getXY(i)==this._getXY(this.align)&&(i=this._getOpp(i));var o="jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+" jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+"-"+i;this.wrapper.addClass(o);i=1e3*parseFloat(this.wrapper.css("animation-duration"));"close"==t&&(i=Math.min(i,this.options.fade)),setTimeout(function(){this.wrapper&&this.wrapper.removeClass(o)}.bind(this),i)},this._abortAnimation=function(){var t=this.wrapper.attr("class").split(" ").filter(function(t){return 0!==t.lastIndexOf("jBox-"+this.id+"-animation",0)}.bind(this));this.wrapper.attr("class",t.join(" "))},(this.options.responsiveWidth||this.options.responsiveHeight)&&j(window).on("resize.responsivejBox-"+this.id,function(t){this.isOpen&&this.position()}.bind(this)),"string"===j.type(this.options.preloadAudio)&&(this.options.preloadAudio=[this.options.preloadAudio]),"string"===j.type(this.options.audio)&&(this.options.audio={open:this.options.audio}),"number"===j.type(this.options.volume)&&(this.options.volume={open:this.options.volume,close:this.options.volume}),!0===this.options.preloadAudio&&this.options.audio&&(this.options.preloadAudio=[],j.each(this.options.audio,function(t,i){this.options.preloadAudio.push(i+".mp3"),this.options.preloadAudio.push(i+".ogg")}.bind(this))),this.options.preloadAudio.length&&j.each(this.options.preloadAudio,function(t,i){var o=new Audio;o.src=i,o.preload="auto"}),this._fireEvent("onInit"),this}var t,i;return h.prototype.attach=function(t,s){return t=t||this.options.attach,"string"==j.type(t)&&(t=j(t)),s=s||this.options.trigger,t&&t.length&&j.each(t,function(t,o){(o=j(o)).data("jBox-attached-"+this.id)||("title"==this.options.getContent&&null!=o.attr("title")&&o.data("jBox-getContent",o.attr("title")).removeAttr("title"),this.attachedElements||(this.attachedElements=[]),this.attachedElements.push(o[0]),o.on(s+".jBox-attach-"+this.id,function(t){var i;this.timer&&clearTimeout(this.timer),"mouseenter"==s&&this.isOpen&&this.source[0]==o[0]||(this.isOpen&&this.source&&this.source[0]!=o[0]&&(i=!0),this.source=o,this.options.target||(this.target=o),"click"==s&&this.options.preventDefault&&t.preventDefault(),this["click"!=s||i?"open":"toggle"]())}.bind(this)),"mouseenter"==this.options.trigger&&o.on("mouseleave",function(t){if(!this.wrapper)return null;this.options.closeOnMouseleave&&(t.relatedTarget==this.wrapper[0]||j(t.relatedTarget).parents("#"+this.id).length)||this.close()}.bind(this)),o.data("jBox-attached-"+this.id,s),this._fireEvent("onAttach",o))}.bind(this)),this},h.prototype.detach=function(t){return(t=t||(this.attachedElements||[]))&&t.length&&j.each(t,function(t,i){(i=j(i)).data("jBox-attached-"+this.id)&&(i.off(i.data("jBox-attached-"+this.id)+".jBox-attach-"+this.id),i.data("jBox-attached-"+this.id,null)),this.attachedElements=j.grep(this.attachedElements,function(t){return t!=i[0]})}.bind(this)),this},h.prototype.setTitle=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();return this.title||(this.titleContainer=j('
'),this.title=j("
").appendTo(this.titleContainer),"title"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay)||(this.wrapper.addClass("jBox-closeButton-title"),this.closeButton.appendTo(this.titleContainer)),this.titleContainer.insertBefore(this.content),this._setTitleWidth()),this.wrapper[t?"addClass":"removeClass"]("jBox-hasTitle"),this.title.html(t),s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setContent=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();switch(this.content.children("[data-jbox-content-appended]").appendTo("body").css({display:"none"}),j.type(t)){case"string":this.content.html(t);break;case"object":t&&(t instanceof j||t.constructor.prototype.jquery)?(this.content.html(""),t.attr("data-jbox-content-appended",1).appendTo(this.content).css({display:"block"})):this.content.html(JSON.stringify(t))}return s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setDimensions=function(t,i,o){this.wrapper||this._create(),this.content.css(t,this._getInt(i=null==i?"auto":i)),"width"==t&&this._setTitleWidth(),this.options[t]=i,null!=o&&!o||this.position()},h.prototype.setWidth=function(t,i){this.setDimensions("width",t,i)},h.prototype.setHeight=function(t,i){this.setDimensions("height",t,i)},h.prototype.position=function(o){if(o=j.extend(!0,this.options,o=o||{}),this.target=o.target||this.target||j(window),this.target instanceof j||"mouse"==this.target||(this.target=j(this.target)),!this.target.length)return this;this.content.css({width:this._getInt(o.width,"width"),height:this._getInt(o.height,"height"),minWidth:this._getInt(o.minWidth,"width"),minHeight:this._getInt(o.minHeight,"height"),maxWidth:this._getInt(o.maxWidth,"width"),maxHeight:this._getInt(o.maxHeight,"height")}),this._setTitleWidth();var s=this._exposeDimensions();"mouse"==this.target||this.target.data("jBox-"+this.id+"-fixed")||this.target.data("jBox-"+this.id+"-fixed",this.target[0]!=j(window)[0]&&("fixed"==this.target.css("position")||0a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),(o.responsiveWidth||o.responsiveHeight)&&(m=function(){var t;o.responsiveWidth&&s.x>a[h.x||"x"]&&(t=a[h.x||"x"]-(this.pointer&&n&&"x"==o.outside?this.pointer.dimensions.x:0)-parseInt(this.container.css("border-left-width"))-parseInt(this.container.css("border-right-width")),this.content.css({width:t>this.options.responsiveMinWidth?t:null,minWidth:ta[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),f=function(){var t;o.responsiveHeight&&s.y>a[h.y||"y"]&&(t=function(){return this.titleContainer||this.footer?("none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),this.wrapper.css("display","none")):t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),t||0):0;var t}.bind(this),t=a[h.y||"y"]-(this.pointer&&n&&"y"==o.outside?this.pointer.dimensions.y:0)-t()-parseInt(this.container.css("border-top-width"))-parseInt(this.container.css("border-bottom-width")),this.content.css({height:t>this.options.responsiveMinHeight?t:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveHeight&&f(),o.responsiveHeight&&!r.x&&h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),o.adjustPosition&&"move"!=o.adjustPosition&&(r.x&&m(),r.y&&f()));var p={},l=function(t){if("number"!=j.type(o.position[t])){var i=o.attributes[t]="x"==t?"left":"top";if(p[i]=e[i],"center"==o.position[t])return p[i]+=Math.ceil((e[t]-s[t])/2),void("mouse"!=this.target&&this.target[0]&&this.target[0]==j(window)[0]&&(p[i]+=.5*(o.adjustDistance[i]-o.adjustDistance[this._getOpp(i)])));i!=o.position[t]&&(p[i]+=e[t]-s[t]),o.outside!=t&&"xy"!=o.outside||(p[i]+=s[t]*(i!=o.position[t]?1:-1))}else p[o.attributes[t]]=o.position[t]}.bind(this);if(l("x"),l("y"),this.pointer&&"target"==o.pointTo&&"number"!=j.type(o.position.x)&&"number"!=j.type(o.position.y)&&(x=0,"center"===this.pointer.align?"center"!=o.position[this._getOpp(o.outside)]&&(x+=s[this._getOpp(o.outside)]/2):"center"===o.position[this._getOpp(o.outside)]?x+=(s[this._getOpp(o.outside)]/2-this.pointer.dimensions[this._getOpp(o.outside)]/2)*(this.pointer.align==this._getTL(this.pointer.align)?1:-1):x+=this.pointer.align!=o.position[this._getOpp(o.outside)]?s[this._getOpp(o.outside)]*(-1!==j.inArray(this.pointer.align,["top","left"])?1:-1)+this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==j.inArray(this.pointer.align,["top","left"])?-1:1):this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==j.inArray(this.pointer.align,["top","left"])?1:-1),x*=o.position[this._getOpp(o.outside)]==this.pointer.alignAttribute?-1:1,x+=this.pointer.offset*(this.pointer.align==this._getOpp(this._getTL(this.pointer.align))?1:-1),p[this._getTL(this._getOpp(this.pointer.xy))]+=x),p[o.attributes.x]+=o.offset.x,p[o.attributes.y]+=o.offset.y,this.wrapper.css(p),o.adjustPosition){this.positionAdjusted&&(this.pointer&&this.wrapper.css("padding",0).css("padding-"+this._getOpp(this.outside),this.pointer.dimensions[this._getXY(this.outside)]).removeClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).addClass("jBox-pointerPosition-"+this.pointer.position),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+this._getOpp(this.outside)).css(this.pointer.margin),this.positionAdjusted=!1,this.flipped=!1);var d=t.top>p.top-(o.adjustDistance.top||0),c=t.rightp.left-(o.adjustDistance.left||0),i=g?"left":c?"right":null,m=d?"top":u?"bottom":null;if(i||m){if(("Modal"==this.type||"Confirm"==this.type)&&"number"==j.type(this.options.position.x)&&"number"==j.type(this.options.position.y)){var f=0,x=0;return this.options.holdPosition&&(g?f=t.left-(p.left-(o.adjustDistance.left||0)):c&&(f=t.right-(p.left+s.x+(o.adjustDistance.right||0))),d?x=t.top-(p.top-(o.adjustDistance.top||0)):u&&(x=t.bottom-(p.top+s.y+(o.adjustDistance.bottom||0))),this.options.position.x=Math.max(t.top,this.options.position.x+f),this.options.position.y=Math.max(t.left,this.options.position.y+x),l("x"),l("y"),this.wrapper.css(p)),this._fireEvent("onPosition"),this}!0!==o.adjustPosition&&"flip"!==o.adjustPosition||(y=function(t){this.wrapper.css(this._getTL(t),p[this._getTL(t)]+(s[this._getXY(t)]+o.offset[this._getXY(t)]*("top"==t||"left"==t?-2:2)+e[this._getXY(t)])*("top"==t||"left"==t?1:-1)),this.pointer&&this.wrapper.removeClass("jBox-pointerPosition-"+this.pointer.position).addClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).css("padding",0).css("padding-"+t,this.pointer.dimensions[this._getXY(t)]),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+t),this.positionAdjusted=!0,this.flipped=!0}.bind(this),r.x&&y(this.options.position.x),r.y&&y(this.options.position.y));var y="x"==this._getXY(this.outside)?m:i;this.pointer&&"target"==o.pointTo&&"flip"!=o.adjustPosition&&this._getXY(y)==this._getOpp(this._getXY(this.outside))&&(m="center"==this.pointer.align?s[this._getXY(y)]/2-this.pointer.dimensions[this._getOpp(this.pointer.xy)]/2-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))*(y!=this._getTL(y)?-1:1):y==this.pointer.alignAttribute?parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute)):s[this._getXY(y)]-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-this.pointer.dimensions[this._getXY(y)],i=y==this._getTL(y)?t[this._getTL(y)]-p[this._getTL(y)]+o.adjustDistance[y]:-1*(t[this._getOpp(this._getTL(y))]-p[this._getTL(y)]-o.adjustDistance[y]-s[this._getXY(y)]),y==this._getOpp(this._getTL(y))&&p[this._getTL(y)]-i<=m&&0window.innerHeight},this.pageHasScrollbar()){t=this.getElementsToAdjust(t);for(var i=0;i").append(this._animationCSS).appendTo(j("head"))),this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;this.options.closeOnEsc&&j(document).on("keyup.jBox-"+this.id,function(t){27==t.keyCode&&this.close({ignoreDelay:!0})}.bind(this)),!0!==this.options.closeOnClick&&"body"!==this.options.closeOnClick||(j("body").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(t){this.blockBodyClick||"body"==this.options.closeOnClick&&(t.target==this.wrapper[0]||this.wrapper.has(t.target).length)||this.close({ignoreDelay:!0})}.bind(this)),this.isTouchDevice&&j("body > *").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(){return!0}));var i=function(){!0===this.adjustZIndexOnOpen&&(h.zIndexMax=Math.max(parseInt(this.wrapper.css("zIndex"),10),this.options.zIndex,h.zIndexMax||0,h.zIndexMaxDragover||0)+2,this.wrapper.css("zIndex",h.zIndexMax),this.options.zIndex=h.zIndexMax),this.source&&this.options.getTitle&&this.source.attr(this.options.getTitle)&&this.setTitle(this.source.attr(this.options.getTitle),!0),this.source&&this.options.getContent&&(this.source.data("jBox-getContent")?this.setContent(this.source.data("jBox-getContent"),!0):this.source.attr(this.options.getContent)?this.setContent(this.source.attr(this.options.getContent),!0):"html"==this.options.getContent&&this.setContent(this.source.html(),!0)),this._fireEvent("onOpen"),(this.options.ajax&&(this.options.ajax.url||this.source&&this.source.attr(this.options.ajax.getURL))&&(!this.ajaxLoaded||this.options.ajax.reload)||t.ajax&&(t.ajax.url||t.ajax.data))&&("strict"==this.options.ajax.reload||!this.source||!this.source.data("jBox-ajax-data")||t.ajax&&(t.ajax.url||t.ajax.data)?this.ajax(t.ajax||null,!0):this.setContent(this.source.data("jBox-ajax-data"))),this.positionedOnOpen&&!this.options.repositionOnOpen||!this.position(t)||(this.positionedOnOpen=!0),this.isClosing&&this._abortAnimation(),this.isOpen||(this.isOpen=!0,this.options.autoClose&&(this.options.delayClose=this.options.autoClose)&&this.close(),this._attachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?h.blockScrollScopes?h.blockScrollScopes++:(h.blockScrollScopes=1,this.unscroll(Array.isArray(this.options.blockScrollAdjust)||"string"==typeof this.options.blockScrollAdjust?this.options.blockScrollAdjust:null)):j("body").addClass("jBox-blockScroll-"+this.id)),this.options.overlay&&(this._showOverlay(),this.position()),this.options.animation&&!this.isClosing&&this._animate("open"),this.options.audio&&this.options.audio.open&&this.audio(this.options.audio.open,this.options.volume.open),this.options.fade?this.wrapper.stop().animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.isOpening=!0,this.wrapper.css({display:"block"})}.bind(this),complete:function(){this._fireEvent("onOpenComplete")}.bind(this),always:function(){this.isOpening=!1,setTimeout(function(){this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)}.bind(this),10)}.bind(this)}):(this.wrapper.css({display:"block",opacity:1}),this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1),this._fireEvent("onOpenComplete")))}.bind(this);return!this.options.delayOpen||this.isOpen||this.isClosing||t.ignoreDelay?i():this.timer=setTimeout(i,this.options.delayOpen),this},h.prototype.close=function(t){if(t=t||{},j("body").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isTouchDevice&&j("body > *").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isDestroyed||this.isClosing)return this;if(this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i,o,s,e=function(){var t;this._fireEvent("onClose"),this.options.cancelAjaxOnClose&&this.cancelAjax(),this.isOpen&&(this.isOpen=!1,this._detachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?(h.blockScrollScopes=h.blockScrollScopes?--h.blockScrollScopes:0)||this.unscroll.reset():j("body").removeClass("jBox-blockScroll-"+this.id)),this.options.overlay&&this._hideOverlay(),this.options.animation&&!this.isOpening&&this._animate("close"),this.options.audio&&this.options.audio.close&&this.audio(this.options.audio.close,this.options.volume.close),(t=this.isTouchDevice&&"mouse"==this.options.target?0:this.options.fade)?this.wrapper.stop().animate({opacity:0},{queue:!1,duration:t,start:function(){this.isClosing=!0}.bind(this),complete:function(){this.wrapper.css({display:"none"}),this._fireEvent("onCloseComplete")}.bind(this),always:function(){this.isClosing=!1}.bind(this)}):(this.wrapper.css({display:"none",opacity:0}),this._fireEvent("onCloseComplete")))}.bind(this);return t.ignoreDelay||this.isTouchDevice&&"mouse"==this.options.target?e():(this.options.delayOnHover||this.options.showCountdown)&&10
'),this.inner=j('
'),t.prepend(this.inner),j("#"+this.id).append(t)),this.countdown=function(){var t=Date.now();i.isHovered||(o-=t-s),s=t,0 ').appendTo(this.container),this.titleContainer&&"absolute"==this.spinner.css("position")&&this.spinner.css({transform:"translateY("+.5*this.titleContainer.outerHeight()+"px)"})}.bind(this),""!=this.content.html()&&h.spinnerDelay||0)),s.bind(this)(t)}.bind(this),h.complete=function(t){this.spinnerDelay&&clearTimeout(this.spinnerDelay),this.wrapper.removeClass("jBox-loading jBox-loading-spinner jBox-loading-spinner-delay"),this.spinner&&this.spinner.length&&this.spinner.remove()&&h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.ajaxLoaded=!0,e.bind(this)(t)}.bind(this),h.success=function(t){h.setContent&&this.setContent(t,!0)&&(i?this.positionOnFadeComplete=!0:this.position()),h.setContent&&this.source&&this.source.data("jBox-ajax-data",t),n.bind(this)(t)}.bind(this),h.error=function(t){a.bind(this)(t)}.bind(this),this.ajaxRequest=j.ajax(h),this},h.prototype.cancelAjax=function(){this.ajaxRequest&&(this.ajaxRequest.abort(),this.ajaxLoaded=!1)},h.prototype.audio=function(t,i){if(!t)return this;var o;(h._audio=!h._audio?{}:h._audio)[t]||(o=j(" "),j(" ",{src:t+".mp3"}).appendTo(o),j(" ",{src:t+".ogg"}).appendTo(o),h._audio[t]=o[0]),h._audio[t].volume=Math.min((null!=i?i:100)/100,1);try{h._audio[t].pause(),h._audio[t].currentTime=0}catch(t){}return h._audio[t].play(),this},h._animationSpeeds={tada:1e3,tadaSmall:1e3,flash:500,shake:400,pulseUp:250,pulseDown:250,popIn:250,popOut:250,fadeIn:200,fadeOut:200,slideUp:400,slideRight:400,slideLeft:400,slideDown:400},h.prototype.animate=function(t,i){i=i||{},this.animationTimeout||(this.animationTimeout={}),i.element||(i.element=this.wrapper),i.element.data("jBox-animating-id")||i.element.data("jBox-animating-id",h._getUniqueElementID()),i.element.data("jBox-animating")&&(i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),this.animationTimeout[i.element.data("jBox-animating-id")]&&clearTimeout(this.animationTimeout[i.element.data("jBox-animating-id")])),i.element.addClass("jBox-animated-"+t).data("jBox-animating","jBox-animated-"+t),this.animationTimeout[i.element.data("jBox-animating-id")]=setTimeout(function(){i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),i.complete&&i.complete()},h._animationSpeeds[t])},h.prototype.swipeDetector=function(i,o){var s=0,e=0,n=0,a=0,h=0;function t(t){o.useOnlyTouch&&!t.originalEvent.touches||(t.originalEvent.touches&&(t=t.originalEvent.touches[0]),0===s&&(s=1,e=t.clientX,n=t.clientY))}function r(t){2===s&&(s=0,Math.abs(a)>Math.abs(h)&&Math.abs(a)>o.swipeThreshold?a<0?i.trigger(j.Event("swipeLeft.sd")):i.trigger(j.Event("swipeRight.sd")):Math.abs(h)>o.swipeThreshold&&(h<0?i.trigger(j.Event("swipeUp.sd")):i.trigger(j.Event("swipeDown.sd"))))}function p(t){var i;1===s&&(i=(t=t.originalEvent.touches?t.originalEvent.touches[0]:t).clientX-e,t=t.clientY-n,(Math.abs(i)>o.swipeThreshold||Math.abs(t)>o.swipeThreshold)&&(s=2,a=i,h=t))}return o=j.extend({swipeThreshold:70,useOnlyTouch:!1},o),i.on("mousedown touchstart",t),j("html").on("mouseup touchend",r),j("html").on("mousemove touchmove",p),i},h.prototype.destroy=function(){return this.detach(),this.isOpen&&this.close({ignoreDelay:!0}),this.wrapper&&this.wrapper.remove(),this.overlay&&this.overlay.remove(),this._styles&&this._styles.remove(),this.isDestroyed=!0,this},h._getUniqueID=(t=1,function(){return t++}),h._getUniqueElementID=(i=1,function(){return i++}),h._pluginOptions={},h.plugin=function(t,i){h._pluginOptions[t]=i},j.fn.jBox=function(t,i){return new h(t=t||{},j.extend(i=i||{},{attach:this}))},h}function jBoxConfirmWrapper(jBox,jQuery){new jBox.plugin("Confirm",{confirmButton:"Submit",cancelButton:"Cancel",confirm:null,cancel:null,closeOnConfirm:!0,target:window,fixed:!0,attach:"[data-confirm]",getContent:"data-confirm",content:"Do you really want to do this?",minWidth:360,maxWidth:500,blockScroll:!0,closeOnEsc:!0,closeOnClick:!1,closeButton:!1,overlay:!0,animation:"zoomIn",preventDefault:!0,_onAttach:function(t){var i;this.options.confirm||(i=t.attr("onclick")?t.attr("onclick"):t.attr("href")?t.attr("target")?'window.open("'+t.attr("href")+'", "'+t.attr("target")+'");':'window.location.href = "'+t.attr("href")+'";':"",t.prop("onclick",null).data("jBox-Confirm-submit",i))},_onCreated:function(){this.wrapper.addClass("jBox-Modal"),this.footer=jQuery(''),jQuery('
').html(this.options.cancelButton).on("click tap",function(){this.options.cancel&&this.options.cancel(this.source),this.close()}.bind(this)).appendTo(this.footer),this.submitButton=jQuery('
').html(this.options.confirmButton).appendTo(this.footer),this.footer.appendTo(this.container)},_onOpen:function(){this.submitButton.off("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id).on("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id,function(){this.options.confirm?this.options.confirm(this.source):eval(this.source.data("jBox-Confirm-submit")),this.options.closeOnConfirm&&this.close()}.bind(this))}})}function jBoxImageWrapper(t,a){new t.plugin("Image",{src:"href",gallery:"data-jbox-image",imageLabel:"title",imageFade:360,imageSize:"contain",imageCounter:!1,imageCounterSeparator:"/",downloadButton:!1,downloadButtonText:null,downloadButtonUrl:null,mobileImageAttr:null,mobileImageBreakpoint:null,preloadFirstImage:!1,target:window,attach:"[data-jbox-image]",fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"button",closeButton:!0,overlay:!0,animation:"zoomIn",preventDefault:!0,width:"100%",height:"100%",adjustDistance:{top:40,right:0,bottom:40,left:0},_onInit:function(){this.images=this.currentImage={},this.imageZIndex=1,this.initImage=function(t){var i,o;(t=a(t)).data("jBox-image-gallery")||(i=t.attr(this.options.src),this.options.mobileImageAttr&&this.options.mobileImageBreakpoint&&t.attr(this.options.mobileImageAttr)&&a(window).width()<=this.options.mobileImageBreakpoint&&(i=t.attr(this.options.mobileImageAttr)),o=t.attr(this.options.gallery)||"default",this.images[o]||(this.images[o]=[]),this.images[o].push({src:i,label:t.attr(this.options.imageLabel)||"",downloadUrl:this.options.downloadButtonUrl&&t.attr(this.options.downloadButtonUrl)?t.attr(this.options.downloadButtonUrl):null}),"title"==this.options.imageLabel&&t.removeAttr("title"),t.data("jBox-image-gallery",o),t.data("jBox-image-id",this.images[o].length-1))}.bind(this),this.attachedElements&&this.attachedElements.length&&a.each(this.attachedElements,function(t,i){this.initImage(i)}.bind(this));var n=function(t,i,o,s){if(!a("#jBox-image-"+t+"-"+i).length){var e=a("
",{id:"jBox-image-"+t+"-"+i,class:"jBox-image-container"+(o?" jBox-image-"+t+"-current":"")}).css({backgroundSize:this.options.imageSize,opacity:s?1:0,zIndex:o?this.imageZIndex++:0}).appendTo(this.content);return this.swipeDetector(e).on("swipeLeft.sd swipeRight.sd",function(t){"swipeLeft"===t.type?this.showImage("next"):"swipeRight"===t.type&&this.showImage("prev")}.bind(this)),a("
",{id:"jBox-image-label-"+t+"-"+i,class:"jBox-image-label"+(o?" active":"")}).html(this.images[t][i].label).on("click tap",function(){a(this).toggleClass("expanded")}).appendTo(this.imageLabelContainer),o&&e.animate({opacity:1},s?0:this.options.imageFade),e}}.bind(this);this.downloadImage=function(t){var i=document.createElement("a");i.href=t,i.setAttribute("download",t.substring(t.lastIndexOf("/")+1)),document.body.appendChild(i),i.click()};var e=function(i,o,t,s){var e=n(i,o,t,s);e.addClass("jBox-image-loading"),a(' ').each(function(){var t=new Image;t.onload=function(){e.removeClass("jBox-image-loading"),e.css({backgroundImage:'url("'+this.images[i][o].src+'")'})}.bind(this),t.onerror=function(){e.removeClass("jBox-image-loading"),e.addClass("jBox-image-not-found")}.bind(this),t.src=this.images[i][o].src}.bind(this))}.bind(this);this.showImage=function(t){var i,o,s;if("open"!=t)i=this.currentImage.gallery,s=(s=this.currentImage.id+(+("prev"==t)?-1:1))>this.images[i].length-1?0:s<0?this.images[i].length-1:s;else{if(this.source)i=this.source.data("jBox-image-gallery"),s=this.source.data("jBox-image-id");else{if(!this.attachedElements||!this.attachedElements.length)return;i=a(this.attachedElements[0]).data("jBox-image-gallery"),s=a(this.attachedElements[0]).data("jBox-image-id")}this.images&&this.images[i]&&a(".jBox-image-pointer-prev, .jBox-image-pointer-next").css({display:1this.images[i].length-1?0:s<0?this.images[i].length-1:s,a("#jBox-image-"+i+"-"+s).length||e(i,s,!1,!1))},this.options.preloadFirstImage&&a(window).on("load",function(){this.showImage("open")}.bind(this))},_onAttach:function(t){this.initImage&&this.initImage(t)},_onCreated:function(){this.imageLabelWrapper=a('
').appendTo(this.wrapper),this.imagePrevButton=a('
').on("click tap",function(){this.showImage("prev")}.bind(this)),this.imageNextButton=a('
').on("click tap",function(){this.showImage("next")}.bind(this)),this.imageLabelContainer=a('
'),this.imageLabelWrapper.append(this.imagePrevButton).append(this.imageLabelContainer).append(this.imageNextButton),this.options.downloadButton&&(this.downloadButton=a("
",{class:"jBox-image-download-button-wrapper"}).appendTo(this.wrapper).append(this.options.downloadButtonText?a("
",{class:"jBox-image-download-button-text"}).html(this.options.downloadButtonText):null).append(a("
",{class:"jBox-image-download-button-icon"})).on("click tap",function(){var t;t=this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl||this.wrapper.find(".jBox-image-"+this.currentImage.gallery+"-current")[0].style.backgroundImage.slice(4,-1).replace(/["']/g,""),this.downloadImage(t)}.bind(this))),this.options.imageCounter&&(this.imageCounter=a("
",{class:"jBox-image-counter-container"}).insertAfter(this.imageLabelContainer),this.imageCounter.append(a(" ",{class:"jBox-image-counter-current"})).append(a(" ").html(this.options.imageCounterSeparator)).append(a(" ",{class:"jBox-image-counter-all"})))},_onOpen:function(){a(document).on("keyup.jBox-Image-"+this.id,function(t){37==t.keyCode&&this.showImage("prev"),39==t.keyCode&&this.showImage("next")}.bind(this)),this.showImage("open")},_onClose:function(){a(document).off("keyup.jBox-Image-"+this.id)},_onCloseComplete:function(){this.wrapper.find(".jBox-image-container").css("opacity",0)}})}function jBoxNoticeWrapper(t,a){new t.plugin("Notice",{color:null,stack:!0,stackSpacing:10,autoClose:6e3,attributes:{x:"right",y:"top"},position:{x:15,y:15},responsivePositions:{500:{x:5,y:5},768:{x:10,y:10}},target:window,fixed:!0,animation:"zoomIn",closeOnClick:"box",zIndex:12e3,_onInit:function(){this.defaultNoticePosition=a.extend({},this.options.position),this._adjustNoticePositon=function(){var t=a(window),o=t.width();t.height();this.options.position=a.extend({},this.defaultNoticePosition),a.each(this.options.responsivePositions,function(t,i){if(o<=t)return this.options.position=i,!1}.bind(this)),this.options.adjustDistance={top:this.options.position.y,right:this.options.position.x,bottom:this.options.position.y,left:this.options.position.x}},this.options.content instanceof a&&(this.options.content=this.options.content.clone().attr("id","")),a(window).on("resize.responsivejBoxNotice-"+this.id,function(t){this.isOpen&&this._adjustNoticePositon()}.bind(this)),this.open()},_onCreated:function(){this.wrapper.addClass("jBox-Notice-color jBox-Notice-"+(this.options.color||"gray")),this.wrapper.data("jBox-Notice-position",this.options.attributes.x+"-"+this.options.attributes.y)},_onOpen:function(){this.options.stack||(this._adjustNoticePositon(),a.each(a(".jBox-Notice"),function(t,i){(i=a(i)).attr("id")!=this.id&&i.data("jBox-Notice-position")==this.options.attributes.x+"-"+this.options.attributes.y&&(this.options.stack||i.data("jBox").close({ignoreDelay:!0}))}.bind(this)))},_onPosition:function(){var t,s={};for(t in a.each(a(".jBox-Notice"),function(t,i){var o=(i=a(i)).data("jBox-Notice-position");s[o]||(s[o]=[]),s[o].push(i)}),s){var i=t.split("-")[1];s[t].reverse();var o,e=0;for(o in s[t]){var n=a(s[t][o]);n.css("margin-"+i,e),e+=n.outerHeight()+this.options.stackSpacing}}},_onCloseComplete:function(){this.destroy(),this.options._onPosition.bind(this).call()}})}!function(i,o){"function"==typeof define&&define.amd?define(["jquery"],function(t){return i.jBox=o(t)}):"object"==typeof module&&module.exports?module.exports=i.jBox=o(require("jquery")):i.jBox=o(i.jQuery)}(this,function(t){var i=jBoxWrapper(t);try{void 0!==jBoxConfirmWrapper&&jBoxConfirmWrapper&&jBoxConfirmWrapper(i,t)}catch(t){console.error(t)}try{void 0!==jBoxImageWrapper&&jBoxImageWrapper&&jBoxImageWrapper(i,t)}catch(t){console.error(t)}try{void 0!==jBoxNoticeWrapper&&jBoxNoticeWrapper&&jBoxNoticeWrapper(i,t)}catch(t){console.error(t)}return i});
\ No newline at end of file
diff --git a/Source/jBox.css b/dist/jBox.css
old mode 100644
new mode 100755
similarity index 58%
rename from Source/jBox.css
rename to dist/jBox.css
index 35bd045..d3c1d23
--- a/Source/jBox.css
+++ b/dist/jBox.css
@@ -1,6 +1,3 @@
-
-/* Global */
-
.jBox-wrapper {
text-align: left;
box-sizing: border-box;
@@ -19,18 +16,20 @@
}
.jBox-content {
- padding: 8px 10px;
+ padding: 8px 12px;
overflow-x: hidden;
overflow-y: auto;
transition: opacity .2s;
}
-/* jBox Tooltip */
+.jBox-footer {
+ box-sizing: border-box;
+}
.jBox-Tooltip .jBox-container,
.jBox-Mouse .jBox-container {
- border-radius: 3px;
- box-shadow: 0 0 3px rgba(0, 0, 0, .25);
+ border-radius: 4px;
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
}
.jBox-Tooltip .jBox-title,
@@ -39,8 +38,8 @@
font-weight: bold;
}
-.jBox-hasTitle.jBox-Tooltip .jBox-content,
-.jBox-hasTitle.jBox-Mouse .jBox-content {
+.jBox-Tooltip.jBox-hasTitle .jBox-content,
+.jBox-Mouse.jBox-hasTitle .jBox-content {
padding-top: 5px;
}
@@ -48,28 +47,10 @@
pointer-events: none;
}
-/* Pointer */
-
.jBox-pointer {
position: absolute;
overflow: hidden;
-}
-
-.jBox-pointer-top { top: 0; }
-.jBox-pointer-bottom { bottom: 0; }
-.jBox-pointer-left { left: 0; }
-.jBox-pointer-right { right: 0; }
-
-.jBox-pointer-top,
-.jBox-pointer-bottom {
- width: 30px;
- height: 12px;
-}
-
-.jBox-pointer-left,
-.jBox-pointer-right {
- width: 12px;
- height: 30px;
+ box-sizing: border-box;
}
.jBox-pointer:after {
@@ -79,38 +60,67 @@
position: absolute;
background: #fff;
transform: rotate(45deg);
+ box-sizing: border-box;
+}
+
+.jBox-pointer-top {
+ top: 0;
}
.jBox-pointer-top:after {
left: 5px;
top: 6px;
- box-shadow: -1px -1px 2px rgba(0, 0, 0, .15);
+ box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-right {
+ right: 0;
}
.jBox-pointer-right:after {
top: 5px;
right: 6px;
- box-shadow: 1px -1px 2px rgba(0, 0, 0, .15);
+ box-shadow: 1px -1px 2px rgba(0, 0, 0, 0.15);
}
-.jBox-pointer-bottom:after {
- left: 5px;
- bottom: 6px;
- box-shadow: 1px 1px 2px rgba(0, 0, 0, .15);
+.jBox-pointer-left {
+ left: 0;
}
.jBox-pointer-left:after {
top: 5px;
left: 6px;
- box-shadow: -1px 1px 2px rgba(0, 0, 0, .15);
+ box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-bottom {
+ bottom: 0;
}
-/* jBox Modal */
+.jBox-pointer-bottom:after {
+ left: 5px;
+ bottom: 6px;
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15);
+}
+
+.jBox-pointer-top, .jBox-pointer-bottom {
+ width: 30px;
+ height: 12px;
+}
+
+.jBox-pointer-left, .jBox-pointer-right {
+ width: 12px;
+ height: 30px;
+}
.jBox-Modal .jBox-container {
border-radius: 4px;
}
+.jBox-Modal .jBox-container, .jBox-Modal.jBox-closeButton-box:before {
+ box-shadow: 0 3px 15px rgba(0, 0, 0, 0.4), 0 0 5px rgba(0, 0, 0, 0.4);
+}
+
.jBox-Modal .jBox-content {
padding: 15px 20px;
}
@@ -122,24 +132,19 @@
border-bottom: 1px solid #eee;
}
-.jBox-Modal .jBox-footer {
- border-radius: 0 0 4px 4px;
-}
-
.jBox-Modal.jBox-closeButton-title .jBox-title {
- padding-right: 55px;
+ padding-right: 65px;
}
-.jBox-Modal .jBox-container,
-.jBox-Modal.jBox-closeButton-box:before {
- box-shadow: 0 3px 15px rgba(0, 0, 0, .4), 0 0 5px rgba(0, 0, 0, .4);
+.jBox-Modal .jBox-footer {
+ border-radius: 0 0 4px 4px;
}
-/* Close button */
-
.jBox-closeButton {
+ z-index: 1;
cursor: pointer;
position: absolute;
+ box-sizing: border-box;
}
.jBox-closeButton svg {
@@ -148,24 +153,15 @@
right: 50%;
}
-.jBox-closeButton path {
- transition: fill .2s;
-}
-
.jBox-closeButton path {
fill: #aaa;
+ transition: fill .2s;
}
.jBox-closeButton:hover path {
fill: #888;
}
-.jBox-closeButton:active path {
- fill: #666;
-}
-
-/* Close button in overlay */
-
.jBox-overlay .jBox-closeButton {
top: 0;
right: 0;
@@ -180,8 +176,7 @@
margin-right: -10px;
}
-.jBox-overlay .jBox-closeButton path,
-.jBox-overlay .jBox-closeButton:active path {
+.jBox-overlay .jBox-closeButton path {
fill: #ddd;
}
@@ -189,23 +184,23 @@
fill: #fff;
}
-/* Close button in title */
-
.jBox-closeButton-title .jBox-closeButton {
top: 0;
right: 0;
bottom: 0;
- width: 40px;
+ width: 50px;
}
-.jBox-closeButton-title .jBox-closeButton svg {
+.jBox-closeButton-title svg {
width: 12px;
height: 12px;
margin-top: -6px;
margin-right: -6px;
}
-/* Close button in box */
+.jBox-closeButton-box {
+ box-sizing: border-box;
+}
.jBox-closeButton-box .jBox-closeButton {
top: -8px;
@@ -223,10 +218,6 @@
margin-right: -5px;
}
-.jBox-hasTitle.jBox-Modal.jBox-closeButton-box .jBox-closeButton {
- background: #fafafa;
-}
-
.jBox-closeButton-box:before {
content: '';
position: absolute;
@@ -235,18 +226,20 @@
width: 24px;
height: 24px;
border-radius: 50%;
- box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
-.jBox-pointerPosition-top.jBox-closeButton-box:before {
+.jBox-closeButton-box.jBox-pointerPosition-top:before {
top: 5px;
}
-.jBox-pointerPosition-right.jBox-closeButton-box:before {
+.jBox-closeButton-box.jBox-pointerPosition-right:before {
right: 2px;
}
-/* Overlay */
+.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton {
+ background: #fafafa;
+}
.jBox-overlay {
position: fixed;
@@ -254,11 +247,9 @@
left: 0;
width: 100%;
height: 100%;
- background-color: rgba(0, 0, 0, .82);
+ background-color: rgba(0, 0, 0, 0.82);
}
-/* Footer */
-
.jBox-footer {
background: #fafafa;
border-top: 1px solid #eee;
@@ -266,23 +257,19 @@
border-radius: 0 0 3px 3px;
}
-/* Block scrolling */
-
body[class^="jBox-blockScroll-"],
body[class*=" jBox-blockScroll-"] {
overflow: hidden;
}
-/* Draggable */
-
.jBox-draggable {
cursor: move;
}
-/* Spinner */
-
@keyframes jBoxLoading {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
.jBox-loading .jBox-content {
@@ -313,12 +300,32 @@ body[class*=" jBox-blockScroll-"] {
width: 24px;
height: 24px;
border-radius: 50%;
- border: 2px solid rgba(0, 0, 0, .2);
- border-top-color: rgba(0, 0, 0, .8);
+ border: 2px solid rgba(0, 0, 0, 0.2);
+ border-top-color: rgba(0, 0, 0, 0.8);
animation: jBoxLoading .6s linear infinite;
}
-/* Animations */
+.jBox-countdown {
+ border-radius: 4px 4px 0 0;
+ z-index: 0;
+ background: #000;
+ opacity: .2;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ overflow: hidden;
+}
+
+.jBox-countdown-inner {
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 3px;
+ position: absolute;
+ background: #fff;
+}
[class^="jBox-animated-"],
[class*=" jBox-animated-"] {
@@ -326,11 +333,27 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-tada {
- 0% {transform: scale(1);}
- 10%, 20% {transform: scale(0.8) rotate(-4deg);}
- 30%, 50%, 70%, 90% {transform: scale(1.2) rotate(4deg);}
- 40%, 60%, 80% {transform: scale(1.2) rotate(-4deg);}
- 100% {transform: scale(1) rotate(0);}
+ 0% {
+ transform: scale(1);
+ }
+ 10%,
+ 20% {
+ transform: scale(0.8) rotate(-4deg);
+ }
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: scale(1.2) rotate(4deg);
+ }
+ 40%,
+ 60%,
+ 80% {
+ transform: scale(1.2) rotate(-4deg);
+ }
+ 100% {
+ transform: scale(1) rotate(0);
+ }
}
.jBox-animated-tada {
@@ -338,11 +361,27 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-tadaSmall {
- 0% {transform: scale(1);}
- 10%, 20% {transform: scale(0.9) rotate(-2deg);}
- 30%, 50%, 70%, 90% {transform: scale(1.1) rotate(2deg);}
- 40%, 60%, 80% {transform: scale(1.1) rotate(-2deg);}
- 100% {transform: scale(1) rotate(0);}
+ 0% {
+ transform: scale(1);
+ }
+ 10%,
+ 20% {
+ transform: scale(0.9) rotate(-2deg);
+ }
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: scale(1.1) rotate(2deg);
+ }
+ 40%,
+ 60%,
+ 80% {
+ transform: scale(1.1) rotate(-2deg);
+ }
+ 100% {
+ transform: scale(1) rotate(0);
+ }
}
.jBox-animated-tadaSmall {
@@ -350,8 +389,15 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-flash {
- 0%, 50%, 100% {opacity: 1;}
- 25%, 75% {opacity: 0;}
+ 0%,
+ 50%,
+ 100% {
+ opacity: 1;
+ }
+ 25%,
+ 75% {
+ opacity: 0;
+ }
}
.jBox-animated-flash {
@@ -359,9 +405,18 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-shake {
- 0%, 100% {transform: translateX(0);}
- 20%, 60% {transform: translateX(-6px);}
- 40%, 80% {transform: translateX(6px);}
+ 0%,
+ 100% {
+ transform: translateX(0);
+ }
+ 20%,
+ 60% {
+ transform: translateX(-6px);
+ }
+ 40%,
+ 80% {
+ transform: translateX(6px);
+ }
}
.jBox-animated-shake {
@@ -369,9 +424,15 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-pulseUp {
- 0% {transform: scale(1);}
- 50% {transform: scale(1.15);}
- 100% {transform: scale(1);}
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.15);
+ }
+ 100% {
+ transform: scale(1);
+ }
}
.jBox-animated-pulseUp {
@@ -379,9 +440,15 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-pulseDown {
- 0% {transform: scale(1);}
- 50% {transform: scale(0.85);}
- 100% {transform: scale(1);}
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(0.85);
+ }
+ 100% {
+ transform: scale(1);
+ }
}
.jBox-animated-pulseDown {
@@ -389,9 +456,15 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-popIn {
- 0% {transform: scale(0);}
- 50% {transform: scale(1.1);}
- 100% {transform: scale(1);}
+ 0% {
+ transform: scale(0);
+ }
+ 50% {
+ transform: scale(1.1);
+ }
+ 100% {
+ transform: scale(1);
+ }
}
.jBox-animated-popIn {
@@ -399,9 +472,15 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-popOut {
- 0% {transform: scale(1);}
- 50% {transform: scale(1.1);}
- 100% {transform: scale(0);}
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.1);
+ }
+ 100% {
+ transform: scale(0);
+ }
}
.jBox-animated-popOut {
@@ -409,8 +488,12 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-fadeIn {
- 0% {opacity: 0;}
- 100% {opacity: 1;}
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
}
.jBox-animated-fadeIn {
@@ -418,8 +501,12 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-fadeOut {
- 0% {opacity: 1;}
- 100% {opacity: 0;}
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
}
.jBox-animated-fadeOut {
@@ -427,8 +514,13 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-slideUp {
- 0% {transform: translateY(0);}
- 100% {transform: translateY(-300px); opacity: 0;}
+ 0% {
+ transform: translateY(0);
+ }
+ 100% {
+ transform: translateY(-300px);
+ opacity: 0;
+ }
}
.jBox-animated-slideUp {
@@ -436,8 +528,13 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-slideRight {
- 0% {transform: translateX(0);}
- 100% {transform: translateX(300px); opacity: 0;}
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(300px);
+ opacity: 0;
+ }
}
.jBox-animated-slideRight {
@@ -445,8 +542,13 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-slideDown {
- 0% {transform: translateY(0);}
- 100% {transform: translateY(300px); opacity: 0;}
+ 0% {
+ transform: translateY(0);
+ }
+ 100% {
+ transform: translateY(300px);
+ opacity: 0;
+ }
}
.jBox-animated-slideDown {
@@ -454,10 +556,17 @@ body[class*=" jBox-blockScroll-"] {
}
@keyframes jBox-slideLeft {
- 0% {transform: translateX(0);}
- 100% {transform: translateX(-300px); opacity: 0;}
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(-300px);
+ opacity: 0;
+ }
}
.jBox-animated-slideLeft {
animation: jBox-slideLeft .4s;
}
+
+/*# sourceMappingURL=jBox.css.map */
diff --git a/dist/jBox.js b/dist/jBox.js
new file mode 100755
index 0000000..8fec5f3
--- /dev/null
+++ b/dist/jBox.js
@@ -0,0 +1,2328 @@
+/**
+ * jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jQuery 3.5.0 (https://code.jquery.com/jquery-3.5.0.min.js)
+ *
+ * Documentation: https://stephanwagner.me/jBox/documentation
+ *
+ * Demos: https://stephanwagner.me/jBox/demos
+ */
+
+function jBoxWrapper(jQuery) {
+
+
+ var jBox = function jBox(type, options) {
+
+
+ // Options (https://stephanwagner.me/jBox/options)
+
+ this.options = {
+
+ // jBox ID
+ id: null, // Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...)
+
+ // Dimensions
+ width: 'auto', // The width of the content area, e.g. 'auto', 200, '80%'
+ height: 'auto', // The height of the content area
+ minWidth: null, // Minimal width
+ minHeight: null, // Minimal height
+ maxWidth: null, // Maximal width
+ maxHeight: null, // Maximal height
+
+ // Responsive dimensions
+ responsiveWidth: true, // Adjusts the width to fit the viewport
+ responsiveHeight: true, // Adjusts the height to fit the viewport
+ responsiveMinWidth: 100, // Don't adjust width below this value (in pixel)
+ responsiveMinHeight: 100, // Don't adjust height below this value (in pixel)
+
+ // Attach
+ attach: null, // A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip'
+ trigger: 'click', // The event to open or close your jBox, use 'click', 'touchclick' or 'mouseenter'
+ preventDefault: false, // Prevent the default event when opening jBox, e.g. don't follow the href in a link
+
+ // Content
+ content: null, // You can use HTML or a jQuery element, e.g. jQuery('#jBox-content'). The elements will be appended to the content element and then made visible, so hide them with style="display: none" beforehand
+ getContent: null, // Get the content from an attribute when jBox opens, e.g. getContent: 'data-content'. Use 'html' to get the attached elements HTML as content
+ title: null, // Adds a title to your jBox
+ getTitle: null, // Get the title from an attribute when jBox opens, e.g. getTitle: 'data-title'
+ footer: null, // Adds a footer to your jBox
+ isolateScroll: true, // Isolates scrolling to the content container
+
+ // AJAX
+ ajax: { // Setting an URL will make an AJAX request when jBox opens. Optional you can add any jQuery AJAX option (http://api.jquery.com/jquery.ajax/)
+ url: null, // The URL to send the AJAX request to
+ data: '', // Data to send with your AJAX request, e.g. {id: 82, limit: 10}
+ reload: false, // Resend the AJAX request when jBox opens. Use true to send the AJAX request only once for every attached element or 'strict' to resend every time jBox opens
+ getURL: 'data-url', // The attribute in the source element where the AJAX request will look for the URL, e.g. data-url="https://reqres.in/api/users"
+ getData: 'data-ajax', // The attribute in the source element where the AJAX request will look for the data, e.g. data-ajax="id=82&limit=10"
+ setContent: true, // Automatically set the response as new content when the AJAX request is finished
+ loadingClass: true, // Add a class to the wrapper when jBox is loading, set to class name or true to use the default class name 'jBox-loading'
+ spinner: true, // Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '
'
+ spinnerDelay: 300, // Milliseconds to wait until spinner appears
+ spinnerReposition: true // Repositions jBox when the spinner is added or removed
+ },
+ cancelAjaxOnClose: true, // Cancels the ajax call when jBox closes and it hasn't finished loading yet
+
+ // Position
+ target: null, // The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target
+ position: {
+ x: 'center', // Horizontal position, use a number, 'left', 'right' or 'center'
+ y: 'center' // Vertical position, use a number, 'top', 'bottom' or 'center'
+ },
+ outside: null, // Use 'x', 'y', or 'xy' to move your jBox outside of the target element
+ offset: 0, // Offset to final position, you can set different values for x and y with an object, e.g. {x: 20, y: 10}
+ attributes: { // Note that attributes can only be 'left' or 'right' when using numbers for position, e.g. {x: 300, y: 20}
+ x: 'left', // Horizontal position, use 'left' or 'right'
+ y: 'top' // Vertical position, use 'top' or 'bottom'
+ },
+ fixed: false, // Your jBox will stay on position when scrolling
+ adjustPosition: true, // Adjusts your jBoxes position if there is not enough space, use 'flip', 'move' or true for both. This option overrides the reposition options
+ adjustTracker: false, // By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling
+ adjustDistance: 5, // The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5}
+ reposition: true, // Calculates new position when the window-size changes
+ repositionOnOpen: true, // Calculates new position each time jBox opens (rather than only when it opens the first time)
+ repositionOnContent: true, // Calculates new position when the content changes with .setContent() or .setTitle()
+ holdPosition: true, // Keeps current position if space permits. Applies only to 'Modal' type.
+
+ // Pointer
+ pointer: false, // Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20'
+ pointTo: 'target', // Setting something else than 'target' will add a pointer even if there is no target element set or found. Use 'top', 'right', 'bottom' or 'left'
+
+ // Animations
+ fade: 180, // Fade duration in ms, set to 0 or false to disable
+ animation: null, // Animation when opening or closing, use 'pulse', 'zoomIn', 'zoomOut', 'move', 'slide', 'flip', 'tada' (CSS inspired from Daniel Edens Animate.css: http://daneden.me/animate)
+
+ // Appearance
+ theme: 'Default', // Set a jBox theme class
+ addClass: null, // Adds classes to the wrapper
+ overlay: false, // Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS)
+ overlayClass: null, // Add a class name to the overlay
+ zIndex: 10000, // Use a high z-index, or set to 'auto' to bring to front on open
+
+ // Delays
+ delayOpen: 0, // Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing
+ delayClose: 0, // Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away
+
+ // Closing
+ closeOnEsc: false, // Close jBox when pressing [esc] key
+ closeOnClick: false, // Close jBox with mouseclick. Use true (click anywhere), 'box' (click on jBox itself), 'overlay' (click on the overlay), 'body' (click anywhere but jBox)
+ closeOnMouseleave: false, // Close jBox when the mouse leaves the jBox area or the area of the attached element
+ closeButton: false, // Adds a close button to your jBox. Use 'title', 'box', 'overlay' or true (true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found)
+
+ // Other options
+ appendTo: jQuery('body'), // The element your jBox will be appended to. Any other element than jQuery('body') is only useful for fixed positions or when position values are numbers
+ createOnInit: false, // Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time
+ blockScroll: false, // Blocks scrolling when jBox is open
+ blockScrollAdjust: true, // Adjust page elements to avoid content jumps when scrolling is blocked. See more here: https://github.com/StephanWagner/unscroll
+ draggable: false, // Make your jBox draggable (use 'true', 'title' or provide an element as handle) (inspired from Chris Coyiers CSS-Tricks http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/)
+ dragOver: true, // When you have multiple draggable jBoxes, the one you select will always move over the other ones
+ autoClose: false, // Time in ms when jBox will close automatically after it was opened
+ delayOnHover: false, // Delay auto-closing while mouse is hovered
+ showCountdown: false, // Display a nice progress-indicator when autoClose is enabled
+
+ // Audio // You can use the integrated audio function whenever you'd like to play an audio file, e.g. onInit: function () { this.audio('url_to_audio_file_without_file_extension', 75); }
+ preloadAudio: true, // Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg']
+ audio: null, // The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'}
+ volume: 100, // The volume in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100}
+
+ // Events // Note that you can use 'this' in all event functions, it refers to your jBox object (e.g. onInit: function () { this.open(); })
+ onInit: null, // Fired when jBox is initialized
+ onAttach: null, // Fired when jBox attached itself to elements, the attached element will be passed as a parameter, e.g. onAttach: function (element) { element.css({color: 'red'}); }
+ onPosition: null, // Fired when jBox is positioned
+ onCreated: null, // Fired when jBox is created and availible in DOM
+ onOpen: null, // Fired when jBox opens
+ onOpenComplete: null, // Fired when jBox is completely open (when fading is finished)
+ onClose: null, // Fired when jBox closes
+ onCloseComplete: null, // Fired when jBox is completely closed (when fading is finished)
+ onDragStart: null, // Fired when dragging starts
+ onDragEnd: null // Fired when dragging finished
+ };
+
+
+ // Default plugin options
+
+ this._pluginOptions = {
+
+ // Default options for tooltips
+ 'Tooltip': {
+ getContent: 'title',
+ trigger: 'mouseenter',
+ position: {
+ x: 'center',
+ y: 'top'
+ },
+ outside: 'y',
+ pointer: true
+ },
+
+ // Default options for mouse tooltips
+ 'Mouse': {
+ responsiveWidth: false,
+ responsiveHeight: false,
+ adjustPosition: 'flip',
+ target: 'mouse',
+ trigger: 'mouseenter',
+ position: {
+ x: 'right',
+ y: 'bottom'
+ },
+ outside: 'xy',
+ offset: 5
+ },
+
+ // Default options for modal windows
+ 'Modal': {
+ target: jQuery(window),
+ fixed: true,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: 'overlay',
+ closeButton: true,
+ overlay: true,
+ animation: 'zoomIn'
+ },
+ };
+
+
+ // Merge options
+
+ this.options = jQuery.extend(true, this.options, this._pluginOptions[type] ? this._pluginOptions[type] : jBox._pluginOptions[type], options);
+
+
+ // Set the jBox type
+
+ jQuery.type(type) == 'string' && (this.type = type);
+
+
+ // Checks if the user is on a touch device, borrowed from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
+
+ this.isTouchDevice = (function () {
+ var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
+ var mq = function (query) {
+ return window.matchMedia(query).matches;
+ }
+
+ if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
+ return true;
+ }
+
+ var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
+ return mq(query);
+ })();
+
+
+ // Add close event for body click when we are on touch device and jBox triggers on mouseenter
+
+ if (this.isTouchDevice && this.options.trigger === 'mouseenter' && this.options.closeOnClick === false) {
+ this.options.closeOnClick = 'body';
+ }
+
+
+ // Local function to fire events
+
+ this._fireEvent = function (event, pass)
+ {
+ this.options['_' + event] && (this.options['_' + event].bind(this))(pass);
+ this.options[event] && (this.options[event].bind(this))(pass);
+ };
+
+
+ // Get a unique jBox ID
+
+ this.options.id === null && (this.options.id = 'jBox' + jBox._getUniqueID());
+ this.id = this.options.id;
+
+
+ // Correct impossible options
+
+ ((this.options.position.x == 'center' && this.options.outside == 'x') || (this.options.position.y == 'center' && this.options.outside == 'y')) && (this.options.outside = null);
+ this.options.pointTo == 'target' && (!this.options.outside || this.options.outside == 'xy') && (this.options.pointer = false);
+
+
+ // Correct multiple choice options
+
+ jQuery.type(this.options.offset) != 'object' ? (this.options.offset = {x: this.options.offset, y: this.options.offset}) : (this.options.offset = jQuery.extend({x: 0, y: 0}, this.options.offset));
+ jQuery.type(this.options.adjustDistance) != 'object' ? (this.options.adjustDistance = {top: this.options.adjustDistance, right: this.options.adjustDistance, bottom: this.options.adjustDistance, left: this.options.adjustDistance}) : (this.options.adjustDistance = jQuery.extend({top: 5, left: 5, right: 5, bottom: 5}, this.options.adjustDistance));
+
+
+ // Save default outside position
+
+ this.outside = this.options.outside && this.options.outside != 'xy' ? this.options.position[this.options.outside] : false;
+
+
+ // Save where the jBox is aligned to
+
+ this.align = this.outside ? this.outside : (this.options.position.y != 'center' && jQuery.type(this.options.position.y) != 'number' ? this.options.position.x : (this.options.position.x != 'center' && jQuery.type(this.options.position.x) != 'number' ? this.options.position.y : this.options.attributes.x));
+
+
+ // Adjust option zIndex
+
+ jBox.zIndexMax = Math.max(jBox.zIndexMax || 0, this.options.zIndex === 'auto' ? 10000 : this.options.zIndex);
+ if (this.options.zIndex === 'auto') {
+ this.adjustZIndexOnOpen = true;
+ jBox.zIndexMax += 2;
+ this.options.zIndex = jBox.zIndexMax;
+ this.trueModal = this.options.overlay;
+ }
+
+ // Internal positioning functions
+
+ this._getOpp = function (opp) { return {left: 'right', right: 'left', top: 'bottom', bottom: 'top', x: 'y', y: 'x'}[opp]; };
+ this._getXY = function (xy) { return {left: 'x', right: 'x', top: 'y', bottom: 'y', center: 'x'}[xy]; };
+ this._getTL = function (tl) { return {left: 'left', right: 'left', top: 'top', bottom: 'top', center: 'left', x: 'left', y: 'top'}[tl]; };
+
+
+ // Get a dimension value in integer pixel dependent on appended element
+
+ this._getInt = function (value, dimension) {
+ if (value == 'auto') return 'auto';
+ if (value && jQuery.type(value) == 'string' && value.slice(-1) == '%') {
+ return jQuery(window)[dimension == 'height' ? 'innerHeight' : 'innerWidth']() * parseInt(value.replace('%', '')) / 100;
+ }
+ return value;
+ };
+
+
+ // Create an svg element
+
+ this._createSVG = function (type, options)
+ {
+ var svg = document.createElementNS('http://www.w3.org/2000/svg', type);
+ jQuery.each(options, function (index, item) {
+ svg.setAttribute(item[0], (item[1] || ''));
+ });
+ return svg;
+ };
+
+
+ // Isolate scrolling in a container
+
+ this._isolateScroll = function (el)
+ {
+ // Abort if element not found
+ if (!el || !el.length) return;
+
+ el.on('DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll', function (ev) {
+ var delta = ev.wheelDelta || (ev.originalEvent && ev.originalEvent.wheelDelta) || -ev.detail;
+ var overflowBottom = this.scrollTop + el.outerHeight() - this.scrollHeight >= 0;
+ var overflowTop = this.scrollTop <= 0;
+ ((delta < 0 && overflowBottom) || (delta > 0 && overflowTop)) && ev.preventDefault();
+ });
+ };
+
+
+ // Set the title width to content width
+
+ this._setTitleWidth = function ()
+ {
+ // Abort if there is no title or width of content is auto
+ if (!this.titleContainer || (this.content[0].style.width == 'auto' && !this.content[0].style.maxWidth)) return null;
+
+ // Expose wrapper to get actual width
+ if (this.wrapper.css('display') == 'none') {
+ this.wrapper.css('display', 'block');
+ var contentWidth = this.content.outerWidth();
+ this.wrapper.css('display', 'none');
+ } else {
+ var contentWidth = this.content.outerWidth();
+ }
+
+ // Set max-width only
+ this.titleContainer.css({maxWidth: (Math.max(contentWidth, parseInt(this.content[0].style.maxWidth)) || null)});
+ }
+
+
+ // Make jBox draggable
+
+ this._draggable = function ()
+ {
+ // Abort if jBox is not draggable
+ if (!this.options.draggable) return false;
+
+ // Get the handle where jBox will be dragged with
+ var handle = this.options.draggable == 'title' ? this.titleContainer : (this.options.draggable instanceof jQuery ? this.options.draggable : (jQuery.type(this.options.draggable) == 'string' ? jQuery(this.options.draggable) : this.wrapper));
+
+ // Abort if no handle or if draggable was set already
+ if (!handle || !(handle instanceof jQuery) || !handle.length || handle.data('jBox-draggable')) {
+ return false;
+ }
+
+ // Add mouse events
+ handle.addClass('jBox-draggable').data('jBox-draggable', true).on('touchstart mousedown', function (ev)
+ {
+ if (ev.button == 2 || jQuery(ev.target).hasClass('jBox-noDrag') || jQuery(ev.target).parents('.jBox-noDrag').length) {
+ // Hacky fix for jBox not closing on mobile devices when using draggable
+ if (ev.type == 'touchstart' && (jQuery(ev.target).hasClass('jBox-closeButton') || jQuery(ev.target).parents('.jBox-closeButton').length)) {
+ this.close({ignoreDelay: true});
+ }
+ return;
+ }
+
+ var pageX;
+ var pageY;
+
+ if (ev.type == 'touchstart' && ev.touches && ev.touches[0]) {
+ pageX = ev.touches[0].pageX;
+ pageY = ev.touches[0].pageY;
+ } else {
+ pageX = ev.pageX;
+ pageY = ev.pageY;
+ }
+
+ // Store current mouse position
+ this.draggingStartX = pageX;
+ this.draggingStartY = pageY;
+
+ // Adjust z-index when dragging jBox over another draggable jBox
+ if (this.options.dragOver && !this.trueModal && parseInt(this.wrapper.css('zIndex'), 10) <= jBox.zIndexMaxDragover) {
+ jBox.zIndexMaxDragover += 1;
+ this.wrapper.css('zIndex', jBox.zIndexMaxDragover);
+ }
+
+ var drg_h = this.wrapper.outerHeight();
+ var drg_w = this.wrapper.outerWidth();
+ var pos_y = this.wrapper.offset().top + drg_h - pageY;
+ var pos_x = this.wrapper.offset().left + drg_w - pageX;
+
+ jQuery(document).on('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id, function (ev) {
+
+ var movingPageX;
+ var movingPageY;
+
+ if (ev.type == 'touchmove' && ev.touches && ev.touches[0]) {
+ movingPageX = ev.touches[0].pageX;
+ movingPageY = ev.touches[0].pageY;
+ } else {
+ movingPageX = ev.pageX;
+ movingPageY = ev.pageY;
+ }
+
+ // Fire onDragStart event when jBox moves
+ if (!this.dragging && this.draggingStartX != movingPageX && this.draggingStartY != movingPageY) {
+ this._fireEvent('onDragStart');
+ this.dragging = true;
+ }
+
+ // Adjust position
+ this.wrapper.offset({
+ top: movingPageY + pos_y - drg_h,
+ left: movingPageX + pos_x - drg_w
+ });
+ }.bind(this));
+ ev.preventDefault();
+
+ }.bind(this)).on('touchend mouseup', function () {
+ // Remove drag event
+ jQuery(document).off('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id);
+
+ // Fire onDragEnd event
+ this.dragging && this._fireEvent('onDragEnd');
+
+ // Reset dragging reference
+ this.dragging = false;
+
+ if ((this.type == 'Modal' || this.type == 'Confirm') && this.options.holdPosition) {
+ // Drag end captures new position
+ var jBoxOffset = jQuery('#' + this.id).offset(),
+ pos = {
+ x: jBoxOffset.left - jQuery(document).scrollLeft(),
+ y: jBoxOffset.top - jQuery(document).scrollTop()
+ };
+ this.position({position: pos, offset: {x: 0, y: 0}});
+ }
+ }.bind(this));
+
+ // Get highest z-index
+ if (!this.trueModal) {
+ jBox.zIndexMaxDragover = !jBox.zIndexMaxDragover ? this.options.zIndex : Math.max(jBox.zIndexMaxDragover, this.options.zIndex);
+ }
+
+ return this;
+ };
+
+ // Create jBox
+
+ this._create = function ()
+ {
+ // Abort if jBox was created already
+ if (this.wrapper) return;
+
+ // Create wrapper
+ this.wrapper = jQuery('
', {
+ id: this.id,
+ 'class': 'jBox-wrapper' + (this.type ? ' jBox-' + this.type : '') + (this.options.theme ? ' jBox-' + this.options.theme : '') + (this.options.addClass ? ' ' + this.options.addClass : '')
+ }).css({
+ position: (this.options.fixed ? 'fixed' : 'absolute'),
+ display: 'none',
+ opacity: 0,
+ zIndex: this.options.zIndex
+
+ // Save the jBox instance in the wrapper, so you can get access to your jBox when you only have the element
+ }).data('jBox', this);
+
+ // Add mouseleave event, only close jBox when the new target is not the source element
+ this.options.closeOnMouseleave && this.wrapper.on('mouseleave', function (ev) {
+ !this.source || !(ev.relatedTarget == this.source[0] || jQuery.inArray(this.source[0], jQuery(ev.relatedTarget).parents('*')) !== -1) && this.close();
+ }.bind(this));
+
+ // Add closeOnClick: 'box' events
+ (this.options.closeOnClick == 'box') && this.wrapper.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
+
+ // Create container
+ this.container = jQuery('
').appendTo(this.wrapper);
+
+ // Create content
+ this.content = jQuery('
').appendTo(this.container);
+
+ // Create footer
+ this.options.footer && (this.footer = jQuery('').append(this.options.footer).appendTo(this.container));
+
+ // Isolate scrolling
+ this.options.isolateScroll && this._isolateScroll(this.content);
+
+ // Create close button
+ if (this.options.closeButton) {
+ var closeButtonSVG = this._createSVG('svg', [['viewBox', '0 0 24 24']]);
+ closeButtonSVG.appendChild(this._createSVG('path', [['d', 'M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z']]));
+ this.closeButton = jQuery('
').on('click tap', function (ev) { this.close({ignoreDelay: true}); }.bind(this)).append(closeButtonSVG);
+
+ // Add close button to jBox container
+ if (this.options.closeButton == 'box' || (this.options.closeButton === true && !this.options.overlay && !this.options.title && !this.options.getTitle)) {
+ this.wrapper.addClass('jBox-closeButton-box');
+ this.closeButton.appendTo(this.container);
+ }
+ }
+
+ // Append jBox to DOM
+ this.wrapper.appendTo(this.options.appendTo);
+
+ // Fix adjustDistance if there is a close button in the box
+ this.wrapper.find('.jBox-closeButton').length && jQuery.each(['top', 'right', 'bottom', 'left'], function (index, pos) {
+ this.wrapper.find('.jBox-closeButton').css(pos) && this.wrapper.find('.jBox-closeButton').css(pos) != 'auto' && (this.options.adjustDistance[pos] = Math.max(this.options.adjustDistance[pos], this.options.adjustDistance[pos] + (((parseInt(this.wrapper.find('.jBox-closeButton').css(pos)) || 0) + (parseInt(this.container.css('border-' + pos + '-width')) || 0)) * -1)));
+ }.bind(this));
+
+ // Create pointer
+ if (this.options.pointer) {
+
+ // Get pointer vars and save globally
+ this.pointer = {
+ position: (this.options.pointTo != 'target') ? this.options.pointTo : this._getOpp(this.outside),
+ xy: (this.options.pointTo != 'target') ? this._getXY(this.options.pointTo) : this._getXY(this.outside),
+ align: 'center',
+ offset: 0
+ };
+
+ this.pointer.element = jQuery('
').appendTo(this.wrapper);
+ this.pointer.dimensions = {
+ x: this.pointer.element.outerWidth(),
+ y: this.pointer.element.outerHeight()
+ };
+
+ if (jQuery.type(this.options.pointer) == 'string') {
+ var split = this.options.pointer.split(':');
+ split[0] && (this.pointer.align = split[0]);
+ split[1] && (this.pointer.offset = parseInt(split[1]));
+ }
+ this.pointer.alignAttribute = (this.pointer.xy == 'x' ? (this.pointer.align == 'bottom' ? 'bottom' : 'top') : (this.pointer.align == 'right' ? 'right' : 'left'));
+
+ // Set wrapper CSS
+ this.wrapper.css('padding-' + this.pointer.position, this.pointer.dimensions[this.pointer.xy]);
+
+ // Set pointer CSS
+ this.pointer.element.css(this.pointer.alignAttribute, (this.pointer.align == 'center' ? '50%' : 0)).css('margin-' + this.pointer.alignAttribute, this.pointer.offset);
+ this.pointer.margin = {};
+ this.pointer.margin['margin-' + this.pointer.alignAttribute] = this.pointer.offset;
+
+ // Add a transform to fix centered position
+ (this.pointer.align == 'center') && this.pointer.element.css('transform', 'translate(' + (this.pointer.xy == 'y' ? (this.pointer.dimensions.x * -0.5 + 'px') : 0) + ', ' + (this.pointer.xy == 'x' ? (this.pointer.dimensions.y * -0.5 + 'px') : 0) + ')');
+
+ this.pointer.element.css((this.pointer.xy == 'x' ? 'width' : 'height'), parseInt(this.pointer.dimensions[this.pointer.xy]) + parseInt(this.container.css('border-' + this.pointer.alignAttribute + '-width')));
+
+ // Add class to wrapper for CSS access
+ this.wrapper.addClass('jBox-pointerPosition-' + this.pointer.position);
+ }
+
+ // Set title and content
+ this.setContent(this.options.content, true);
+ this.setTitle(this.options.title, true);
+
+ this.options.draggable && this._draggable();
+
+ // Fire onCreated event
+ this._fireEvent('onCreated');
+ };
+
+
+ // Create jBox onInit
+
+ this.options.createOnInit && this._create();
+
+
+ // Attach jBox
+
+ this.options.attach && this.attach();
+
+
+ // Attach document and window events
+
+ this._attachEvents = function ()
+ {
+ // Cancel countdown on mouseenter if delayOnHover
+ this.options.delayOnHover && jQuery('#' + this.id).on('mouseenter', function (ev) { this.isHovered = true; }.bind(this));
+
+ // Resume countdown on mouseleave if delayOnHover
+ this.options.delayOnHover && jQuery('#' + this.id).on('mouseleave', function (ev) { this.isHovered = false; }.bind(this));
+
+ // Positioning events
+ if ((this.options.adjustPosition || this.options.reposition) && !this.fixed && this.outside) {
+
+ // Trigger position events when scrolling
+ this.options.adjustTracker && jQuery(window).on('scroll.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
+
+ // Trigger position events when resizing
+ (this.options.adjustPosition || this.options.reposition) && jQuery(window).on('resize.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
+ }
+
+ // Mousemove events
+ this.options.target == 'mouse' && jQuery('body').on('mousemove.jBox-' + this.id, function (ev) { this.position({mouseTarget: {top: ev.pageY, left: ev.pageX}}); }.bind(this));
+ };
+
+
+ // Detach document and window events
+
+ this._detachEvents = function ()
+ {
+ // Closing event: closeOnEsc
+ this.options.closeOnEsc && jQuery(document).off('keyup.jBox-' + this.id);
+
+ // Closing event: closeOnClick
+ (this.options.closeOnClick === true || this.options.closeOnClick == 'body') && jQuery(document).off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+
+ // Positioning events
+ this.options.adjustTracker && jQuery(window).off('scroll.jBox-' + this.id);
+ (this.options.adjustPosition || this.options.reposition) && jQuery(window).off('resize.jBox-' + this.id);
+
+ // Mousemove events
+ this.options.target == 'mouse' && jQuery('body').off('mousemove.jBox-' + this.id);
+ };
+
+
+ // Show overlay
+
+ this._showOverlay = function ()
+ {
+ // Create the overlay if wasn't created already
+ if (!this.overlay) {
+
+ // Create element and append to the element where jBox is appended to
+ this.overlay = jQuery('
').addClass('jBox-overlay' + (this.type ? ' jBox-overlay-' + this.type : '')).css({
+ display: 'none',
+ opacity: 0,
+ zIndex: this.options.zIndex - 1
+ }).appendTo(this.options.appendTo);
+
+ // Add a class name to the overlay
+ this.options.overlayClass && this.overlay.addClass(this.options.overlayClass);
+
+ // Add close button to overlay
+ (this.options.closeButton == 'overlay' || this.options.closeButton === true) && this.overlay.append(this.closeButton);
+
+ // Add closeOnClick: 'overlay' events
+ this.options.closeOnClick == 'overlay' && this.overlay.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
+
+ // Adjust option adjustDistance if there is a close button in the overlay
+ jQuery('#' + this.id + '-overlay .jBox-closeButton').length && (this.options.adjustDistance.top = Math.max(jQuery('#' + this.id + '-overlay .jBox-closeButton').outerHeight(), this.options.adjustDistance.top));
+ }
+
+ // Adjust zIndex
+ if (this.adjustZIndexOnOpen === true) {
+ this.overlay.css('zIndex', parseInt(this.wrapper.css('zIndex'), 10) - 1);
+ }
+
+ // Abort if overlay is already visible
+ if (this.overlay.css('display') == 'block') return;
+
+ // Show overlay
+ this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 1}, {
+ queue: false,
+ duration: this.options.fade,
+ start: function () { this.overlay.css({display: 'block'}); }.bind(this)
+ })) : this.overlay.css({display: 'block', opacity: 1});
+ };
+
+
+ // Hide overlay
+
+ this._hideOverlay = function ()
+ {
+ // Abort if the overlay wasn't created yet
+ if (!this.overlay) return;
+
+ // Hide overlay if no other jBox needs it
+ this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 0}, {
+ queue: false,
+ duration: this.options.fade,
+ complete: function () { this.overlay.css({display: 'none'}); }.bind(this)
+ })) : this.overlay.css({display: 'none', opacity: 0});
+ };
+
+
+ // Get the correct jBox dimensions by moving jBox out of viewport
+
+ this._exposeDimensions = function ()
+ {
+ // Move wrapper out of viewport
+ this.wrapper.css({
+ top: -10000,
+ left: -10000,
+ right: 'auto',
+ bottom: 'auto'
+ });
+
+ // Get jBox dimensions
+ var jBoxDimensions = {
+ x: this.wrapper.outerWidth(),
+ y: this.wrapper.outerHeight()
+ };
+
+ // Reset position to viewport
+ this.wrapper.css({
+ top: 'auto',
+ left: 'auto'
+ });
+
+ return jBoxDimensions;
+ };
+
+
+ // Generate CSS for animations and append to header
+
+ this._generateAnimationCSS = function ()
+ {
+ // Get open and close animations if none provided
+ (jQuery.type(this.options.animation) != 'object') && (this.options.animation = {
+ pulse: {open: 'pulse', close: 'zoomOut'},
+ zoomIn: {open: 'zoomIn', close: 'zoomIn'},
+ zoomOut: {open: 'zoomOut', close: 'zoomOut'},
+ move: {open: 'move', close: 'move'},
+ slide: {open: 'slide', close: 'slide'},
+ flip: {open: 'flip', close: 'flip'},
+ tada: {open: 'tada', close: 'zoomOut'}
+ }[this.options.animation]);
+
+ // Abort if animation not found
+ if (!this.options.animation) return null;
+
+ // Get direction var
+ this.options.animation.open && (this.options.animation.open = this.options.animation.open.split(':'));
+ this.options.animation.close && (this.options.animation.close = this.options.animation.close.split(':'));
+ this.options.animation.openDirection = this.options.animation.open[1] ? this.options.animation.open[1] : null;
+ this.options.animation.closeDirection = this.options.animation.close[1] ? this.options.animation.close[1] : null;
+ this.options.animation.open && (this.options.animation.open = this.options.animation.open[0]);
+ this.options.animation.close && (this.options.animation.close = this.options.animation.close[0]);
+
+ // Add 'Open' and 'Close' to animation names
+ this.options.animation.open && (this.options.animation.open += 'Open');
+ this.options.animation.close && (this.options.animation.close += 'Close');
+
+ // All animations
+ var animations = {
+ pulse: {
+ duration: 350,
+ css: [['0%', 'scale(1)'], ['50%', 'scale(1.1)'], ['100%', 'scale(1)']]
+ },
+ zoomInOpen: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(0.9)'], ['100%', 'scale(1)']]
+ },
+ zoomInClose: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1)'], ['100%', 'scale(0.9)']]
+ },
+ zoomOutOpen: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1.1)'], ['100%', 'scale(1)']]
+ },
+ zoomOutClose: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1)'], ['100%', 'scale(1.1)']]
+ },
+ moveOpen: {
+ duration: (this.options.fade || 180),
+ positions: {top: {'0%': -12}, right: {'0%': 12}, bottom: {'0%': 12}, left: {'0%': -12}},
+ css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
+ },
+ moveClose: {
+ duration: (this.options.fade || 180),
+ timing: 'ease-in',
+ positions: {top: {'100%': -12}, right: {'100%': 12}, bottom: {'100%': 12}, left: {'100%': -12}},
+ css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
+ },
+ slideOpen: {
+ duration: 400,
+ positions: {top: {'0%': -400}, right: {'0%': 400}, bottom: {'0%': 400}, left: {'0%': -400}},
+ css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
+ },
+ slideClose: {
+ duration: 400,
+ timing: 'ease-in',
+ positions: {top: {'100%': -400}, right: {'100%': 400}, bottom: {'100%': 400}, left: {'100%': -400}},
+ css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
+ },
+ flipOpen: {
+ duration: 600,
+ css: [['0%', 'perspective(400px) rotateX(90deg)'], ['40%', 'perspective(400px) rotateX(-15deg)'], ['70%', 'perspective(400px) rotateX(15deg)'], ['100%', 'perspective(400px) rotateX(0deg)']]
+ },
+ flipClose: {
+ duration: (this.options.fade || 300),
+ css: [['0%', 'perspective(400px) rotateX(0deg)'], ['100%', 'perspective(400px) rotateX(90deg)']]
+ },
+ tada: {
+ duration: 800,
+ css: [['0%', 'scale(1)'], ['10%, 20%', 'scale(0.9) rotate(-3deg)'], ['30%, 50%, 70%, 90%', 'scale(1.1) rotate(3deg)'], ['40%, 60%, 80%', 'scale(1.1) rotate(-3deg)'], ['100%', 'scale(1) rotate(0)']]
+ }
+ };
+
+ // Set Open and Close names for standalone animations
+ jQuery.each(['pulse', 'tada'], function (index, item) { animations[item + 'Open'] = animations[item + 'Close'] = animations[item]; });
+
+ // Function to generate the CSS for the keyframes
+ var generateKeyframeCSS = function (ev, position)
+ {
+ // Generate keyframes CSS
+ var keyframe_css = '@keyframes jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
+ jQuery.each(animations[this.options.animation[ev]].css, function (index, item) {
+ var translate = position ? item[1].replace('%XY', this._getXY(position).toUpperCase()) : item[1];
+ animations[this.options.animation[ev]].positions && (translate = translate.replace('%V', animations[this.options.animation[ev]].positions[position][item[0]]));
+ keyframe_css += item[0] + ' {transform:' + translate + ';}';
+
+ }.bind(this));
+ keyframe_css += '}';
+
+ // Generate class CSS
+ keyframe_css += '.jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
+ keyframe_css += 'animation-duration: ' + animations[this.options.animation[ev]].duration + 'ms;';
+ keyframe_css += 'animation-name: jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ';';
+ keyframe_css += animations[this.options.animation[ev]].timing ? ('animation-timing-function: ' + animations[this.options.animation[ev]].timing + ';') : '';
+ keyframe_css += '}';
+
+ return keyframe_css;
+ }.bind(this);
+
+ // Generate css for each event and positions
+ this._animationCSS = '';
+ jQuery.each(['open', 'close'], function (index, ev)
+ {
+ // No CSS needed for closing with no fade
+ if (!this.options.animation[ev] || !animations[this.options.animation[ev]] || (ev == 'close' && !this.options.fade)) return '';
+
+ // Generate CSS
+ animations[this.options.animation[ev]].positions ?
+ jQuery.each(['top', 'right', 'bottom', 'left'], function (index2, position) { this._animationCSS += generateKeyframeCSS(ev, position); }.bind(this)) :
+ this._animationCSS += generateKeyframeCSS(ev);
+ }.bind(this));
+
+ };
+
+
+ // Add css for animations
+
+ this.options.animation && this._generateAnimationCSS();
+
+
+ // Block body clicks for 10ms to prevent extra event triggering
+
+ this._blockBodyClick = function ()
+ {
+ this.blockBodyClick = true;
+ setTimeout(function () { this.blockBodyClick = false; }.bind(this), 10);
+ };
+
+
+ // Animations
+
+ this._animate = function (ev)
+ {
+ // The event which triggers the animation
+ !ev && (ev = this.isOpen ? 'open' : 'close');
+
+ // Don't animate when closing with no fade duration
+ if (!this.options.fade && ev == 'close') return null;
+
+ // Get the current position, use opposite if jBox is flipped
+ var animationDirection = (this.options.animation[ev + 'Direction'] || ((this.align != 'center') ? this.align : this.options.attributes.x));
+ this.flipped && this._getXY(animationDirection) == (this._getXY(this.align)) && (animationDirection = this._getOpp(animationDirection));
+
+ // Add event and position classes
+ var classnames = 'jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + ' jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + '-' + animationDirection;
+ this.wrapper.addClass(classnames);
+
+ // Get duration of animation
+ var animationDuration = parseFloat(this.wrapper.css('animation-duration')) * 1000;
+ ev == 'close' && (animationDuration = Math.min(animationDuration, this.options.fade));
+
+ // Remove animation classes when animation is finished
+ setTimeout(function () {
+ this.wrapper && this.wrapper.removeClass(classnames);
+ }.bind(this), animationDuration);
+ };
+
+
+ // Abort an animation
+
+ this._abortAnimation = function ()
+ {
+ // Remove all animation classes
+ var classes = this.wrapper.attr('class').split(' ').filter(function (c) {
+ return c.lastIndexOf('jBox-' + this.id + '-animation', 0) !== 0;
+ }.bind(this));
+ this.wrapper.attr('class', classes.join(' '));
+ };
+
+
+ // Adjust dimensions when browser is resized
+
+ if (this.options.responsiveWidth || this.options.responsiveHeight)
+ {
+ // Responsive positioning overrides options adjustPosition and reposition
+ // TODO: Only add this resize event when the other one from adjustPosition and reposition was not set
+ jQuery(window).on('resize.responsivejBox-' + this.id, function (ev) { if (this.isOpen) { this.position(); } }.bind(this));
+ }
+
+
+ // Fix audio options
+
+ jQuery.type(this.options.preloadAudio) === 'string' && (this.options.preloadAudio = [this.options.preloadAudio]);
+ jQuery.type(this.options.audio) === 'string' && (this.options.audio = {open: this.options.audio});
+ jQuery.type(this.options.volume) === 'number' && (this.options.volume = {open: this.options.volume, close: this.options.volume});
+
+ if (this.options.preloadAudio === true && this.options.audio) {
+ this.options.preloadAudio = [];
+ jQuery.each(this.options.audio, function (index, url) {
+ this.options.preloadAudio.push(url + '.mp3');
+ this.options.preloadAudio.push(url + '.ogg');
+ }.bind(this));
+ }
+
+
+ // Preload audio files
+
+ this.options.preloadAudio.length && jQuery.each(this.options.preloadAudio, function (index, url) {
+ var audio = new Audio();
+ audio.src = url;
+ audio.preload = 'auto';
+ });
+
+
+ // Fire onInit event
+
+ this._fireEvent('onInit');
+
+
+ return this;
+ };
+
+
+ // Attach jBox to elements
+
+ jBox.prototype.attach = function (elements, trigger)
+ {
+ // Get elements from options if none passed
+ !elements && (elements = this.options.attach);
+
+ // Convert selectors to jQuery objects
+ jQuery.type(elements) == 'string' && (elements = jQuery(elements));
+
+ // Get trigger event from options if not passed
+ !trigger && (trigger = this.options.trigger);
+
+ // Loop through elements and attach jBox
+ elements && elements.length && jQuery.each(elements, function (index, el) {
+ el = jQuery(el);
+
+ // Only attach if the element wasn't attached to this jBox already
+ if (!el.data('jBox-attached-' + this.id)) {
+
+ // Remove title attribute and store content on element
+ (this.options.getContent == 'title' && el.attr('title') != undefined) && el.data('jBox-getContent', el.attr('title')).removeAttr('title');
+
+ // Add Element to collection
+ this.attachedElements || (this.attachedElements = []);
+ this.attachedElements.push(el[0]);
+
+ // Add click or mouseenter event, click events can prevent default as well
+ el.on(trigger + '.jBox-attach-' + this.id, function (ev)
+ {
+ // Clear timer
+ this.timer && clearTimeout(this.timer);
+
+ // Block opening when jbox is open and the source element is triggering
+ if (trigger == 'mouseenter' && this.isOpen && this.source[0] == el[0]) return;
+
+ // Only close jBox if you click the current target element, otherwise open at new target
+ if (this.isOpen && this.source && this.source[0] != el[0]) var forceOpen = true;
+
+ // Set new source element
+ this.source = el;
+
+ // Set new target
+ !this.options.target && (this.target = el);
+
+ // Prevent default action on click
+ trigger == 'click' && this.options.preventDefault && ev.preventDefault();
+
+ // Toggle or open jBox
+ this[trigger == 'click' && !forceOpen ? 'toggle' : 'open']();
+
+ }.bind(this));
+
+ // Add close event for trigger event mouseenter
+ (this.options.trigger == 'mouseenter') && el.on('mouseleave', function (ev)
+ {
+ // Abort if jBox wasn't created yet
+ if (!this.wrapper) return null;
+
+ // If we have set closeOnMouseleave, do not close jBox when leaving attached element and mouse is over jBox
+ if (!this.options.closeOnMouseleave || !(ev.relatedTarget == this.wrapper[0] || jQuery(ev.relatedTarget).parents('#' + this.id).length)) this.close();
+ }.bind(this));
+
+ // Store
+ el.data('jBox-attached-' + this.id, trigger);
+
+ // Fire onAttach event
+ this._fireEvent('onAttach', el);
+ }
+
+ }.bind(this));
+
+ return this;
+ };
+
+
+ // Detach jBox from elements
+
+ jBox.prototype.detach = function (elements)
+ {
+ // Get elements from stores elements if none passed
+ !elements && (elements = this.attachedElements || []);
+
+ elements && elements.length && jQuery.each(elements, function (index, el) {
+ el = jQuery(el);
+
+ // Remove events
+ if (el.data('jBox-attached-' + this.id)) {
+ el.off(el.data('jBox-attached-' + this.id) + '.jBox-attach-' + this.id);
+ el.data('jBox-attached-' + this.id, null);
+ }
+ // Remove element from collection
+ this.attachedElements = jQuery.grep(this.attachedElements, function (value) {
+ return value != el[0];
+ });
+ }.bind(this));
+
+ return this;
+ };
+
+
+ // Set title
+
+ jBox.prototype.setTitle = function (title, ignore_positioning)
+ {
+ // Abort if title to set
+ if (title == null || title == undefined) return this;
+
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Get the width and height of wrapper, only if they change we need to reposition
+ var wrapperHeight = this.wrapper.outerHeight();
+ var wrapperWidth = this.wrapper.outerWidth();
+
+ // Create title elements if they weren't created already
+ if (!this.title) {
+ this.titleContainer = jQuery('
');
+ this.title = jQuery('
').appendTo(this.titleContainer);
+ if (this.options.closeButton == 'title' || (this.options.closeButton === true && !this.options.overlay)) {
+ this.wrapper.addClass('jBox-closeButton-title');
+ this.closeButton.appendTo(this.titleContainer);
+ }
+ this.titleContainer.insertBefore(this.content);
+ this._setTitleWidth();
+ }
+
+ // Add or remove wrapper class
+ this.wrapper[title ? 'addClass' : 'removeClass']('jBox-hasTitle');
+
+ // Set title html
+ this.title.html(title);
+
+ // Adjust width of title
+ wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
+
+ // Make jBox draggable
+ this.options.draggable && this._draggable();
+
+ // Reposition if dimensions changed
+ !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
+
+ return this;
+ };
+
+
+ // Set content
+
+ jBox.prototype.setContent = function (content, ignore_positioning)
+ {
+ // Abort if no content to set
+ if (content == null || content == undefined) return this;
+
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Get the width and height of wrapper, only if they change we need to reposition
+ var wrapperHeight = this.wrapper.outerHeight();
+ var wrapperWidth = this.wrapper.outerWidth();
+
+ // Move all appended containers to body
+ this.content.children('[data-jbox-content-appended]').appendTo('body').css({display: 'none'});
+
+ // Set the new content
+ switch (jQuery.type(content)) {
+ case 'string':
+ this.content.html(content);
+ break;
+ case 'object':
+ if (content && (content instanceof jQuery || content.constructor.prototype.jquery)) {
+ this.content.html('');
+ content.attr('data-jbox-content-appended', 1).appendTo(this.content).css({display: 'block'});
+ } else {
+ this.content.html(JSON.stringify(content));
+ }
+ break;
+ }
+
+ // Adjust title width
+ wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
+
+ // Make jBox draggable
+ this.options.draggable && this._draggable();
+
+ // Reposition if dimensions changed
+ !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
+
+ return this;
+ };
+
+
+ // Set jBox dimensions
+
+ jBox.prototype.setDimensions = function (type, value, pos)
+ {
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Default value is 'auto'
+ value == undefined && (value = 'auto');
+
+ // Set CSS of content and title
+ this.content.css(type, this._getInt(value));
+
+ // Adjust title width
+ type == 'width' && this._setTitleWidth();
+
+ // Update options
+ this.options[type] = value;
+
+ // Reposition by default
+ (pos == undefined || pos) && this.position();
+ };
+
+
+ // Set jBox width or height
+
+ jBox.prototype.setWidth = function (value, pos) { this.setDimensions('width', value, pos); };
+ jBox.prototype.setHeight = function (value, pos) { this.setDimensions('height', value, pos); };
+
+
+ // Position jBox
+
+ jBox.prototype.position = function (options)
+ {
+ // Options are required
+ !options && (options = {});
+
+ // Combine passed options with jBox options
+ options = jQuery.extend(true, this.options, options);
+
+ // Get the target
+ this.target = options.target || this.target || jQuery(window);
+
+ // Make sure target is a jQuery element
+ !(this.target instanceof jQuery || this.target == 'mouse') && (this.target = jQuery(this.target));
+
+ // Abort if target is missing
+ if (!this.target.length) return this;
+
+ // Reset content css to get original dimensions
+ this.content.css({
+ width: this._getInt(options.width, 'width'),
+ height: this._getInt(options.height, 'height'),
+ minWidth: this._getInt(options.minWidth, 'width'),
+ minHeight: this._getInt(options.minHeight, 'height'),
+ maxWidth: this._getInt(options.maxWidth, 'width'),
+ maxHeight: this._getInt(options.maxHeight, 'height'),
+ });
+
+ // Reset width of title
+ this._setTitleWidth();
+
+ // Get jBox dimensions
+ var jBoxDimensions = this._exposeDimensions();
+
+ // Check if target has fixed position, store in elements data
+ this.target != 'mouse' && !this.target.data('jBox-' + this.id + '-fixed') && this.target.data('jBox-' + this.id + '-fixed', (this.target[0] != jQuery(window)[0] && (this.target.css('position') == 'fixed' || this.target.parents().filter(function () { return jQuery(this).css('position') == 'fixed'; }).length > 0)) ? 'fixed' : 'static');
+
+ // Get the window dimensions
+ var windowDimensions = {
+ x: jQuery(window).outerWidth(),
+ y: jQuery(window).outerHeight(),
+ top: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollTop()),
+ left: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollLeft())
+ };
+ windowDimensions.bottom = windowDimensions.top + windowDimensions.y;
+ windowDimensions.right = windowDimensions.left + windowDimensions.x;
+
+ // Get target offset
+ try { var targetOffset = this.target.offset(); } catch (e) { var targetOffset = {top: 0, left: 0}; };
+
+ // When the target is fixed and jBox is fixed, remove scroll offset
+ if (this.target != 'mouse' && this.target.data('jBox-' + this.id + '-fixed') == 'fixed' && options.fixed) {
+ targetOffset.top = targetOffset.top - jQuery(window).scrollTop();
+ targetOffset.left = targetOffset.left - jQuery(window).scrollLeft();
+ }
+
+ // Get target dimensions
+ var targetDimensions = {
+ x: this.target == 'mouse' ? 12 : this.target.outerWidth(),
+ y: this.target == 'mouse' ? 20 : this.target.outerHeight(),
+ top: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.top : (targetOffset ? targetOffset.top : 0),
+ left: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.left : (targetOffset ? targetOffset.left : 0)
+ };
+
+ // Check if jBox is outside
+ var outside = options.outside && !(options.position.x == 'center' && options.position.y == 'center');
+
+ // Get the available space on all sides
+ var availableSpace = {
+ x: windowDimensions.x - options.adjustDistance.left - options.adjustDistance.right, // TODO: substract position.x when they are numbers
+ y: windowDimensions.y - options.adjustDistance.top - options.adjustDistance.bottom, // TODO: substract position.x when they are numbers
+ left: !outside ? 0 : (targetDimensions.left - jQuery(window).scrollLeft() - options.adjustDistance.left),
+ right: !outside ? 0 : (windowDimensions.x - targetDimensions.left + jQuery(window).scrollLeft() - targetDimensions.x - options.adjustDistance.right),
+ top: !outside ? 0 : (targetDimensions.top - jQuery(window).scrollTop() - this.options.adjustDistance.top),
+ bottom: !outside ? 0 : (windowDimensions.y - targetDimensions.top + jQuery(window).scrollTop() - targetDimensions.y - options.adjustDistance.bottom),
+ };
+
+ // Get the default outside position, check if box will be flipped
+ var jBoxOutsidePosition = {
+ x: (options.outside == 'x' || options.outside == 'xy') && jQuery.type(options.position.x) != 'number' ? options.position.x : null,
+ y: (options.outside == 'y' || options.outside == 'xy') && jQuery.type(options.position.y) != 'number' ? options.position.y : null
+ };
+ var flip = {x: false, y: false};
+ (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
+ (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
+
+ // Adjust responsive dimensions
+ if (options.responsiveWidth || options.responsiveHeight) {
+
+ // Adjust width and height according to default outside position
+ var adjustResponsiveWidth = function ()
+ {
+ if (options.responsiveWidth && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x || 'x']) {
+ var contentWidth = availableSpace[jBoxOutsidePosition.x || 'x'] - (this.pointer && outside && options.outside == 'x' ? this.pointer.dimensions.x : 0) - parseInt(this.container.css('border-left-width')) - parseInt(this.container.css('border-right-width'));
+ this.content.css({
+ width: contentWidth > this.options.responsiveMinWidth ? contentWidth : null,
+ minWidth: contentWidth < parseInt(this.content.css('minWidth')) ? 0 : null
+ });
+ this._setTitleWidth();
+ }
+ jBoxDimensions = this._exposeDimensions();
+
+ }.bind(this);
+ options.responsiveWidth && adjustResponsiveWidth();
+
+ // After adjusting width, check if jBox will be flipped for y
+ options.responsiveWidth && !flip.y && (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
+
+ // Adjust width and height according to default outside position
+ var adjustResponsiveHeight = function ()
+ {
+ if (options.responsiveHeight && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y || 'y']) {
+
+ // Expose wrapper to get correct title height
+ var exposeTitleFooterHeight = function () {
+ if (!this.titleContainer && !this.footer) return 0;
+ if (this.wrapper.css('display') == 'none') {
+ this.wrapper.css('display', 'block');
+ var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
+ this.wrapper.css('display', 'none');
+ } else {
+ var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
+ }
+ return height || 0;
+ }.bind(this);
+
+ var contentHeight = availableSpace[jBoxOutsidePosition.y || 'y'] - (this.pointer && outside && options.outside == 'y' ? this.pointer.dimensions.y : 0) - exposeTitleFooterHeight() - parseInt(this.container.css('border-top-width')) - parseInt(this.container.css('border-bottom-width'));
+ this.content.css({height: contentHeight > this.options.responsiveMinHeight ? contentHeight : null});
+ this._setTitleWidth();
+ }
+ jBoxDimensions = this._exposeDimensions();
+
+ }.bind(this);
+ options.responsiveHeight && adjustResponsiveHeight();
+
+ // After adjusting height, check if jBox will be flipped for x
+ options.responsiveHeight && !flip.x && (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
+
+ // Adjust width and height if jBox will be flipped
+ if (options.adjustPosition && options.adjustPosition != 'move') {
+ flip.x && adjustResponsiveWidth();
+ flip.y && adjustResponsiveHeight();
+ }
+ }
+
+ // Store new positioning vars in local var
+ var pos = {};
+
+ // Calculate positions
+ var setPosition = function (p)
+ {
+ // Set number positions
+ if (jQuery.type(options.position[p]) == 'number') {
+ pos[options.attributes[p]] = options.position[p];
+ return;
+ }
+
+ // We have a target, so use 'left' or 'top' as attributes
+ var a = options.attributes[p] = (p == 'x' ? 'left' : 'top');
+
+ // Start at target position
+ pos[a] = targetDimensions[a];
+
+ // Set centered position
+ if (options.position[p] == 'center') {
+ pos[a] += Math.ceil((targetDimensions[p] - jBoxDimensions[p]) / 2);
+
+ // If the target is the window, adjust centered position depending on adjustDistance
+ (this.target != 'mouse' && this.target[0] && this.target[0] == jQuery(window)[0]) && (pos[a] += (options.adjustDistance[a] - options.adjustDistance[this._getOpp(a)]) * 0.5);
+ return;
+ }
+
+ // Move inside
+ (a != options.position[p]) && (pos[a] += targetDimensions[p] - jBoxDimensions[p]);
+
+ // Move outside
+ (options.outside == p || options.outside == 'xy') && (pos[a] += jBoxDimensions[p] * (a != options.position[p] ? 1 : -1));
+
+ }.bind(this);
+
+ // Set position including offset
+ setPosition('x');
+ setPosition('y');
+
+ // Adjust position depending on pointer align
+ if (this.pointer && options.pointTo == 'target' && jQuery.type(options.position.x) != 'number' && jQuery.type(options.position.y) != 'number') {
+
+ var adjustWrapper = 0;
+
+ // Where is the pointer aligned? Add or substract accordingly
+ switch (this.pointer.align) {
+ case 'center':
+ if (options.position[this._getOpp(options.outside)] != 'center') {
+ adjustWrapper += (jBoxDimensions[this._getOpp(options.outside)] / 2);
+ }
+ break;
+ default:
+ switch (options.position[this._getOpp(options.outside)]) {
+ case 'center':
+ adjustWrapper += ((jBoxDimensions[this._getOpp(options.outside)] / 2) - (this.pointer.dimensions[this._getOpp(options.outside)] / 2)) * (this.pointer.align == this._getTL(this.pointer.align) ? 1 : -1);
+ break;
+ default:
+ adjustWrapper += (this.pointer.align != options.position[this._getOpp(options.outside)]) ?
+
+ // If pointer align is different to position align
+ (jBoxDimensions[this._getOpp(options.outside)] * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1)) + ((this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? -1 : 1)) :
+
+ // If pointer align is same as position align
+ (this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1);
+ break;
+ }
+ break;
+ }
+
+ adjustWrapper *= (options.position[this._getOpp(options.outside)] == this.pointer.alignAttribute ? -1 : 1);
+ adjustWrapper += this.pointer.offset * (this.pointer.align == this._getOpp(this._getTL(this.pointer.align)) ? 1 : -1);
+
+ pos[this._getTL(this._getOpp(this.pointer.xy))] += adjustWrapper;
+ }
+
+ // Add final offset
+ pos[options.attributes.x] += options.offset.x;
+ pos[options.attributes.y] += options.offset.y;
+
+ // Set CSS
+ this.wrapper.css(pos);
+
+ // Adjust position
+ if (options.adjustPosition) {
+
+ // Reset cached pointer position
+ if (this.positionAdjusted) {
+ this.pointer && this.wrapper.css('padding', 0).css('padding-' + this._getOpp(this.outside), this.pointer.dimensions[this._getXY(this.outside)]).removeClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).addClass('jBox-pointerPosition-' + this.pointer.position);
+ this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + this._getOpp(this.outside)).css(this.pointer.margin);
+ this.positionAdjusted = false;
+ this.flipped = false;
+ }
+
+ // Find out where the jBox is out of view area
+ var outYT = (windowDimensions.top > pos.top - (options.adjustDistance.top || 0)),
+ outXR = (windowDimensions.right < pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0)),
+ outYB = (windowDimensions.bottom < pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0)),
+ outXL = (windowDimensions.left > pos.left - (options.adjustDistance.left || 0)),
+ outX = outXL ? 'left' : (outXR ? 'right' : null),
+ outY = outYT ? 'top' : (outYB ? 'bottom' : null),
+ out = outX || outY;
+
+ // Only continue if jBox is out of view area
+ if (out) {
+
+ if ((this.type == 'Modal' || this.type == 'Confirm')
+ && jQuery.type(this.options.position.x) == 'number'
+ && jQuery.type(this.options.position.y) == 'number'
+ ) {
+ var diffX = 0, diffY = 0;
+ if (this.options.holdPosition) {
+
+ // Adjust left or right
+ if (outXL) {
+ diffX = windowDimensions.left - (pos.left - (options.adjustDistance.left || 0));
+ } else if (outXR) {
+ diffX = windowDimensions.right - (pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0));
+ }
+
+ // Adjust top or bottom
+ if (outYT) {
+ diffY = windowDimensions.top - (pos.top - (options.adjustDistance.top || 0));
+ } else if (outYB) {
+ diffY = windowDimensions.bottom - (pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0));
+ }
+
+ this.options.position.x = Math.max(windowDimensions.top, this.options.position.x + diffX);
+ this.options.position.y = Math.max(windowDimensions.left, this.options.position.y + diffY);
+
+ setPosition('x');
+ setPosition('y');
+ this.wrapper.css(pos);
+ }
+ // Fire onPosition event
+ this._fireEvent('onPosition');
+
+ return this;
+ }
+
+ // Function to flip position
+ if (options.adjustPosition === true || options.adjustPosition === 'flip') {
+ var flipJBox = function (xy) {
+ this.wrapper.css(this._getTL(xy), pos[this._getTL(xy)] + ((jBoxDimensions[this._getXY(xy)] + (options.offset[this._getXY(xy)] * (xy == 'top' || xy == 'left' ? -2 : 2)) + targetDimensions[this._getXY(xy)]) * (xy == 'top' || xy == 'left' ? 1 : -1)));
+ this.pointer && this.wrapper.removeClass('jBox-pointerPosition-' + this.pointer.position).addClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).css('padding', 0).css('padding-' + xy, this.pointer.dimensions[this._getXY(xy)]);
+ this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + xy);
+ this.positionAdjusted = true;
+ this.flipped = true;
+ }.bind(this);
+
+ // Flip jBox
+ flip.x && flipJBox(this.options.position.x);
+ flip.y && flipJBox(this.options.position.y);
+ }
+
+ // Move jBox (only possible with pointer)
+ var outMove = (this._getXY(this.outside) == 'x') ? outY : outX;
+
+ if (this.pointer && options.pointTo == 'target' && options.adjustPosition != 'flip' && this._getXY(outMove) == this._getOpp(this._getXY(this.outside))) {
+
+ // Get the maximum space we have availible to adjust
+ if (this.pointer.align == 'center') {
+ var spaceAvail = (jBoxDimensions[this._getXY(outMove)] / 2) - (this.pointer.dimensions[this._getOpp(this.pointer.xy)] / 2) - (parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) * (outMove != this._getTL(outMove) ? -1 : 1));
+ } else {
+ var spaceAvail = (outMove == this.pointer.alignAttribute) ?
+ parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) :
+ jBoxDimensions[this._getXY(outMove)] - parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - this.pointer.dimensions[this._getXY(outMove)];
+ }
+
+ // Get the overlapping space
+ var spaceDiff = (outMove == this._getTL(outMove)) ?
+ windowDimensions[this._getTL(outMove)] - pos[this._getTL(outMove)] + options.adjustDistance[outMove] :
+ (windowDimensions[this._getOpp(this._getTL(outMove))] - pos[this._getTL(outMove)] - options.adjustDistance[outMove] - jBoxDimensions[this._getXY(outMove)]) * -1;
+
+ // Add overlapping space on left or top window edge
+ if (outMove == this._getOpp(this._getTL(outMove)) && pos[this._getTL(outMove)] - spaceDiff < windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)]) {
+ spaceDiff -= windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)] - (pos[this._getTL(outMove)] - spaceDiff);
+ }
+
+ // Only adjust the maximum availible
+ spaceDiff = Math.min(spaceDiff, spaceAvail);
+
+ // Move jBox
+ if (spaceDiff <= spaceAvail && spaceDiff > 0) {
+ this.pointer.element.css('margin-' + this.pointer.alignAttribute, parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - (spaceDiff * (outMove != this.pointer.alignAttribute ? -1 : 1)));
+ this.wrapper.css(this._getTL(outMove), pos[this._getTL(outMove)] + (spaceDiff * (outMove != this._getTL(outMove) ? -1 : 1)));
+ this.positionAdjusted = true;
+ }
+ }
+ }
+ }
+
+ // Fire onPosition event
+ this._fireEvent('onPosition');
+
+ return this;
+ };
+
+
+ // Block scrolling
+ // Borrowed from https://github.com/StephanWagner/unscroll
+
+ jBox.prototype.unscroll = function (elements) {
+
+ // Store reusable vars
+ this.set = function (id, value) {
+ if (!window.unscrollStore) {
+ window.unscrollStore = {};
+ }
+ window.unscrollStore[id] = value;
+ };
+
+ // Get reusable vars
+ this.get = function (id) {
+ return window.unscrollStore ? window.unscrollStore[id] : null;
+ };
+
+ // Get the width of the scroll bar in pixel
+ this.getScrollbarWidth = function () {
+ if (this.get('scrollbarWidth')) {
+ return this.get('scrollbarWidth') + 'px';
+ }
+ var scrollElement = document.createElement('div');
+ scrollElement.style.width = '100px';
+ scrollElement.style.height = '100px';
+ scrollElement.style.overflow = 'scroll';
+ scrollElement.style.position = 'absolute';
+ scrollElement.style.top = '-10000';
+
+ document.body.appendChild(scrollElement);
+ var scrollbarWidth = scrollElement.offsetWidth - scrollElement.clientWidth;
+ document.body.removeChild(scrollElement);
+
+ this.set('scrollbarWidth', scrollbarWidth);
+ return scrollbarWidth + 'px';
+ }
+
+ // Add unscroll class to head
+ function addUnscrollClassName() {
+ if (document.getElementById('unscroll-class-name')) {
+ return;
+ }
+ var css = '.unscrollable { overflow: hidden !important; }',
+ head = document.head || document.getElementsByTagName('head')[0],
+ style = document.createElement('style');
+ style.type = 'text/css';
+ style.setAttribute('id', 'unscroll-class-name');
+ style.appendChild(document.createTextNode(css));
+ head.appendChild(style);
+ }
+
+ // Get the elements to adjust, force body element
+ this.getElementsToAdjust = function (elements) {
+ !elements && (elements = []);
+
+ if (typeof elements === 'string') {
+ elements = [
+ [elements, 'padding-right']
+ ];
+ }
+
+ elements.forEach(function (element, index) {
+ if (typeof element === 'string') {
+ elements[index] = [element, 'padding-right'];
+ }
+ });
+
+ var bodyFound = false;
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i][0].indexOf('body') !== -1) {
+ bodyFound = true;
+ }
+ };
+
+ if (bodyFound === false) {
+ elements.push(['body', 'padding-right']);
+ }
+
+ return elements;
+ }
+
+ this.pageHasScrollbar = function () {
+ return this.getScrollbarWidth() && document.body.offsetHeight > window.innerHeight;
+ }
+
+ // Clean up elements
+ if (this.pageHasScrollbar()) {
+ elements = this.getElementsToAdjust(elements);
+
+ // Loop through elements and adjust accordingly
+ for (var i = 0; i < elements.length; i++) {
+ var elementsDOM = document.querySelectorAll(elements[i][0]);
+ for (var j = 0; j < elementsDOM.length; j++) {
+ if (elementsDOM[j].getAttribute('data-unscroll')) {
+ return;
+ }
+ var attribute = elements[i][1];
+ var computedStyles = window.getComputedStyle(elementsDOM[j]);
+ var computedStyle = computedStyles.getPropertyValue(attribute);
+ elementsDOM[j].setAttribute('data-unscroll', attribute);
+ if (!computedStyle) {
+ computedStyle = '0px';
+ }
+ var operator = attribute == 'padding-right' || attribute == 'right' ? '+' : '-';
+ elementsDOM[j].style[attribute] = 'calc(' + computedStyle + ' ' + operator + ' ' + this.getScrollbarWidth() + ')';
+ }
+ }
+ }
+
+ // Make the page unscrollable
+ addUnscrollClassName();
+ document.body.classList.add('unscrollable');
+ }
+
+ jBox.prototype.unscroll.reset = function () {
+ var elements = document.querySelectorAll('[data-unscroll]');
+
+ for (var i = 0; i < elements.length; i++) {
+ var attribute = elements[i].getAttribute('data-unscroll');
+ elements[i].style[attribute] = null;
+ elements[i].removeAttribute('data-unscroll');
+ }
+ document.body.classList.remove('unscrollable');
+ }
+
+
+ // Open jBox
+
+ jBox.prototype.open = function (options)
+ {
+ // Create blank options if none passed
+ !options && (options = {});
+
+ // Abort if jBox was destroyed
+ if (this.isDestroyed) return this;
+
+ // Construct jBox if not already constructed
+ !this.wrapper && this._create();
+
+ // Add css to header if not added already
+ !this._styles && (this._styles = jQuery('
').append(this._animationCSS).appendTo(jQuery('head')));
+
+ // Abort any opening or closing timer
+ this.timer && clearTimeout(this.timer);
+
+ // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body'
+ this._blockBodyClick();
+
+ // Block opening
+ if (this.isDisabled) return this;
+
+ // Closing event: closeOnEsc
+ this.options.closeOnEsc && jQuery(document).on('keyup.jBox-' + this.id, function (ev) { if (ev.keyCode == 27) { this.close({ignoreDelay: true}); }}.bind(this));
+
+ // Closing event: closeOnClick
+ if (this.options.closeOnClick === true || this.options.closeOnClick === 'body') {
+ jQuery('body').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function (ev) {
+ if (this.blockBodyClick || (this.options.closeOnClick == 'body' && (ev.target == this.wrapper[0] || this.wrapper.has(ev.target).length))) return;
+ this.close({ignoreDelay: true});
+ }.bind(this));
+
+ // Fix for iOS event bubbling issue
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+ this.isTouchDevice && jQuery('body > *').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function () {
+ return true;
+ });
+ }
+
+ // Opening function
+ var open = function () {
+
+ // Adjust zIndex
+ if (this.adjustZIndexOnOpen === true) {
+ jBox.zIndexMax = Math.max(
+ parseInt(this.wrapper.css('zIndex'), 10),
+ this.options.zIndex,
+ jBox.zIndexMax || 0,
+ jBox.zIndexMaxDragover || 0
+ ) + 2;
+ this.wrapper.css('zIndex', jBox.zIndexMax);
+ this.options.zIndex = jBox.zIndexMax;
+ }
+
+ // Set title from source element
+ this.source && this.options.getTitle && (this.source.attr(this.options.getTitle) && this.setTitle(this.source.attr(this.options.getTitle), true));
+
+ // Set content from source element
+ this.source && this.options.getContent && (this.source.data('jBox-getContent') ? this.setContent(this.source.data('jBox-getContent'), true) : (this.source.attr(this.options.getContent) ? this.setContent(this.source.attr(this.options.getContent), true) : (this.options.getContent == 'html' ? this.setContent(this.source.html(), true) : null)));
+
+ // Fire onOpen event
+ this._fireEvent('onOpen');
+
+ // Get content from ajax
+ if ((this.options.ajax && (this.options.ajax.url || (this.source && this.source.attr(this.options.ajax.getURL))) && (!this.ajaxLoaded || this.options.ajax.reload)) || (options.ajax && (options.ajax.url || options.ajax.data))) {
+ // Send the content from stored data if there is any, otherwise load new data
+ (this.options.ajax.reload != 'strict' && this.source && this.source.data('jBox-ajax-data') && !(options.ajax && (options.ajax.url || options.ajax.data))) ? this.setContent(this.source.data('jBox-ajax-data')) : this.ajax((options.ajax || null), true);
+ }
+
+ // Set position
+ (!this.positionedOnOpen || this.options.repositionOnOpen) && this.position(options) && (this.positionedOnOpen = true);
+
+ // Abort closing
+ this.isClosing && this._abortAnimation();
+
+ // Open functions to call when jBox is closed
+ if (!this.isOpen) {
+
+ // jBox is open now
+ this.isOpen = true;
+
+ // Automatically close jBox after some time
+ this.options.autoClose && (this.options.delayClose = this.options.autoClose) && this.close();
+
+ // Attach events
+ this._attachEvents();
+
+ // Block scrolling
+ if (this.options.blockScroll) {
+ if (this.options.blockScrollAdjust) {
+ if (jBox.blockScrollScopes) {
+ jBox.blockScrollScopes++;
+ } else {
+ jBox.blockScrollScopes = 1;
+ this.unscroll(Array.isArray(this.options.blockScrollAdjust) || typeof this.options.blockScrollAdjust === 'string' ? this.options.blockScrollAdjust : null);
+ }
+ } else {
+ jQuery('body').addClass('jBox-blockScroll-' + this.id);
+ }
+ }
+
+ // Show overlay
+ if (this.options.overlay) {
+ this._showOverlay();
+
+ // TODO Optimize: We have to position here again, because if the overlay has a close button, the upper adjustDistance will be wrong
+ this.position();
+ }
+
+ // Only animate if jBox is completely closed
+ this.options.animation && !this.isClosing && this._animate('open');
+
+ // Play audio file
+ this.options.audio && this.options.audio.open && this.audio(this.options.audio.open, this.options.volume.open);
+
+ // Fading animation or show immediately
+ if (this.options.fade) {
+ this.wrapper.stop().animate({opacity: 1}, {
+ queue: false,
+ duration: this.options.fade,
+ start: function () {
+ this.isOpening = true;
+ this.wrapper.css({display: 'block'});
+ }.bind(this),
+ complete: function () {
+ this._fireEvent('onOpenComplete');
+ }.bind(this),
+ always: function () {
+ this.isOpening = false;
+
+ // Delay positioning for ajax to prevent positioning during animation
+ setTimeout(function () { this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false); }.bind(this), 10);
+ }.bind(this)
+ });
+ } else {
+ this.wrapper.css({display: 'block', opacity: 1});
+ this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false);
+ this._fireEvent('onOpenComplete');
+ }
+ }
+ }.bind(this);
+
+ // Open jBox
+ this.options.delayOpen && !this.isOpen && !this.isClosing && !options.ignoreDelay ? (this.timer = setTimeout(open, this.options.delayOpen)) : open();
+
+ return this;
+ };
+
+
+ // Close jBox
+
+ jBox.prototype.close = function (options)
+ {
+ // Create blank options if none passed
+ options || (options = {});
+
+ // Remove close events
+ jQuery('body').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+ this.isTouchDevice && jQuery('body > *').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+
+ // Abort if jBox was destroyed or is currently closing
+ if (this.isDestroyed || this.isClosing) return this;
+
+ // Abort opening
+ this.timer && clearTimeout(this.timer);
+
+ // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body' is true
+ this._blockBodyClick();
+
+ // Block closing
+ if (this.isDisabled) return this;
+
+ // Close function
+ var close = function () {
+
+ // Fire onClose event
+ this._fireEvent('onClose');
+
+ // Cancel the ajax call
+ if (this.options.cancelAjaxOnClose) {
+ this.cancelAjax();
+ }
+
+ // Only close if jBox is open
+ if (this.isOpen) {
+
+ // jBox is not open anymore
+ this.isOpen = false;
+
+ // Detach events
+ this._detachEvents();
+
+ // Unblock scrolling
+ if (this.options.blockScroll) {
+ if (this.options.blockScrollAdjust) {
+ jBox.blockScrollScopes = jBox.blockScrollScopes ? --jBox.blockScrollScopes : 0;
+ !jBox.blockScrollScopes && this.unscroll.reset();
+ } else {
+ jQuery('body').removeClass('jBox-blockScroll-' + this.id);
+ }
+ }
+
+ // Hide overlay
+ this.options.overlay && this._hideOverlay();
+
+ // Only animate if jBox is compleately closed
+ this.options.animation && !this.isOpening && this._animate('close');
+
+ // Play audio file
+ this.options.audio && this.options.audio.close && this.audio(this.options.audio.close, this.options.volume.close);
+
+ // Get fade duration
+ var fadeDuration = this.isTouchDevice && this.options.target == 'mouse' ? 0 : this.options.fade;
+
+ // Fading animation or show immediately
+ if (fadeDuration) {
+ this.wrapper.stop().animate({opacity: 0}, {
+ queue: false,
+ duration: fadeDuration,
+ start: function () {
+ this.isClosing = true;
+ }.bind(this),
+ complete: function () {
+ this.wrapper.css({display: 'none'});
+ this._fireEvent('onCloseComplete');
+ }.bind(this),
+ always: function () {
+ this.isClosing = false;
+ }.bind(this)
+ });
+ } else {
+ this.wrapper.css({display: 'none', opacity: 0});
+ this._fireEvent('onCloseComplete');
+ }
+ }
+ }.bind(this);
+
+ // Close jBox
+ if (options.ignoreDelay || (this.isTouchDevice && this.options.target == 'mouse')) {
+ close();
+ } else if ((this.options.delayOnHover || this.options.showCountdown) && this.options.delayClose > 10) {
+ var self = this;
+ var remaining = this.options.delayClose;
+ var prevFrame = Date.now();
+ if (this.options.showCountdown && !this.inner) {
+ var outer = jQuery('
');
+ this.inner = jQuery('
');
+ outer.prepend(this.inner);
+ jQuery('#' + this.id).append(outer);
+ }
+ this.countdown = function(){
+ var dateNow = Date.now();
+ if (!self.isHovered) {
+ remaining -= dateNow - prevFrame;
+ }
+ prevFrame = dateNow;
+ if (remaining > 0) {
+ if (self.options.showCountdown) {
+ self.inner.css('width', (remaining * 100 / self.options.delayClose) + '%');
+ }
+ window.requestAnimationFrame(self.countdown);
+ } else {
+ close();
+ }
+ };
+ window.requestAnimationFrame(this.countdown);
+ } else {
+ this.timer = setTimeout(close, Math.max(this.options.delayClose, 10));
+ }
+
+ return this;
+ };
+
+
+ // Open or close jBox
+
+ jBox.prototype.toggle = function (options)
+ {
+ this[this.isOpen ? 'close' : 'open'](options);
+ return this;
+ };
+
+
+ // Block opening and closing
+
+ jBox.prototype.disable = function ()
+ {
+ this.isDisabled = true;
+ return this;
+ };
+
+
+ // Unblock opening and closing
+
+ jBox.prototype.enable = function ()
+ {
+ this.isDisabled = false;
+ return this;
+ };
+
+
+ // Hide jBox
+
+ jBox.prototype.hide = function ()
+ {
+ this.disable();
+ if (this.wrapper) {
+ this.cacheWrapperDisplay = this.wrapper.css('display');
+ this.wrapper.css({display: 'none'});
+ }
+ if (this.overlay) {
+ this.cacheOverlayDisplay = this.overlay.css('display');
+ this.overlay.css({display: 'none'});
+ }
+ return this;
+ };
+
+
+ // Show jBox
+
+ jBox.prototype.show = function ()
+ {
+ this.enable();
+ if (this.wrapper && this.cacheWrapperDisplay) {
+ this.wrapper.css({display: this.cacheWrapperDisplay});
+ this.cacheWrapperDisplay = null;
+ }
+ if (this.overlay && this.cacheOverlayDisplay) {
+ this.overlay.css({display: this.cacheOverlayDisplay});
+ this.cacheOverlayDisplay = null;
+ }
+ return this;
+ };
+
+
+ // Get content from ajax
+
+ jBox.prototype.ajax = function (options, opening)
+ {
+ options || (options = {});
+
+ // Add data or url from source element if none set in options
+ jQuery.each([['getData', 'data'], ['getURL', 'url']], function (index, item) {
+ (this.options.ajax[item[0]] && !options[item[1]] && this.source && this.source.attr(this.options.ajax[item[0]]) != undefined) && (options[item[1]] = this.source.attr(this.options.ajax[item[0]]) || '');
+ }.bind(this));
+
+ // Clone the system options
+ var sysOptions = jQuery.extend(true, {}, this.options.ajax);
+
+ // Abort running ajax call
+ this.cancelAjax();
+
+ // Extract events
+ var beforeSend = options.beforeSend || sysOptions.beforeSend || function () {};
+ var complete = options.complete || sysOptions.complete || function () {};
+ var success = options.success || sysOptions.success || function () {};
+ var error = options.error || sysOptions.error || function () {};
+
+ // Merge options
+ var userOptions = jQuery.extend(true, sysOptions, options);
+
+ // Set new beforeSend event
+ userOptions.beforeSend = function (xhr)
+ {
+ // jBox is loading
+ userOptions.loadingClass && this.wrapper.addClass(userOptions.loadingClass === true ? 'jBox-loading' : userOptions.loadingClass);
+
+ // Add loading spinner
+ userOptions.spinner && (this.spinnerDelay = setTimeout(function ()
+ {
+ // Add class for loading spinner
+ this.wrapper.addClass('jBox-loading-spinner');
+
+ // Reposition jBox
+ // TODO: Only reposition if dimensions change
+ userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Add spinner to container
+ this.spinner = jQuery(userOptions.spinner !== true ? userOptions.spinner : '
').appendTo(this.container);
+
+ // Fix spinners position if there is a title
+ this.titleContainer && this.spinner.css('position') == 'absolute' && this.spinner.css({transform: 'translateY(' + (this.titleContainer.outerHeight() * 0.5) + 'px)'});
+
+ }.bind(this), (this.content.html() == '' ? 0 : (userOptions.spinnerDelay || 0))));
+
+ // Fire users beforeSend event
+ (beforeSend.bind(this))(xhr);
+
+ }.bind(this);
+
+ // Set up new complete event
+ userOptions.complete = function (response)
+ {
+ // Abort spinner timeout
+ this.spinnerDelay && clearTimeout(this.spinnerDelay);
+
+ // jBox finished loading
+ this.wrapper.removeClass('jBox-loading jBox-loading-spinner jBox-loading-spinner-delay');
+
+ // Remove spinner
+ this.spinner && this.spinner.length && this.spinner.remove() && userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Store that ajax loading finished
+ this.ajaxLoaded = true;
+
+ // Fire users complete event
+ (complete.bind(this))(response);
+
+ }.bind(this);
+
+ // Set up new success event
+ userOptions.success = function (response)
+ {
+ // Set content
+ userOptions.setContent && this.setContent(response, true) && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Store content in source element
+ userOptions.setContent && this.source && this.source.data('jBox-ajax-data', response);
+
+ // Fire users success event
+ (success.bind(this))(response);
+
+ }.bind(this);
+
+ // Add error event
+ userOptions.error = function (response) { (error.bind(this))(response); }.bind(this);
+
+ // Send new ajax request
+ this.ajaxRequest = jQuery.ajax(userOptions);
+
+ return this;
+ };
+
+
+ // Abort an ajax call
+
+ jBox.prototype.cancelAjax = function () {
+ if (this.ajaxRequest) {
+ this.ajaxRequest.abort();
+ this.ajaxLoaded = false;
+ }
+ };
+
+
+ // Play an audio file
+
+ jBox.prototype.audio = function (url, volume)
+ {
+ // URL is required
+ if (!url) return this;
+
+ // Create intern audio object if it wasn't created already
+ !jBox._audio && (jBox._audio = {});
+
+ // Create an audio element specific to this audio file if it doesn't exist already
+ if (!jBox._audio[url]) {
+ var audio = jQuery(' ');
+ jQuery(' ', {src: url + '.mp3'}).appendTo(audio);
+ jQuery(' ', {src: url + '.ogg'}).appendTo(audio);
+ jBox._audio[url] = audio[0];
+ }
+
+ // Set volume
+ jBox._audio[url].volume = Math.min(((volume != undefined ? volume : 100) / 100), 1);
+
+ // Try to pause current audio
+ try {
+ jBox._audio[url].pause();
+ jBox._audio[url].currentTime = 0;
+ } catch (e) {}
+
+ // Play audio
+ jBox._audio[url].play();
+
+ return this;
+ };
+
+ // Apply custom animations to jBox (being used in playground demos)
+
+ jBox._animationSpeeds = {
+ 'tada': 1000,
+ 'tadaSmall': 1000,
+ 'flash': 500,
+ 'shake': 400,
+ 'pulseUp': 250,
+ 'pulseDown': 250,
+ 'popIn': 250,
+ 'popOut': 250,
+ 'fadeIn': 200,
+ 'fadeOut': 200,
+ 'slideUp': 400,
+ 'slideRight': 400,
+ 'slideLeft': 400,
+ 'slideDown': 400
+ };
+
+ jBox.prototype.animate = function (animation, options)
+ {
+ // Options are required
+ !options && (options = {});
+
+ // Timout needs to be an object
+ !this.animationTimeout && (this.animationTimeout = {});
+
+ // Use jBox wrapper by default
+ !options.element && (options.element = this.wrapper);
+
+ // Give the element an unique id
+ !options.element.data('jBox-animating-id') && options.element.data('jBox-animating-id', jBox._getUniqueElementID());
+
+ // Abort if element is animating
+ if (options.element.data('jBox-animating')) {
+ options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null);
+ this.animationTimeout[options.element.data('jBox-animating-id')] && clearTimeout(this.animationTimeout[options.element.data('jBox-animating-id')]);
+ }
+
+ // Animate the element
+ options.element.addClass('jBox-animated-' + animation).data('jBox-animating', 'jBox-animated-' + animation);
+ this.animationTimeout[options.element.data('jBox-animating-id')] = setTimeout((function() { options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null); options.complete && options.complete(); }), jBox._animationSpeeds[animation]);
+ };
+
+ // https://gist.github.com/AlexEmashev/ee8302b5036b01362f63dab35948401f
+ jBox.prototype.swipeDetector = function (swipeTarget, options) {
+ // States: 0 - no swipe, 1 - swipe started, 2 - swipe released
+ var swipeState = 0;
+ // Coordinates when swipe started
+ var startX = 0;
+ var startY = 0;
+ // Distance of swipe
+ var pixelOffsetX = 0;
+ var pixelOffsetY = 0;
+
+ var defaultSettings = {
+ // Amount of pixels, when swipe don't count.
+ swipeThreshold: 70,
+ // Flag that indicates that plugin should react only on touch events.
+ // Not on mouse events too.
+ useOnlyTouch: false
+ };
+
+ // Initializer
+ (function init() {
+ options = jQuery.extend(defaultSettings, options);
+ // Support touch and mouse as well.
+ swipeTarget.on("mousedown touchstart", swipeStart);
+ jQuery("html").on("mouseup touchend", swipeEnd);
+ jQuery("html").on("mousemove touchmove", swiping);
+ })();
+
+ function swipeStart(event) {
+ if (options.useOnlyTouch && !event.originalEvent.touches) {
+ return;
+ }
+
+ if (event.originalEvent.touches) {
+ event = event.originalEvent.touches[0];
+ }
+
+ if (swipeState === 0) {
+ swipeState = 1;
+ startX = event.clientX;
+ startY = event.clientY;
+ }
+ }
+
+ function swipeEnd(event) {
+ if (swipeState === 2) {
+ swipeState = 0;
+
+ if (
+ Math.abs(pixelOffsetX) > Math.abs(pixelOffsetY) &&
+ Math.abs(pixelOffsetX) > options.swipeThreshold
+ ) {
+ // Horizontal Swipe
+ if (pixelOffsetX < 0) {
+ swipeTarget.trigger(jQuery.Event("swipeLeft.sd"));
+ } else {
+ swipeTarget.trigger(jQuery.Event("swipeRight.sd"));
+ }
+ } else if (Math.abs(pixelOffsetY) > options.swipeThreshold) {
+ // Vertical swipe
+ if (pixelOffsetY < 0) {
+ swipeTarget.trigger(jQuery.Event("swipeUp.sd"));
+ } else {
+ swipeTarget.trigger(jQuery.Event("swipeDown.sd"));
+ }
+ }
+ }
+ }
+
+ function swiping(event) {
+ // If swipe don't occuring, do nothing.
+ if (swipeState !== 1) return;
+
+ if (event.originalEvent.touches) {
+ event = event.originalEvent.touches[0];
+ }
+
+ var swipeOffsetX = event.clientX - startX;
+ var swipeOffsetY = event.clientY - startY;
+
+ if (
+ Math.abs(swipeOffsetX) > options.swipeThreshold ||
+ Math.abs(swipeOffsetY) > options.swipeThreshold
+ ) {
+ swipeState = 2;
+ pixelOffsetX = swipeOffsetX;
+ pixelOffsetY = swipeOffsetY;
+ }
+ }
+
+ return swipeTarget; // Return element available for chaining.
+ }
+
+
+ // Destroy jBox and remove it from DOM
+
+ jBox.prototype.destroy = function ()
+ {
+ // Detach from attached elements
+ this.detach();
+
+ // If jBox is open, close without delay
+ this.isOpen && this.close({ignoreDelay: true});
+
+ // Remove wrapper
+ this.wrapper && this.wrapper.remove();
+
+ // Remove overlay
+ this.overlay && this.overlay.remove();
+
+ // Remove styles
+ this._styles && this._styles.remove();
+
+ // Tell the jBox instance it is destroyed
+ this.isDestroyed = true;
+
+ return this;
+ };
+
+
+ // Get a unique ID for jBoxes
+
+ jBox._getUniqueID = (function ()
+ {
+ var i = 1;
+ return function () { return i++; };
+ }());
+
+
+ // Get a unique ID for animating elements
+
+ jBox._getUniqueElementID = (function ()
+ {
+ var i = 1;
+ return function () { return i++; };
+ }());
+
+
+ // Function to create jBox plugins
+
+ jBox._pluginOptions = {};
+ jBox.plugin = function (type, options)
+ {
+ jBox._pluginOptions[type] = options;
+ };
+
+
+ // Make jBox usable with jQuery selectors
+
+ jQuery.fn.jBox = function (type, options) {
+ // Variables type and object are required
+ !type && (type = {});
+ !options && (options = {});
+
+ // Return a new instance of jBox with the selector as attached element
+ return new jBox(type, jQuery.extend(options, {
+ attach: this
+ }));
+ };
+
+ return jBox;
+
+};
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], function (jQuery) {
+ return (root.jBox = factory(jQuery));
+ });
+ } else if (typeof module === 'object' && module.exports) {
+ module.exports = (root.jBox = factory(require('jquery')));
+ } else {
+ root.jBox = factory(root.jQuery);
+ }
+}(this, function (jQuery) {
+ var jBox = jBoxWrapper(jQuery);
+ try { typeof jBoxConfirmWrapper !== 'undefined' && jBoxConfirmWrapper && jBoxConfirmWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ try { typeof jBoxImageWrapper !== 'undefined' && jBoxImageWrapper && jBoxImageWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ try { typeof jBoxNoticeWrapper !== 'undefined' && jBoxNoticeWrapper && jBoxNoticeWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ return jBox;
+}));
+
+//# sourceMappingURL=jBox.js.map
diff --git a/dist/jBox.min.css b/dist/jBox.min.css
new file mode 100755
index 0000000..7091b9c
--- /dev/null
+++ b/dist/jBox.min.css
@@ -0,0 +1 @@
+.jBox-wrapper{text-align:left;box-sizing:border-box}.jBox-container,.jBox-content,.jBox-title{position:relative;word-break:break-word;box-sizing:border-box}.jBox-container{background:#fff}.jBox-content{padding:8px 12px;overflow-x:hidden;overflow-y:auto;transition:opacity .2s}.jBox-footer{box-sizing:border-box}.jBox-Mouse .jBox-container,.jBox-Tooltip .jBox-container{border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.25)}.jBox-Mouse .jBox-title,.jBox-Tooltip .jBox-title{padding:8px 10px 0;font-weight:700}.jBox-Mouse.jBox-hasTitle .jBox-content,.jBox-Tooltip.jBox-hasTitle .jBox-content{padding-top:5px}.jBox-Mouse{pointer-events:none}.jBox-pointer{position:absolute;overflow:hidden;box-sizing:border-box}.jBox-pointer:after{content:'';width:20px;height:20px;position:absolute;background:#fff;transform:rotate(45deg);box-sizing:border-box}.jBox-pointer-top{top:0}.jBox-pointer-top:after{left:5px;top:6px;box-shadow:-1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-right{right:0}.jBox-pointer-right:after{top:5px;right:6px;box-shadow:1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-left{left:0}.jBox-pointer-left:after{top:5px;left:6px;box-shadow:-1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom{bottom:0}.jBox-pointer-bottom:after{left:5px;bottom:6px;box-shadow:1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom,.jBox-pointer-top{width:30px;height:12px}.jBox-pointer-left,.jBox-pointer-right{width:12px;height:30px}.jBox-Modal .jBox-container{border-radius:4px}.jBox-Modal .jBox-container,.jBox-Modal.jBox-closeButton-box:before{box-shadow:0 3px 15px rgba(0,0,0,.4),0 0 5px rgba(0,0,0,.4)}.jBox-Modal .jBox-content{padding:15px 20px}.jBox-Modal .jBox-title{border-radius:4px 4px 0 0;padding:15px 20px;background:#fafafa;border-bottom:1px solid #eee}.jBox-Modal.jBox-closeButton-title .jBox-title{padding-right:65px}.jBox-Modal .jBox-footer{border-radius:0 0 4px 4px}.jBox-closeButton{z-index:1;cursor:pointer;position:absolute;box-sizing:border-box}.jBox-closeButton svg{position:absolute;top:50%;right:50%}.jBox-closeButton path{fill:#aaa;transition:fill .2s}.jBox-closeButton:hover path{fill:#888}.jBox-overlay .jBox-closeButton{top:0;right:0;width:40px;height:40px}.jBox-overlay .jBox-closeButton svg{width:20px;height:20px;margin-top:-10px;margin-right:-10px}.jBox-overlay .jBox-closeButton path{fill:#ddd}.jBox-overlay .jBox-closeButton:hover path{fill:#fff}.jBox-closeButton-title .jBox-closeButton{top:0;right:0;bottom:0;width:50px}.jBox-closeButton-title svg{width:12px;height:12px;margin-top:-6px;margin-right:-6px}.jBox-closeButton-box{box-sizing:border-box}.jBox-closeButton-box .jBox-closeButton{top:-8px;right:-10px;width:24px;height:24px;background:#fff;border-radius:50%}.jBox-closeButton-box .jBox-closeButton svg{width:10px;height:10px;margin-top:-5px;margin-right:-5px}.jBox-closeButton-box:before{content:'';position:absolute;top:-8px;right:-10px;width:24px;height:24px;border-radius:50%;box-shadow:0 0 5px rgba(0,0,0,.3)}.jBox-closeButton-box.jBox-pointerPosition-top:before{top:5px}.jBox-closeButton-box.jBox-pointerPosition-right:before{right:2px}.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton{background:#fafafa}.jBox-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.82)}.jBox-footer{background:#fafafa;border-top:1px solid #eee;padding:8px 10px;border-radius:0 0 3px 3px}body[class*=" jBox-blockScroll-"],body[class^=jBox-blockScroll-]{overflow:hidden}.jBox-draggable{cursor:move}@keyframes jBoxLoading{to{transform:rotate(360deg)}}.jBox-loading .jBox-content{opacity:.2}.jBox-loading-spinner .jBox-content{min-height:38px!important;min-width:38px!important;opacity:0}.jBox-spinner{box-sizing:border-box;position:absolute;top:50%;left:50%;width:24px;height:24px;margin-top:-12px;margin-left:-12px}.jBox-spinner:before{display:block;box-sizing:border-box;content:'';width:24px;height:24px;border-radius:50%;border:2px solid rgba(0,0,0,.2);border-top-color:rgba(0,0,0,.8);animation:jBoxLoading .6s linear infinite}.jBox-countdown{border-radius:4px 4px 0 0;z-index:0;background:#000;opacity:.2;position:absolute;top:0;left:0;right:0;height:3px;overflow:hidden}.jBox-countdown-inner{top:0;right:0;width:100%;height:3px;position:absolute;background:#fff}[class*=" jBox-animated-"],[class^=jBox-animated-]{animation-fill-mode:both}@keyframes jBox-tada{0%{transform:scale(1)}10%,20%{transform:scale(.8) rotate(-4deg)}30%,50%,70%,90%{transform:scale(1.2) rotate(4deg)}40%,60%,80%{transform:scale(1.2) rotate(-4deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tada{animation:jBox-tada 1s}@keyframes jBox-tadaSmall{0%{transform:scale(1)}10%,20%{transform:scale(.9) rotate(-2deg)}30%,50%,70%,90%{transform:scale(1.1) rotate(2deg)}40%,60%,80%{transform:scale(1.1) rotate(-2deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tadaSmall{animation:jBox-tadaSmall 1s}@keyframes jBox-flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.jBox-animated-flash{animation:jBox-flash .5s}@keyframes jBox-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-6px)}40%,80%{transform:translateX(6px)}}.jBox-animated-shake{animation:jBox-shake .4s}@keyframes jBox-pulseUp{0%{transform:scale(1)}50%{transform:scale(1.15)}100%{transform:scale(1)}}.jBox-animated-pulseUp{animation:jBox-pulseUp .25s}@keyframes jBox-pulseDown{0%{transform:scale(1)}50%{transform:scale(.85)}100%{transform:scale(1)}}.jBox-animated-pulseDown{animation:jBox-pulseDown .25s}@keyframes jBox-popIn{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.jBox-animated-popIn{animation:jBox-popIn .25s}@keyframes jBox-popOut{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(0)}}.jBox-animated-popOut{animation:jBox-popOut .25s}@keyframes jBox-fadeIn{0%{opacity:0}100%{opacity:1}}.jBox-animated-fadeIn{animation:jBox-fadeIn .2s}@keyframes jBox-fadeOut{0%{opacity:1}100%{opacity:0}}.jBox-animated-fadeOut{animation:jBox-fadeOut .2s}@keyframes jBox-slideUp{0%{transform:translateY(0)}100%{transform:translateY(-300px);opacity:0}}.jBox-animated-slideUp{animation:jBox-slideUp .4s}@keyframes jBox-slideRight{0%{transform:translateX(0)}100%{transform:translateX(300px);opacity:0}}.jBox-animated-slideRight{animation:jBox-slideRight .4s}@keyframes jBox-slideDown{0%{transform:translateY(0)}100%{transform:translateY(300px);opacity:0}}.jBox-animated-slideDown{animation:jBox-slideDown .4s}@keyframes jBox-slideLeft{0%{transform:translateX(0)}100%{transform:translateX(-300px);opacity:0}}.jBox-animated-slideLeft{animation:jBox-slideLeft .4s}
\ No newline at end of file
diff --git a/dist/jBox.min.js b/dist/jBox.min.js
new file mode 100755
index 0000000..cc74d86
--- /dev/null
+++ b/dist/jBox.min.js
@@ -0,0 +1 @@
+function jBoxWrapper(v){function h(t,i){return this.options={id:null,width:"auto",height:"auto",minWidth:null,minHeight:null,maxWidth:null,maxHeight:null,responsiveWidth:!0,responsiveHeight:!0,responsiveMinWidth:100,responsiveMinHeight:100,attach:null,trigger:"click",preventDefault:!1,content:null,getContent:null,title:null,getTitle:null,footer:null,isolateScroll:!0,ajax:{url:null,data:"",reload:!1,getURL:"data-url",getData:"data-ajax",setContent:!0,loadingClass:!0,spinner:!0,spinnerDelay:300,spinnerReposition:!0},cancelAjaxOnClose:!0,target:null,position:{x:"center",y:"center"},outside:null,offset:0,attributes:{x:"left",y:"top"},fixed:!1,adjustPosition:!0,adjustTracker:!1,adjustDistance:5,reposition:!0,repositionOnOpen:!0,repositionOnContent:!0,holdPosition:!0,pointer:!1,pointTo:"target",fade:180,animation:null,theme:"Default",addClass:null,overlay:!1,overlayClass:null,zIndex:1e4,delayOpen:0,delayClose:0,closeOnEsc:!1,closeOnClick:!1,closeOnMouseleave:!1,closeButton:!1,appendTo:v("body"),createOnInit:!1,blockScroll:!1,blockScrollAdjust:!0,draggable:!1,dragOver:!0,autoClose:!1,delayOnHover:!1,showCountdown:!1,preloadAudio:!0,audio:null,volume:100,onInit:null,onAttach:null,onPosition:null,onCreated:null,onOpen:null,onOpenComplete:null,onClose:null,onCloseComplete:null,onDragStart:null,onDragEnd:null},this._pluginOptions={Tooltip:{getContent:"title",trigger:"mouseenter",position:{x:"center",y:"top"},outside:"y",pointer:!0},Mouse:{responsiveWidth:!1,responsiveHeight:!1,adjustPosition:"flip",target:"mouse",trigger:"mouseenter",position:{x:"right",y:"bottom"},outside:"xy",offset:5},Modal:{target:v(window),fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"overlay",closeButton:!0,overlay:!0,animation:"zoomIn"}},this.options=v.extend(!0,this.options,this._pluginOptions[t]||h._pluginOptions[t],i),"string"==v.type(t)&&(this.type=t),this.isTouchDevice=function(){var t=" -webkit- -moz- -o- -ms- ".split(" ");if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)return!0;var i,t=["(",t.join("touch-enabled),("),"heartz",")"].join("");return i=t,window.matchMedia(i).matches}(),this.isTouchDevice&&"mouseenter"===this.options.trigger&&!1===this.options.closeOnClick&&(this.options.closeOnClick="body"),this._fireEvent=function(t,i){this.options["_"+t]&&this.options["_"+t].bind(this)(i),this.options[t]&&this.options[t].bind(this)(i)},null===this.options.id&&(this.options.id="jBox"+h._getUniqueID()),this.id=this.options.id,("center"==this.options.position.x&&"x"==this.options.outside||"center"==this.options.position.y&&"y"==this.options.outside)&&(this.options.outside=null),"target"!=this.options.pointTo||this.options.outside&&"xy"!=this.options.outside||(this.options.pointer=!1),"object"!=v.type(this.options.offset)?this.options.offset={x:this.options.offset,y:this.options.offset}:this.options.offset=v.extend({x:0,y:0},this.options.offset),"object"!=v.type(this.options.adjustDistance)?this.options.adjustDistance={top:this.options.adjustDistance,right:this.options.adjustDistance,bottom:this.options.adjustDistance,left:this.options.adjustDistance}:this.options.adjustDistance=v.extend({top:5,left:5,right:5,bottom:5},this.options.adjustDistance),this.outside=!(!this.options.outside||"xy"==this.options.outside)&&this.options.position[this.options.outside],this.align=this.outside||("center"!=this.options.position.y&&"number"!=v.type(this.options.position.y)?this.options.position.x:"center"!=this.options.position.x&&"number"!=v.type(this.options.position.x)?this.options.position.y:this.options.attributes.x),h.zIndexMax=Math.max(h.zIndexMax||0,"auto"===this.options.zIndex?1e4:this.options.zIndex),"auto"===this.options.zIndex&&(this.adjustZIndexOnOpen=!0,this.options.zIndex=h.zIndexMax+=2,this.trueModal=this.options.overlay),this._getOpp=function(t){return{left:"right",right:"left",top:"bottom",bottom:"top",x:"y",y:"x"}[t]},this._getXY=function(t){return{left:"x",right:"x",top:"y",bottom:"y",center:"x"}[t]},this._getTL=function(t){return{left:"left",right:"left",top:"top",bottom:"top",center:"left",x:"left",y:"top"}[t]},this._getInt=function(t,i){return"auto"==t?"auto":t&&"string"==v.type(t)&&"%"==t.slice(-1)?v(window)["height"==i?"innerHeight":"innerWidth"]()*parseInt(t.replace("%",""))/100:t},this._createSVG=function(t,i){var o=document.createElementNS("http://www.w3.org/2000/svg",t);return v.each(i,function(t,i){o.setAttribute(i[0],i[1]||"")}),o},this._isolateScroll=function(e){e&&e.length&&e.on("DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll",function(t){var i=t.wheelDelta||t.originalEvent&&t.originalEvent.wheelDelta||-t.detail,o=0<=this.scrollTop+e.outerHeight()-this.scrollHeight,s=this.scrollTop<=0;(i<0&&o||0",{id:this.id,class:"jBox-wrapper"+(this.type?" jBox-"+this.type:"")+(this.options.theme?" jBox-"+this.options.theme:"")+(this.options.addClass?" "+this.options.addClass:"")}).css({position:this.options.fixed?"fixed":"absolute",display:"none",opacity:0,zIndex:this.options.zIndex}).data("jBox",this),this.options.closeOnMouseleave&&this.wrapper.on("mouseleave",function(t){!this.source||t.relatedTarget!=this.source[0]&&-1===v.inArray(this.source[0],v(t.relatedTarget).parents("*"))&&this.close()}.bind(this)),"box"==this.options.closeOnClick&&this.wrapper.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),this.container=v('
').appendTo(this.wrapper),this.content=v('
').appendTo(this.container),this.options.footer&&(this.footer=v('').append(this.options.footer).appendTo(this.container)),this.options.isolateScroll&&this._isolateScroll(this.content),this.options.closeButton&&((t=this._createSVG("svg",[["viewBox","0 0 24 24"]])).appendChild(this._createSVG("path",[["d","M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z"]])),this.closeButton=v('
').on("click tap",function(t){this.close({ignoreDelay:!0})}.bind(this)).append(t),"box"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay||this.options.title||this.options.getTitle)||(this.wrapper.addClass("jBox-closeButton-box"),this.closeButton.appendTo(this.container))),this.wrapper.appendTo(this.options.appendTo),this.wrapper.find(".jBox-closeButton").length&&v.each(["top","right","bottom","left"],function(t,i){this.wrapper.find(".jBox-closeButton").css(i)&&"auto"!=this.wrapper.find(".jBox-closeButton").css(i)&&(this.options.adjustDistance[i]=Math.max(this.options.adjustDistance[i],this.options.adjustDistance[i]+-1*((parseInt(this.wrapper.find(".jBox-closeButton").css(i))||0)+(parseInt(this.container.css("border-"+i+"-width"))||0))))}.bind(this)),this.options.pointer&&(this.pointer={position:"target"!=this.options.pointTo?this.options.pointTo:this._getOpp(this.outside),xy:"target"!=this.options.pointTo?this._getXY(this.options.pointTo):this._getXY(this.outside),align:"center",offset:0},this.pointer.element=v('
').appendTo(this.wrapper),this.pointer.dimensions={x:this.pointer.element.outerWidth(),y:this.pointer.element.outerHeight()},"string"==v.type(this.options.pointer)&&((t=this.options.pointer.split(":"))[0]&&(this.pointer.align=t[0]),t[1]&&(this.pointer.offset=parseInt(t[1]))),this.pointer.alignAttribute="x"==this.pointer.xy?"bottom"==this.pointer.align?"bottom":"top":"right"==this.pointer.align?"right":"left",this.wrapper.css("padding-"+this.pointer.position,this.pointer.dimensions[this.pointer.xy]),this.pointer.element.css(this.pointer.alignAttribute,"center"==this.pointer.align?"50%":0).css("margin-"+this.pointer.alignAttribute,this.pointer.offset),this.pointer.margin={},this.pointer.margin["margin-"+this.pointer.alignAttribute]=this.pointer.offset,"center"==this.pointer.align&&this.pointer.element.css("transform","translate("+("y"==this.pointer.xy?-.5*this.pointer.dimensions.x+"px":0)+", "+("x"==this.pointer.xy?-.5*this.pointer.dimensions.y+"px":0)+")"),this.pointer.element.css("x"==this.pointer.xy?"width":"height",parseInt(this.pointer.dimensions[this.pointer.xy])+parseInt(this.container.css("border-"+this.pointer.alignAttribute+"-width"))),this.wrapper.addClass("jBox-pointerPosition-"+this.pointer.position)),this.setContent(this.options.content,!0),this.setTitle(this.options.title,!0),this.options.draggable&&this._draggable(),this._fireEvent("onCreated"))},this.options.createOnInit&&this._create(),this.options.attach&&this.attach(),this._attachEvents=function(){this.options.delayOnHover&&v("#"+this.id).on("mouseenter",function(t){this.isHovered=!0}.bind(this)),this.options.delayOnHover&&v("#"+this.id).on("mouseleave",function(t){this.isHovered=!1}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&!this.fixed&&this.outside&&(this.options.adjustTracker&&v(window).on("scroll.jBox-"+this.id,function(t){this.position()}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&v(window).on("resize.jBox-"+this.id,function(t){this.position()}.bind(this))),"mouse"==this.options.target&&v("body").on("mousemove.jBox-"+this.id,function(t){this.position({mouseTarget:{top:t.pageY,left:t.pageX}})}.bind(this))},this._detachEvents=function(){this.options.closeOnEsc&&v(document).off("keyup.jBox-"+this.id),!0!==this.options.closeOnClick&&"body"!=this.options.closeOnClick||v(document).off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.options.adjustTracker&&v(window).off("scroll.jBox-"+this.id),(this.options.adjustPosition||this.options.reposition)&&v(window).off("resize.jBox-"+this.id),"mouse"==this.options.target&&v("body").off("mousemove.jBox-"+this.id)},this._showOverlay=function(){this.overlay||(this.overlay=v('
').addClass("jBox-overlay"+(this.type?" jBox-overlay-"+this.type:"")).css({display:"none",opacity:0,zIndex:this.options.zIndex-1}).appendTo(this.options.appendTo),this.options.overlayClass&&this.overlay.addClass(this.options.overlayClass),"overlay"!=this.options.closeButton&&!0!==this.options.closeButton||this.overlay.append(this.closeButton),"overlay"==this.options.closeOnClick&&this.overlay.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),v("#"+this.id+"-overlay .jBox-closeButton").length&&(this.options.adjustDistance.top=Math.max(v("#"+this.id+"-overlay .jBox-closeButton").outerHeight(),this.options.adjustDistance.top))),!0===this.adjustZIndexOnOpen&&this.overlay.css("zIndex",parseInt(this.wrapper.css("zIndex"),10)-1),"block"!=this.overlay.css("display")&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.overlay.css({display:"block"})}.bind(this)}):this.overlay.css({display:"block",opacity:1}))},this._hideOverlay=function(){this.overlay&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:0},{queue:!1,duration:this.options.fade,complete:function(){this.overlay.css({display:"none"})}.bind(this)}):this.overlay.css({display:"none",opacity:0}))},this._exposeDimensions=function(){this.wrapper.css({top:-1e4,left:-1e4,right:"auto",bottom:"auto"});var t={x:this.wrapper.outerWidth(),y:this.wrapper.outerHeight()};return this.wrapper.css({top:"auto",left:"auto"}),t},this._generateAnimationCSS=function(){if("object"!=v.type(this.options.animation)&&(this.options.animation={pulse:{open:"pulse",close:"zoomOut"},zoomIn:{open:"zoomIn",close:"zoomIn"},zoomOut:{open:"zoomOut",close:"zoomOut"},move:{open:"move",close:"move"},slide:{open:"slide",close:"slide"},flip:{open:"flip",close:"flip"},tada:{open:"tada",close:"zoomOut"}}[this.options.animation]),!this.options.animation)return null;this.options.animation.open&&(this.options.animation.open=this.options.animation.open.split(":")),this.options.animation.close&&(this.options.animation.close=this.options.animation.close.split(":")),this.options.animation.openDirection=this.options.animation.open[1]||null,this.options.animation.closeDirection=this.options.animation.close[1]||null,this.options.animation.open&&(this.options.animation.open=this.options.animation.open[0]),this.options.animation.close&&(this.options.animation.close=this.options.animation.close[0]),this.options.animation.open&&(this.options.animation.open+="Open"),this.options.animation.close&&(this.options.animation.close+="Close");var a={pulse:{duration:350,css:[["0%","scale(1)"],["50%","scale(1.1)"],["100%","scale(1)"]]},zoomInOpen:{duration:this.options.fade||180,css:[["0%","scale(0.9)"],["100%","scale(1)"]]},zoomInClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(0.9)"]]},zoomOutOpen:{duration:this.options.fade||180,css:[["0%","scale(1.1)"],["100%","scale(1)"]]},zoomOutClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(1.1)"]]},moveOpen:{duration:this.options.fade||180,positions:{top:{"0%":-12},right:{"0%":12},bottom:{"0%":12},left:{"0%":-12}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},moveClose:{duration:this.options.fade||180,timing:"ease-in",positions:{top:{"100%":-12},right:{"100%":12},bottom:{"100%":12},left:{"100%":-12}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},slideOpen:{duration:400,positions:{top:{"0%":-400},right:{"0%":400},bottom:{"0%":400},left:{"0%":-400}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},slideClose:{duration:400,timing:"ease-in",positions:{top:{"100%":-400},right:{"100%":400},bottom:{"100%":400},left:{"100%":-400}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},flipOpen:{duration:600,css:[["0%","perspective(400px) rotateX(90deg)"],["40%","perspective(400px) rotateX(-15deg)"],["70%","perspective(400px) rotateX(15deg)"],["100%","perspective(400px) rotateX(0deg)"]]},flipClose:{duration:this.options.fade||300,css:[["0%","perspective(400px) rotateX(0deg)"],["100%","perspective(400px) rotateX(90deg)"]]},tada:{duration:800,css:[["0%","scale(1)"],["10%, 20%","scale(0.9) rotate(-3deg)"],["30%, 50%, 70%, 90%","scale(1.1) rotate(3deg)"],["40%, 60%, 80%","scale(1.1) rotate(-3deg)"],["100%","scale(1) rotate(0)"]]}};v.each(["pulse","tada"],function(t,i){a[i+"Open"]=a[i+"Close"]=a[i]});var s=function(s,e){var n="@keyframes jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {";return v.each(a[this.options.animation[s]].css,function(t,i){var o=e?i[1].replace("%XY",this._getXY(e).toUpperCase()):i[1];a[this.options.animation[s]].positions&&(o=o.replace("%V",a[this.options.animation[s]].positions[e][i[0]])),n+=i[0]+" {transform:"+o+";}"}.bind(this)),n+="}",n+=".jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {",n+="animation-duration: "+a[this.options.animation[s]].duration+"ms;",n+="animation-name: jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+";",n+=a[this.options.animation[s]].timing?"animation-timing-function: "+a[this.options.animation[s]].timing+";":"",n+="}"}.bind(this);this._animationCSS="",v.each(["open","close"],function(t,o){if(!this.options.animation[o]||!a[this.options.animation[o]]||"close"==o&&!this.options.fade)return"";a[this.options.animation[o]].positions?v.each(["top","right","bottom","left"],function(t,i){this._animationCSS+=s(o,i)}.bind(this)):this._animationCSS+=s(o)}.bind(this))},this.options.animation&&this._generateAnimationCSS(),this._blockBodyClick=function(){this.blockBodyClick=!0,setTimeout(function(){this.blockBodyClick=!1}.bind(this),10)},this._animate=function(t){if(t=t||(this.isOpen?"open":"close"),!this.options.fade&&"close"==t)return null;var i=this.options.animation[t+"Direction"]||("center"!=this.align?this.align:this.options.attributes.x);this.flipped&&this._getXY(i)==this._getXY(this.align)&&(i=this._getOpp(i));var o="jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+" jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+"-"+i;this.wrapper.addClass(o);i=1e3*parseFloat(this.wrapper.css("animation-duration"));"close"==t&&(i=Math.min(i,this.options.fade)),setTimeout(function(){this.wrapper&&this.wrapper.removeClass(o)}.bind(this),i)},this._abortAnimation=function(){var t=this.wrapper.attr("class").split(" ").filter(function(t){return 0!==t.lastIndexOf("jBox-"+this.id+"-animation",0)}.bind(this));this.wrapper.attr("class",t.join(" "))},(this.options.responsiveWidth||this.options.responsiveHeight)&&v(window).on("resize.responsivejBox-"+this.id,function(t){this.isOpen&&this.position()}.bind(this)),"string"===v.type(this.options.preloadAudio)&&(this.options.preloadAudio=[this.options.preloadAudio]),"string"===v.type(this.options.audio)&&(this.options.audio={open:this.options.audio}),"number"===v.type(this.options.volume)&&(this.options.volume={open:this.options.volume,close:this.options.volume}),!0===this.options.preloadAudio&&this.options.audio&&(this.options.preloadAudio=[],v.each(this.options.audio,function(t,i){this.options.preloadAudio.push(i+".mp3"),this.options.preloadAudio.push(i+".ogg")}.bind(this))),this.options.preloadAudio.length&&v.each(this.options.preloadAudio,function(t,i){var o=new Audio;o.src=i,o.preload="auto"}),this._fireEvent("onInit"),this}var t,i;return h.prototype.attach=function(t,s){return t=t||this.options.attach,"string"==v.type(t)&&(t=v(t)),s=s||this.options.trigger,t&&t.length&&v.each(t,function(t,o){(o=v(o)).data("jBox-attached-"+this.id)||("title"==this.options.getContent&&null!=o.attr("title")&&o.data("jBox-getContent",o.attr("title")).removeAttr("title"),this.attachedElements||(this.attachedElements=[]),this.attachedElements.push(o[0]),o.on(s+".jBox-attach-"+this.id,function(t){var i;this.timer&&clearTimeout(this.timer),"mouseenter"==s&&this.isOpen&&this.source[0]==o[0]||(this.isOpen&&this.source&&this.source[0]!=o[0]&&(i=!0),this.source=o,this.options.target||(this.target=o),"click"==s&&this.options.preventDefault&&t.preventDefault(),this["click"!=s||i?"open":"toggle"]())}.bind(this)),"mouseenter"==this.options.trigger&&o.on("mouseleave",function(t){if(!this.wrapper)return null;this.options.closeOnMouseleave&&(t.relatedTarget==this.wrapper[0]||v(t.relatedTarget).parents("#"+this.id).length)||this.close()}.bind(this)),o.data("jBox-attached-"+this.id,s),this._fireEvent("onAttach",o))}.bind(this)),this},h.prototype.detach=function(t){return(t=t||(this.attachedElements||[]))&&t.length&&v.each(t,function(t,i){(i=v(i)).data("jBox-attached-"+this.id)&&(i.off(i.data("jBox-attached-"+this.id)+".jBox-attach-"+this.id),i.data("jBox-attached-"+this.id,null)),this.attachedElements=v.grep(this.attachedElements,function(t){return t!=i[0]})}.bind(this)),this},h.prototype.setTitle=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();return this.title||(this.titleContainer=v('
'),this.title=v("
").appendTo(this.titleContainer),"title"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay)||(this.wrapper.addClass("jBox-closeButton-title"),this.closeButton.appendTo(this.titleContainer)),this.titleContainer.insertBefore(this.content),this._setTitleWidth()),this.wrapper[t?"addClass":"removeClass"]("jBox-hasTitle"),this.title.html(t),s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setContent=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();switch(this.content.children("[data-jbox-content-appended]").appendTo("body").css({display:"none"}),v.type(t)){case"string":this.content.html(t);break;case"object":t&&(t instanceof v||t.constructor.prototype.jquery)?(this.content.html(""),t.attr("data-jbox-content-appended",1).appendTo(this.content).css({display:"block"})):this.content.html(JSON.stringify(t))}return s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setDimensions=function(t,i,o){this.wrapper||this._create(),this.content.css(t,this._getInt(i=null==i?"auto":i)),"width"==t&&this._setTitleWidth(),this.options[t]=i,null!=o&&!o||this.position()},h.prototype.setWidth=function(t,i){this.setDimensions("width",t,i)},h.prototype.setHeight=function(t,i){this.setDimensions("height",t,i)},h.prototype.position=function(o){if(o=v.extend(!0,this.options,o=o||{}),this.target=o.target||this.target||v(window),this.target instanceof v||"mouse"==this.target||(this.target=v(this.target)),!this.target.length)return this;this.content.css({width:this._getInt(o.width,"width"),height:this._getInt(o.height,"height"),minWidth:this._getInt(o.minWidth,"width"),minHeight:this._getInt(o.minHeight,"height"),maxWidth:this._getInt(o.maxWidth,"width"),maxHeight:this._getInt(o.maxHeight,"height")}),this._setTitleWidth();var s=this._exposeDimensions();"mouse"==this.target||this.target.data("jBox-"+this.id+"-fixed")||this.target.data("jBox-"+this.id+"-fixed",this.target[0]!=v(window)[0]&&("fixed"==this.target.css("position")||0a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),(o.responsiveWidth||o.responsiveHeight)&&(m=function(){var t;o.responsiveWidth&&s.x>a[h.x||"x"]&&(t=a[h.x||"x"]-(this.pointer&&n&&"x"==o.outside?this.pointer.dimensions.x:0)-parseInt(this.container.css("border-left-width"))-parseInt(this.container.css("border-right-width")),this.content.css({width:t>this.options.responsiveMinWidth?t:null,minWidth:ta[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),f=function(){var t;o.responsiveHeight&&s.y>a[h.y||"y"]&&(t=function(){return this.titleContainer||this.footer?("none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),this.wrapper.css("display","none")):t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),t||0):0;var t}.bind(this),t=a[h.y||"y"]-(this.pointer&&n&&"y"==o.outside?this.pointer.dimensions.y:0)-t()-parseInt(this.container.css("border-top-width"))-parseInt(this.container.css("border-bottom-width")),this.content.css({height:t>this.options.responsiveMinHeight?t:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveHeight&&f(),o.responsiveHeight&&!r.x&&h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),o.adjustPosition&&"move"!=o.adjustPosition&&(r.x&&m(),r.y&&f()));var p={},l=function(t){if("number"!=v.type(o.position[t])){var i=o.attributes[t]="x"==t?"left":"top";if(p[i]=e[i],"center"==o.position[t])return p[i]+=Math.ceil((e[t]-s[t])/2),void("mouse"!=this.target&&this.target[0]&&this.target[0]==v(window)[0]&&(p[i]+=.5*(o.adjustDistance[i]-o.adjustDistance[this._getOpp(i)])));i!=o.position[t]&&(p[i]+=e[t]-s[t]),o.outside!=t&&"xy"!=o.outside||(p[i]+=s[t]*(i!=o.position[t]?1:-1))}else p[o.attributes[t]]=o.position[t]}.bind(this);if(l("x"),l("y"),this.pointer&&"target"==o.pointTo&&"number"!=v.type(o.position.x)&&"number"!=v.type(o.position.y)&&(x=0,"center"===this.pointer.align?"center"!=o.position[this._getOpp(o.outside)]&&(x+=s[this._getOpp(o.outside)]/2):"center"===o.position[this._getOpp(o.outside)]?x+=(s[this._getOpp(o.outside)]/2-this.pointer.dimensions[this._getOpp(o.outside)]/2)*(this.pointer.align==this._getTL(this.pointer.align)?1:-1):x+=this.pointer.align!=o.position[this._getOpp(o.outside)]?s[this._getOpp(o.outside)]*(-1!==v.inArray(this.pointer.align,["top","left"])?1:-1)+this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==v.inArray(this.pointer.align,["top","left"])?-1:1):this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==v.inArray(this.pointer.align,["top","left"])?1:-1),x*=o.position[this._getOpp(o.outside)]==this.pointer.alignAttribute?-1:1,x+=this.pointer.offset*(this.pointer.align==this._getOpp(this._getTL(this.pointer.align))?1:-1),p[this._getTL(this._getOpp(this.pointer.xy))]+=x),p[o.attributes.x]+=o.offset.x,p[o.attributes.y]+=o.offset.y,this.wrapper.css(p),o.adjustPosition){this.positionAdjusted&&(this.pointer&&this.wrapper.css("padding",0).css("padding-"+this._getOpp(this.outside),this.pointer.dimensions[this._getXY(this.outside)]).removeClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).addClass("jBox-pointerPosition-"+this.pointer.position),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+this._getOpp(this.outside)).css(this.pointer.margin),this.positionAdjusted=!1,this.flipped=!1);var d=t.top>p.top-(o.adjustDistance.top||0),c=t.rightp.left-(o.adjustDistance.left||0),i=g?"left":c?"right":null,m=d?"top":u?"bottom":null;if(i||m){if(("Modal"==this.type||"Confirm"==this.type)&&"number"==v.type(this.options.position.x)&&"number"==v.type(this.options.position.y)){var f=0,x=0;return this.options.holdPosition&&(g?f=t.left-(p.left-(o.adjustDistance.left||0)):c&&(f=t.right-(p.left+s.x+(o.adjustDistance.right||0))),d?x=t.top-(p.top-(o.adjustDistance.top||0)):u&&(x=t.bottom-(p.top+s.y+(o.adjustDistance.bottom||0))),this.options.position.x=Math.max(t.top,this.options.position.x+f),this.options.position.y=Math.max(t.left,this.options.position.y+x),l("x"),l("y"),this.wrapper.css(p)),this._fireEvent("onPosition"),this}!0!==o.adjustPosition&&"flip"!==o.adjustPosition||(y=function(t){this.wrapper.css(this._getTL(t),p[this._getTL(t)]+(s[this._getXY(t)]+o.offset[this._getXY(t)]*("top"==t||"left"==t?-2:2)+e[this._getXY(t)])*("top"==t||"left"==t?1:-1)),this.pointer&&this.wrapper.removeClass("jBox-pointerPosition-"+this.pointer.position).addClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).css("padding",0).css("padding-"+t,this.pointer.dimensions[this._getXY(t)]),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+t),this.positionAdjusted=!0,this.flipped=!0}.bind(this),r.x&&y(this.options.position.x),r.y&&y(this.options.position.y));var y="x"==this._getXY(this.outside)?m:i;this.pointer&&"target"==o.pointTo&&"flip"!=o.adjustPosition&&this._getXY(y)==this._getOpp(this._getXY(this.outside))&&(m="center"==this.pointer.align?s[this._getXY(y)]/2-this.pointer.dimensions[this._getOpp(this.pointer.xy)]/2-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))*(y!=this._getTL(y)?-1:1):y==this.pointer.alignAttribute?parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute)):s[this._getXY(y)]-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-this.pointer.dimensions[this._getXY(y)],i=y==this._getTL(y)?t[this._getTL(y)]-p[this._getTL(y)]+o.adjustDistance[y]:-1*(t[this._getOpp(this._getTL(y))]-p[this._getTL(y)]-o.adjustDistance[y]-s[this._getXY(y)]),y==this._getOpp(this._getTL(y))&&p[this._getTL(y)]-i<=m&&0window.innerHeight},this.pageHasScrollbar()){t=this.getElementsToAdjust(t);for(var i=0;i").append(this._animationCSS).appendTo(v("head"))),this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;this.options.closeOnEsc&&v(document).on("keyup.jBox-"+this.id,function(t){27==t.keyCode&&this.close({ignoreDelay:!0})}.bind(this)),!0!==this.options.closeOnClick&&"body"!==this.options.closeOnClick||(v("body").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(t){this.blockBodyClick||"body"==this.options.closeOnClick&&(t.target==this.wrapper[0]||this.wrapper.has(t.target).length)||this.close({ignoreDelay:!0})}.bind(this)),this.isTouchDevice&&v("body > *").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(){return!0}));var i=function(){!0===this.adjustZIndexOnOpen&&(h.zIndexMax=Math.max(parseInt(this.wrapper.css("zIndex"),10),this.options.zIndex,h.zIndexMax||0,h.zIndexMaxDragover||0)+2,this.wrapper.css("zIndex",h.zIndexMax),this.options.zIndex=h.zIndexMax),this.source&&this.options.getTitle&&this.source.attr(this.options.getTitle)&&this.setTitle(this.source.attr(this.options.getTitle),!0),this.source&&this.options.getContent&&(this.source.data("jBox-getContent")?this.setContent(this.source.data("jBox-getContent"),!0):this.source.attr(this.options.getContent)?this.setContent(this.source.attr(this.options.getContent),!0):"html"==this.options.getContent&&this.setContent(this.source.html(),!0)),this._fireEvent("onOpen"),(this.options.ajax&&(this.options.ajax.url||this.source&&this.source.attr(this.options.ajax.getURL))&&(!this.ajaxLoaded||this.options.ajax.reload)||t.ajax&&(t.ajax.url||t.ajax.data))&&("strict"==this.options.ajax.reload||!this.source||!this.source.data("jBox-ajax-data")||t.ajax&&(t.ajax.url||t.ajax.data)?this.ajax(t.ajax||null,!0):this.setContent(this.source.data("jBox-ajax-data"))),this.positionedOnOpen&&!this.options.repositionOnOpen||!this.position(t)||(this.positionedOnOpen=!0),this.isClosing&&this._abortAnimation(),this.isOpen||(this.isOpen=!0,this.options.autoClose&&(this.options.delayClose=this.options.autoClose)&&this.close(),this._attachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?h.blockScrollScopes?h.blockScrollScopes++:(h.blockScrollScopes=1,this.unscroll(Array.isArray(this.options.blockScrollAdjust)||"string"==typeof this.options.blockScrollAdjust?this.options.blockScrollAdjust:null)):v("body").addClass("jBox-blockScroll-"+this.id)),this.options.overlay&&(this._showOverlay(),this.position()),this.options.animation&&!this.isClosing&&this._animate("open"),this.options.audio&&this.options.audio.open&&this.audio(this.options.audio.open,this.options.volume.open),this.options.fade?this.wrapper.stop().animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.isOpening=!0,this.wrapper.css({display:"block"})}.bind(this),complete:function(){this._fireEvent("onOpenComplete")}.bind(this),always:function(){this.isOpening=!1,setTimeout(function(){this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)}.bind(this),10)}.bind(this)}):(this.wrapper.css({display:"block",opacity:1}),this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1),this._fireEvent("onOpenComplete")))}.bind(this);return!this.options.delayOpen||this.isOpen||this.isClosing||t.ignoreDelay?i():this.timer=setTimeout(i,this.options.delayOpen),this},h.prototype.close=function(t){if(t=t||{},v("body").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isTouchDevice&&v("body > *").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isDestroyed||this.isClosing)return this;if(this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i,o,s,e=function(){var t;this._fireEvent("onClose"),this.options.cancelAjaxOnClose&&this.cancelAjax(),this.isOpen&&(this.isOpen=!1,this._detachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?(h.blockScrollScopes=h.blockScrollScopes?--h.blockScrollScopes:0)||this.unscroll.reset():v("body").removeClass("jBox-blockScroll-"+this.id)),this.options.overlay&&this._hideOverlay(),this.options.animation&&!this.isOpening&&this._animate("close"),this.options.audio&&this.options.audio.close&&this.audio(this.options.audio.close,this.options.volume.close),(t=this.isTouchDevice&&"mouse"==this.options.target?0:this.options.fade)?this.wrapper.stop().animate({opacity:0},{queue:!1,duration:t,start:function(){this.isClosing=!0}.bind(this),complete:function(){this.wrapper.css({display:"none"}),this._fireEvent("onCloseComplete")}.bind(this),always:function(){this.isClosing=!1}.bind(this)}):(this.wrapper.css({display:"none",opacity:0}),this._fireEvent("onCloseComplete")))}.bind(this);return t.ignoreDelay||this.isTouchDevice&&"mouse"==this.options.target?e():(this.options.delayOnHover||this.options.showCountdown)&&10
'),this.inner=v('
'),t.prepend(this.inner),v("#"+this.id).append(t)),this.countdown=function(){var t=Date.now();i.isHovered||(o-=t-s),s=t,0 ').appendTo(this.container),this.titleContainer&&"absolute"==this.spinner.css("position")&&this.spinner.css({transform:"translateY("+.5*this.titleContainer.outerHeight()+"px)"})}.bind(this),""!=this.content.html()&&h.spinnerDelay||0)),s.bind(this)(t)}.bind(this),h.complete=function(t){this.spinnerDelay&&clearTimeout(this.spinnerDelay),this.wrapper.removeClass("jBox-loading jBox-loading-spinner jBox-loading-spinner-delay"),this.spinner&&this.spinner.length&&this.spinner.remove()&&h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.ajaxLoaded=!0,e.bind(this)(t)}.bind(this),h.success=function(t){h.setContent&&this.setContent(t,!0)&&(i?this.positionOnFadeComplete=!0:this.position()),h.setContent&&this.source&&this.source.data("jBox-ajax-data",t),n.bind(this)(t)}.bind(this),h.error=function(t){a.bind(this)(t)}.bind(this),this.ajaxRequest=v.ajax(h),this},h.prototype.cancelAjax=function(){this.ajaxRequest&&(this.ajaxRequest.abort(),this.ajaxLoaded=!1)},h.prototype.audio=function(t,i){if(!t)return this;var o;(h._audio=!h._audio?{}:h._audio)[t]||(o=v(" "),v(" ",{src:t+".mp3"}).appendTo(o),v(" ",{src:t+".ogg"}).appendTo(o),h._audio[t]=o[0]),h._audio[t].volume=Math.min((null!=i?i:100)/100,1);try{h._audio[t].pause(),h._audio[t].currentTime=0}catch(t){}return h._audio[t].play(),this},h._animationSpeeds={tada:1e3,tadaSmall:1e3,flash:500,shake:400,pulseUp:250,pulseDown:250,popIn:250,popOut:250,fadeIn:200,fadeOut:200,slideUp:400,slideRight:400,slideLeft:400,slideDown:400},h.prototype.animate=function(t,i){i=i||{},this.animationTimeout||(this.animationTimeout={}),i.element||(i.element=this.wrapper),i.element.data("jBox-animating-id")||i.element.data("jBox-animating-id",h._getUniqueElementID()),i.element.data("jBox-animating")&&(i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),this.animationTimeout[i.element.data("jBox-animating-id")]&&clearTimeout(this.animationTimeout[i.element.data("jBox-animating-id")])),i.element.addClass("jBox-animated-"+t).data("jBox-animating","jBox-animated-"+t),this.animationTimeout[i.element.data("jBox-animating-id")]=setTimeout(function(){i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),i.complete&&i.complete()},h._animationSpeeds[t])},h.prototype.swipeDetector=function(i,o){var s=0,e=0,n=0,a=0,h=0;function t(t){o.useOnlyTouch&&!t.originalEvent.touches||(t.originalEvent.touches&&(t=t.originalEvent.touches[0]),0===s&&(s=1,e=t.clientX,n=t.clientY))}function r(t){2===s&&(s=0,Math.abs(a)>Math.abs(h)&&Math.abs(a)>o.swipeThreshold?a<0?i.trigger(v.Event("swipeLeft.sd")):i.trigger(v.Event("swipeRight.sd")):Math.abs(h)>o.swipeThreshold&&(h<0?i.trigger(v.Event("swipeUp.sd")):i.trigger(v.Event("swipeDown.sd"))))}function p(t){var i;1===s&&(i=(t=t.originalEvent.touches?t.originalEvent.touches[0]:t).clientX-e,t=t.clientY-n,(Math.abs(i)>o.swipeThreshold||Math.abs(t)>o.swipeThreshold)&&(s=2,a=i,h=t))}return o=v.extend({swipeThreshold:70,useOnlyTouch:!1},o),i.on("mousedown touchstart",t),v("html").on("mouseup touchend",r),v("html").on("mousemove touchmove",p),i},h.prototype.destroy=function(){return this.detach(),this.isOpen&&this.close({ignoreDelay:!0}),this.wrapper&&this.wrapper.remove(),this.overlay&&this.overlay.remove(),this._styles&&this._styles.remove(),this.isDestroyed=!0,this},h._getUniqueID=(t=1,function(){return t++}),h._getUniqueElementID=(i=1,function(){return i++}),h._pluginOptions={},h.plugin=function(t,i){h._pluginOptions[t]=i},v.fn.jBox=function(t,i){return new h(t=t||{},v.extend(i=i||{},{attach:this}))},h}!function(i,o){"function"==typeof define&&define.amd?define(["jquery"],function(t){return i.jBox=o(t)}):"object"==typeof module&&module.exports?module.exports=i.jBox=o(require("jquery")):i.jBox=o(i.jQuery)}(this,function(t){var i=jBoxWrapper(t);try{"undefined"!=typeof jBoxConfirmWrapper&&jBoxConfirmWrapper&&jBoxConfirmWrapper(i,t)}catch(t){console.error(t)}try{"undefined"!=typeof jBoxImageWrapper&&jBoxImageWrapper&&jBoxImageWrapper(i,t)}catch(t){console.error(t)}try{"undefined"!=typeof jBoxNoticeWrapper&&jBoxNoticeWrapper&&jBoxNoticeWrapper(i,t)}catch(t){console.error(t)}return i});
\ No newline at end of file
diff --git a/Source/plugins/Confirm/jBox.Confirm.css b/dist/plugins/jBox.Confirm.css
old mode 100644
new mode 100755
similarity index 73%
rename from Source/plugins/Confirm/jBox.Confirm.css
rename to dist/plugins/jBox.Confirm.css
index 4fdb49a..20102ba
--- a/Source/plugins/Confirm/jBox.Confirm.css
+++ b/dist/plugins/jBox.Confirm.css
@@ -1,9 +1,14 @@
-
.jBox-Confirm .jBox-content {
text-align: center;
padding: 46px 35px;
}
+@media (max-width: 500px) {
+ .jBox-Confirm .jBox-content {
+ padding: 32px 20px;
+ }
+}
+
.jBox-Confirm-footer {
height: 46px;
}
@@ -28,31 +33,26 @@
color: #666;
}
-.jBox-Confirm-button-cancel:hover,
-.jBox-Confirm-button-cancel:active {
+.jBox-Confirm-button-cancel:hover, .jBox-Confirm-button-cancel:active {
background: #ccc;
}
+.jBox-Confirm-button-cancel:active {
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
+}
+
.jBox-Confirm-button-submit {
border-bottom-right-radius: 4px;
background: #7d0;
color: #fff;
}
-.jBox-Confirm-button-submit:hover,
-.jBox-Confirm-button-submit:active {
+.jBox-Confirm-button-submit:hover, .jBox-Confirm-button-submit:active {
background: #6c0;
}
-.jBox-Confirm-button-cancel:active,
.jBox-Confirm-button-submit:active {
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
}
-@media (max-width: 500px) {
-
- .jBox-Confirm .jBox-content {
- padding: 32px 20px;
- }
-
-}
\ No newline at end of file
+/*# sourceMappingURL=jBox.Confirm.css.map */
diff --git a/dist/plugins/jBox.Confirm.js b/dist/plugins/jBox.Confirm.js
new file mode 100755
index 0000000..500e4fe
--- /dev/null
+++ b/dist/plugins/jBox.Confirm.js
@@ -0,0 +1,97 @@
+/**
+ * jBox Confirm plugin: Add a confirm dialog to links, buttons, etc.
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxConfirmWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Confirm', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-confirm)
+
+ confirmButton: 'Submit', // Text for the submit button
+ cancelButton: 'Cancel', // Text for the cancel button
+ confirm: null, // Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found
+ cancel: null, // Function to execute when clicking the cancel button
+ closeOnConfirm: true, // Close jBox when the user clicks the confirm button
+ target: window,
+ fixed: true,
+ attach: '[data-confirm]',
+ getContent: 'data-confirm',
+ content: 'Do you really want to do this?',
+ minWidth: 360,
+ maxWidth: 500,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: false,
+ closeButton: false,
+ overlay: true,
+ animation: 'zoomIn',
+ preventDefault: true,
+
+
+ // Triggered when jBox is attached to the element
+
+ _onAttach: function (el)
+ {
+ // Extract the href or the onclick event if no submit event is passed
+ if (!this.options.confirm) {
+ var submit = el.attr('onclick') ? el.attr('onclick') : (
+ el.attr('href') ? (
+ el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");' : 'window.location.href = "' + el.attr('href') + '";'
+ ) : '');
+ el.prop('onclick', null).data('jBox-Confirm-submit', submit);
+ }
+ },
+
+
+ // Triggered when jBox was created
+
+ _onCreated: function ()
+ {
+ // Add modal class to mimic jBox modal
+ this.wrapper.addClass('jBox-Modal');
+
+ // Add a footer to the jBox container
+ this.footer = jQuery('');
+
+ jQuery('
')
+ .html(this.options.cancelButton)
+ .on('click tap', function () {
+ this.options.cancel && this.options.cancel(this.source);
+ this.close();
+ }.bind(this))
+ .appendTo(this.footer);
+
+ this.submitButton = jQuery('
')
+ .html(this.options.confirmButton)
+ .appendTo(this.footer);
+
+ this.footer.appendTo(this.container);
+ },
+
+
+ // Triggered when jBox is opened
+
+ _onOpen: function ()
+ {
+ // Set the new action for the submit button
+ this.submitButton
+ .off('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id)
+ .on('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id, function () {
+ this.options.confirm ? this.options.confirm(this.source) : eval(this.source.data('jBox-Confirm-submit'));
+ this.options.closeOnConfirm && this.close();
+ }.bind(this));
+ }
+
+ });
+
+};
+
+//# sourceMappingURL=jBox.Confirm.js.map
diff --git a/dist/plugins/jBox.Confirm.min.css b/dist/plugins/jBox.Confirm.min.css
new file mode 100755
index 0000000..76acc43
--- /dev/null
+++ b/dist/plugins/jBox.Confirm.min.css
@@ -0,0 +1 @@
+.jBox-Confirm .jBox-content{text-align:center;padding:46px 35px}@media (max-width:500px){.jBox-Confirm .jBox-content{padding:32px 20px}}.jBox-Confirm-footer{height:46px}.jBox-Confirm-button{display:block;float:left;cursor:pointer;text-align:center;width:50%;line-height:46px;height:46px;overflow:hidden;padding:0 10px;transition:color .2s,background-color .2s;box-sizing:border-box}.jBox-Confirm-button-cancel{border-bottom-left-radius:4px;background:#ddd;color:#666}.jBox-Confirm-button-cancel:active,.jBox-Confirm-button-cancel:hover{background:#ccc}.jBox-Confirm-button-cancel:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.jBox-Confirm-button-submit{border-bottom-right-radius:4px;background:#7d0;color:#fff}.jBox-Confirm-button-submit:active,.jBox-Confirm-button-submit:hover{background:#6c0}.jBox-Confirm-button-submit:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}
\ No newline at end of file
diff --git a/dist/plugins/jBox.Confirm.min.js b/dist/plugins/jBox.Confirm.min.js
new file mode 100755
index 0000000..9d39d5e
--- /dev/null
+++ b/dist/plugins/jBox.Confirm.min.js
@@ -0,0 +1 @@
+function jBoxConfirmWrapper(jBox,jQuery){new jBox.plugin("Confirm",{confirmButton:"Submit",cancelButton:"Cancel",confirm:null,cancel:null,closeOnConfirm:!0,target:window,fixed:!0,attach:"[data-confirm]",getContent:"data-confirm",content:"Do you really want to do this?",minWidth:360,maxWidth:500,blockScroll:!0,closeOnEsc:!0,closeOnClick:!1,closeButton:!1,overlay:!0,animation:"zoomIn",preventDefault:!0,_onAttach:function(o){var t;this.options.confirm||(t=o.attr("onclick")?o.attr("onclick"):o.attr("href")?o.attr("target")?'window.open("'+o.attr("href")+'", "'+o.attr("target")+'");':'window.location.href = "'+o.attr("href")+'";':"",o.prop("onclick",null).data("jBox-Confirm-submit",t))},_onCreated:function(){this.wrapper.addClass("jBox-Modal"),this.footer=jQuery(''),jQuery('
').html(this.options.cancelButton).on("click tap",function(){this.options.cancel&&this.options.cancel(this.source),this.close()}.bind(this)).appendTo(this.footer),this.submitButton=jQuery('
').html(this.options.confirmButton).appendTo(this.footer),this.footer.appendTo(this.container)},_onOpen:function(){this.submitButton.off("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id).on("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id,function(){this.options.confirm?this.options.confirm(this.source):eval(this.source.data("jBox-Confirm-submit")),this.options.closeOnConfirm&&this.close()}.bind(this))}})}
\ No newline at end of file
diff --git a/Source/plugins/Image/jBox.Image.css b/dist/plugins/jBox.Image.css
old mode 100644
new mode 100755
similarity index 72%
rename from Source/plugins/Image/jBox.Image.css
rename to dist/plugins/jBox.Image.css
index 09b9265..df4ee98
--- a/Source/plugins/Image/jBox.Image.css
+++ b/dist/plugins/jBox.Image.css
@@ -1,4 +1,3 @@
-
.jBox-Image .jBox-container {
background-color: transparent;
}
@@ -17,24 +16,31 @@
opacity: 0;
}
-.jBox-image-label-container {
+.jBox-image-label-wrapper {
position: absolute;
top: 100%;
left: 0;
right: 0;
height: 40px;
z-index: 100;
+ display: flex;
+}
+
+.jBox-image-label-container {
+ position: relative;
+ flex: 1;
}
.jBox-image-label {
box-sizing: border-box;
position: absolute;
+ left: 0;
bottom: 0;
width: 100%;
text-align: center;
- left: 0;
color: #fff;
- padding: 8px 40px;
+ padding: 8px 12px;
+ font-size: 15px;
line-height: 24px;
transition: opacity .36s;
opacity: 0;
@@ -57,10 +63,15 @@
pointer-events: all;
}
+@media (max-width: 600px) {
+ .jBox-image-label {
+ font-size: 13px;
+ }
+}
+
.jBox-image-pointer-next,
.jBox-image-pointer-prev {
- position: absolute;
- bottom: 0;
+ flex-shrink: 0;
width: 40px;
height: 40px;
cursor: pointer;
@@ -78,17 +89,12 @@
}
.jBox-image-pointer-next {
- right: 0;
transform: scaleX(-1);
}
-.jBox-image-pointer-prev {
- left: 0;
-}
-
.jBox-image-counter-container {
- position: absolute;
- right: 40px;
+ flex-shrink: 0;
+ white-space: nowrap;
height: 40px;
line-height: 40px;
font-size: 13px;
@@ -101,11 +107,6 @@
display: block;
}
-.jBox-image-has-counter .jBox-image-label:not(.expanded) {
- padding-right: 80px;
- text-indent: 40px;
-}
-
.jBox-overlay.jBox-overlay-Image {
background: #000;
}
@@ -146,13 +147,43 @@
transform-origin: 50% 50% 0;
}
-/* Image spinner */
+.jBox-image-download-button-wrapper {
+ position: absolute;
+ top: -40px;
+ right: 35px;
+ height: 40px;
+ display: flex;
+ cursor: pointer;
+ opacity: .8;
+ transition: opacity .2s;
+}
+
+.jBox-image-download-button-wrapper:hover {
+ opacity: 1;
+}
+
+.jBox-image-download-button-icon {
+ width: 40px;
+ height: 40px;
+ background: center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);
+ background-size: 60%;
+}
+
+.jBox-image-download-button-text {
+ white-space: nowrap;
+ line-height: 40px;
+ padding: 0 10px 0 0;
+ color: #fff;
+ font-size: 14px;
+}
@keyframes jBoxImageLoading {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
-.jBox-image-loading .jBox-container:before {
+.jBox-image-loading:before {
content: '';
position: absolute;
top: 50%;
@@ -166,3 +197,5 @@
animation: jBoxImageLoading 1.2s linear infinite;
border-radius: 50%;
}
+
+/*# sourceMappingURL=jBox.Image.css.map */
diff --git a/dist/plugins/jBox.Image.js b/dist/plugins/jBox.Image.js
new file mode 100755
index 0000000..cc0c57c
--- /dev/null
+++ b/dist/plugins/jBox.Image.js
@@ -0,0 +1,358 @@
+/**
+ * jBox Image plugin: Adds a lightbox to your images
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxImageWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Image', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-image)
+
+ src: 'href', // The attribute where jBox gets the image source from, e.g. href="/path_to_image/image.jpg"
+ gallery: 'data-jbox-image', // The attribute to set the galleries, e.g. data-jbox-image="gallery1"
+ imageLabel: 'title', // The attribute where jBox gets the image label from, e.g. title="My label"
+ imageFade: 360, // The fade duration for images in ms
+ imageSize: 'contain', // How to display the images. Use CSS background-position values, e.g. 'cover', 'contain', 'auto', 'initial', '50% 50%'
+ imageCounter: false, // Set to true to add an image counter, e.g. 4/20
+ imageCounterSeparator: '/', // HTML to separate the current image number from all image numbers, e.g. '/' or ' of '
+ downloadButton: false, // Adds a download button
+ downloadButtonText: null, // Text for the download button
+ downloadButtonUrl: null, // The attribute at the source element where to find the image to download, e.g. data-download="/path_to_image/image.jpg". If none provided, the currently active image will be downloaded
+ mobileImageAttr: null, // The attribute to look for an mobile version of the image
+ mobileImageBreakpoint: null, // The upper breakpoint to load the mobile image
+ preloadFirstImage: false, // Preload the first image when page is loaded
+ target: window,
+ attach: '[data-jbox-image]',
+ fixed: true,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: 'button',
+ closeButton: true,
+ overlay: true,
+ animation: 'zoomIn',
+ preventDefault: true,
+ width: '100%',
+ height: '100%',
+ adjustDistance: {
+ top: 40,
+ right: 0,
+ bottom: 40,
+ left: 0
+ },
+
+
+ // Triggered when jBox is initialized
+
+ _onInit: function ()
+ {
+ // Initial images and z-index
+ this.images = this.currentImage = {};
+ this.imageZIndex = 1;
+
+ this.initImage = function (item) {
+ item = jQuery(item);
+
+ // Abort if the item was added to a gallery already
+ if (item.data('jBox-image-gallery')) {
+ return;
+ }
+
+ // Get the image src
+ var src = item.attr(this.options.src);
+
+ // Update responsive image src
+ if (this.options.mobileImageAttr && this.options.mobileImageBreakpoint && item.attr(this.options.mobileImageAttr)) {
+ if (jQuery(window).width() <= this.options.mobileImageBreakpoint) {
+ src = item.attr(this.options.mobileImageAttr);
+ }
+ }
+
+ // Add item to a gallery
+ var gallery = item.attr(this.options.gallery) || 'default';
+ !this.images[gallery] && (this.images[gallery] = []);
+ this.images[gallery].push({
+ src: src,
+ label: (item.attr(this.options.imageLabel) || ''),
+ downloadUrl: this.options.downloadButtonUrl && item.attr(this.options.downloadButtonUrl) ? item.attr(this.options.downloadButtonUrl) : null
+ });
+
+ // Remove the title attribute so it won't show the browsers tooltip
+ this.options.imageLabel == 'title' && item.removeAttr('title');
+
+ // Store data in source element for easy access
+ item.data('jBox-image-gallery', gallery);
+ item.data('jBox-image-id', (this.images[gallery].length - 1));
+ }.bind(this);
+
+ // Loop through images, sort and save in global variable
+ this.attachedElements && this.attachedElements.length && jQuery.each(this.attachedElements, function (index, item) {
+ this.initImage(item);
+ }.bind(this));
+
+ // Helper to inject the image into content area
+ var appendImage = function (gallery, id, show, instant) {
+ // Abort if image was appended already
+ if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
+ return;
+ }
+
+ // Create image container
+ var image = jQuery('
', {
+ id: 'jBox-image-' + gallery + '-' + id,
+ 'class': 'jBox-image-container' + (show ? ' jBox-image-' + gallery + '-current' : '')
+ }).css({
+ backgroundSize: this.options.imageSize,
+ opacity: (instant ? 1 : 0),
+ zIndex: (show ? this.imageZIndex++ : 0)
+ }).appendTo(this.content);
+
+ // Add swipe events
+ this.swipeDetector(image)
+ .on("swipeLeft.sd swipeRight.sd", function (event) {
+ if (event.type === "swipeLeft") {
+ this.showImage('next');
+ } else if (event.type === "swipeRight") {
+ this.showImage('prev');
+ }
+ }.bind(this));
+
+ // Create labels
+ jQuery('
', {
+ id: 'jBox-image-label-' + gallery + '-' + id,
+ 'class': 'jBox-image-label' + (show ? ' active' : '')
+ })
+ .html(this.images[gallery][id].label)
+ .on('click tap', function () {
+ jQuery(this).toggleClass('expanded');
+ })
+ .appendTo(this.imageLabelContainer);
+
+ // Show image
+ show && image.animate({opacity: 1}, instant ? 0 : this.options.imageFade);
+
+ return image;
+ }.bind(this);
+
+ // Function to download an image
+ this.downloadImage = function (imageUrl) {
+ var link = document.createElement('a');
+ link.href = imageUrl;
+ link.setAttribute('download', imageUrl.substring(imageUrl.lastIndexOf('/')+1));
+ document.body.appendChild(link);
+ link.click();
+ };
+
+ // Helper to show new image label
+ var showLabel = function (gallery, id) {
+ jQuery('.jBox-image-label.active').removeClass('active expanded');
+ jQuery('#jBox-image-label-' + gallery + '-' + id).addClass('active');
+ };
+
+ // Helper to load image
+ var loadImage = function (gallery, id, show, instant) {
+ var imageContainer = appendImage(gallery, id, show, instant);
+ imageContainer.addClass('jBox-image-loading');
+
+ jQuery(' ').each(function () {
+ var tmpImg = new Image();
+ tmpImg.onload = function () {
+ imageContainer.removeClass('jBox-image-loading');
+ imageContainer.css({backgroundImage: 'url("' + this.images[gallery][id].src + '")'});
+ }.bind(this);
+
+ tmpImg.onerror = function () {
+ imageContainer.removeClass('jBox-image-loading');
+ imageContainer.addClass('jBox-image-not-found');
+ }.bind(this);
+
+ tmpImg.src = this.images[gallery][id].src;
+ }.bind(this));
+ }.bind(this);
+
+ // Show images when they are loaded or load them if not
+ this.showImage = function (img) {
+ // Get the gallery and the image id from the next or the previous image
+ var gallery;
+ var id;
+
+ if (img != 'open') {
+ gallery = this.currentImage.gallery;
+ id = this.currentImage.id + (1 * (img == 'prev') ? -1 : 1);
+ id = id > (this.images[gallery].length - 1) ? 0 : (id < 0 ? (this.images[gallery].length - 1) : id);
+
+ // Or get image data from source element
+ } else {
+ // Get gallery and image id from source element
+ if (this.source) {
+ gallery = this.source.data('jBox-image-gallery');
+ id = this.source.data('jBox-image-id');
+
+ // Get gallery and image id attached elements
+ } else if (this.attachedElements && this.attachedElements.length) {
+ gallery = jQuery(this.attachedElements[0]).data('jBox-image-gallery');
+ id = jQuery(this.attachedElements[0]).data('jBox-image-id');
+ } else {
+ return;
+ }
+
+ // Remove or show the next and prev buttons
+ if (this.images && this.images[gallery]) {
+ jQuery('.jBox-image-pointer-prev, .jBox-image-pointer-next').css({display: (this.images[gallery].length > 1 ? 'block' : 'none')});
+ }
+ }
+
+ // If there is a current image already shown, hide it
+ if (jQuery('.jBox-image-' + gallery + '-current').length) {
+ jQuery('.jBox-image-' + gallery + '-current').removeClass('jBox-image-' + gallery + '-current').animate({opacity: 0}, (img == 'open') ? 0 : this.options.imageFade);
+ }
+
+ // Set new current image
+ this.currentImage = {gallery: gallery, id: id};
+
+ // Show image if it already exists
+ if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
+ jQuery('#jBox-image-' + gallery + '-' + id).addClass('jBox-image-' + gallery + '-current').css({zIndex: this.imageZIndex++, opacity: 0}).animate({opacity: 1}, (img == 'open') ? 0 : this.options.imageFade);
+
+ // Load image
+ } else {
+ loadImage(gallery, id, true, (img === 'open'));
+ }
+
+ // Show label
+ showLabel(gallery, id);
+
+ // Update the image counter numbers
+ if (this.imageCounter) {
+ if (this.images[gallery] && this.images[gallery].length > 1) {
+ this.wrapper.addClass('jBox-image-has-counter');
+ this.imageCounter.find('.jBox-image-counter-all').html(this.images[gallery].length);
+ this.imageCounter.find('.jBox-image-counter-current').html(id + 1);
+ } else {
+ this.wrapper.removeClass('jBox-image-has-counter');
+ }
+ }
+
+ // Preload next image
+ if (this.images[gallery] && this.images[gallery].length - 1) {
+ var next_id = id + 1;
+ next_id = next_id > (this.images[gallery].length - 1) ? 0 : (next_id < 0 ? (this.images[gallery].length - 1) : next_id);
+
+ if (!jQuery('#jBox-image-' + gallery + '-' + next_id).length) {
+ loadImage(gallery, next_id, false, false);
+ }
+ }
+ };
+
+ // Preload image
+ if (this.options.preloadFirstImage) {
+ jQuery(window).on('load', function() {
+ this.showImage('open');
+ }.bind(this));
+ }
+ },
+
+
+ // Triggered when jBox attaches a new element
+
+ _onAttach: function (item) {
+ this.initImage && this.initImage(item);
+ },
+
+
+ // Triggered when jBox was created
+
+ _onCreated: function ()
+ {
+ // Create image label and navigation buttons
+ this.imageLabelWrapper = jQuery('
').appendTo(this.wrapper);
+
+ this.imagePrevButton = jQuery('
')
+ .on('click tap', function () {
+ this.showImage('prev');
+ }.bind(this));
+
+ this.imageNextButton = jQuery('
')
+ .on('click tap', function () {
+ this.showImage('next');
+ }.bind(this));
+
+ this.imageLabelContainer = jQuery('
');
+
+ this.imageLabelWrapper
+ .append(this.imagePrevButton)
+ .append(this.imageLabelContainer)
+ .append(this.imageNextButton);
+
+ // Append the download button
+ if (this.options.downloadButton) {
+ this.downloadButton = jQuery('
', {'class': 'jBox-image-download-button-wrapper'})
+ .appendTo(this.wrapper)
+ .append(
+ this.options.downloadButtonText ? jQuery('
', {'class': 'jBox-image-download-button-text'}).html(this.options.downloadButtonText) : null
+ )
+ .append(
+ jQuery('
', {'class': 'jBox-image-download-button-icon'})
+ ).on('click tap', function () {
+ if (this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl) {
+ var currentImageUrl = this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl;
+ } else {
+ var currentImage = this.wrapper.find('.jBox-image-' + this.currentImage.gallery + '-current');
+ var currentImageStyle = currentImage[0].style.backgroundImage;
+ var currentImageUrl = currentImageStyle.slice(4, -1).replace(/["']/g, '');
+ }
+ this.downloadImage(currentImageUrl);
+ }.bind(this));
+ }
+
+ // Creating the image counter containers
+ if (this.options.imageCounter) {
+ this.imageCounter = jQuery('
', {'class': 'jBox-image-counter-container'}).insertAfter(this.imageLabelContainer);
+ this.imageCounter.append(jQuery(' ', {'class': 'jBox-image-counter-current'})).append(jQuery(' ').html(this.options.imageCounterSeparator)).append(jQuery(' ', {'class': 'jBox-image-counter-all'}));
+ }
+ },
+
+
+ // Triggered when jBox opens
+
+ _onOpen: function ()
+ {
+ // Add key events
+ jQuery(document).on('keyup.jBox-Image-' + this.id, function (ev) {
+ (ev.keyCode == 37) && this.showImage('prev');
+ (ev.keyCode == 39) && this.showImage('next');
+ }.bind(this));
+
+ // Load the image from the attached element
+ this.showImage('open');
+ },
+
+
+ // Triggered when jBox closes
+
+ _onClose: function ()
+ {
+ // Remove key events
+ jQuery(document).off('keyup.jBox-Image-' + this.id);
+ },
+
+
+ // Triggered when jBox finished closing
+
+ _onCloseComplete: function ()
+ {
+ // Hide all image containers
+ this.wrapper.find('.jBox-image-container').css('opacity', 0);
+ }
+
+ });
+
+};
+
+//# sourceMappingURL=jBox.Image.js.map
diff --git a/dist/plugins/jBox.Image.min.css b/dist/plugins/jBox.Image.min.css
new file mode 100755
index 0000000..1d95c7a
--- /dev/null
+++ b/dist/plugins/jBox.Image.min.css
@@ -0,0 +1 @@
+.jBox-Image .jBox-container{background-color:transparent}.jBox-Image .jBox-content{padding:0;width:100%;height:100%}.jBox-image-container{background:center center no-repeat;position:absolute;width:100%;height:100%;opacity:0}.jBox-image-label-wrapper{position:absolute;top:100%;left:0;right:0;height:40px;z-index:100;display:flex}.jBox-image-label-container{position:relative;flex:1}.jBox-image-label{box-sizing:border-box;position:absolute;left:0;bottom:0;width:100%;text-align:center;color:#fff;padding:8px 12px;font-size:15px;line-height:24px;transition:opacity .36s;opacity:0;z-index:0;pointer-events:none}.jBox-image-label.expanded{background:#000}.jBox-image-label:not(.expanded){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jBox-image-label.active{opacity:1;pointer-events:all}@media (max-width:600px){.jBox-image-label{font-size:13px}}.jBox-image-pointer-next,.jBox-image-pointer-prev{flex-shrink:0;width:40px;height:40px;cursor:pointer;opacity:.8;transition:opacity .2s;background:no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);background-size:11px auto;user-select:none;z-index:1}.jBox-image-pointer-next:hover,.jBox-image-pointer-prev:hover{opacity:1}.jBox-image-pointer-next{transform:scaleX(-1)}.jBox-image-counter-container{flex-shrink:0;white-space:nowrap;height:40px;line-height:40px;font-size:13px;color:#fff;text-align:right;display:none}.jBox-image-has-counter .jBox-image-counter-container{display:block}.jBox-overlay.jBox-overlay-Image{background:#000}.jBox-image-not-found{background:#000}.jBox-image-not-found:before{content:'';box-sizing:border-box;display:block;width:80px;height:80px;margin-top:-40px;margin-left:-40px;position:absolute;top:50%;left:50%;border:5px solid #222;border-radius:50%}.jBox-image-not-found:after{content:'';display:block;box-sizing:content-box;z-index:auto;width:6px;height:74px;margin-top:-37px;margin-left:-3px;position:absolute;top:50%;left:50%;background:#222;transform:rotateZ(45deg);transform-origin:50% 50% 0}.jBox-image-download-button-wrapper{position:absolute;top:-40px;right:35px;height:40px;display:flex;cursor:pointer;opacity:.8;transition:opacity .2s}.jBox-image-download-button-wrapper:hover{opacity:1}.jBox-image-download-button-icon{width:40px;height:40px;background:center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);background-size:60%}.jBox-image-download-button-text{white-space:nowrap;line-height:40px;padding:0 10px 0 0;color:#fff;font-size:14px}@keyframes jBoxImageLoading{to{transform:rotate(360deg)}}.jBox-image-loading:before{content:'';position:absolute;top:50%;left:50%;width:32px;height:32px;margin-top:-16px;margin-left:-16px;border:4px solid #333;border-bottom-color:#666;animation:jBoxImageLoading 1.2s linear infinite;border-radius:50%}
\ No newline at end of file
diff --git a/dist/plugins/jBox.Image.min.js b/dist/plugins/jBox.Image.min.js
new file mode 100755
index 0000000..d9528fe
--- /dev/null
+++ b/dist/plugins/jBox.Image.min.js
@@ -0,0 +1 @@
+function jBoxImageWrapper(t,s){new t.plugin("Image",{src:"href",gallery:"data-jbox-image",imageLabel:"title",imageFade:360,imageSize:"contain",imageCounter:!1,imageCounterSeparator:"/",downloadButton:!1,downloadButtonText:null,downloadButtonUrl:null,mobileImageAttr:null,mobileImageBreakpoint:null,preloadFirstImage:!1,target:window,attach:"[data-jbox-image]",fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"button",closeButton:!0,overlay:!0,animation:"zoomIn",preventDefault:!0,width:"100%",height:"100%",adjustDistance:{top:40,right:0,bottom:40,left:0},_onInit:function(){this.images=this.currentImage={},this.imageZIndex=1,this.initImage=function(t){var e,i;(t=s(t)).data("jBox-image-gallery")||(e=t.attr(this.options.src),this.options.mobileImageAttr&&this.options.mobileImageBreakpoint&&t.attr(this.options.mobileImageAttr)&&s(window).width()<=this.options.mobileImageBreakpoint&&(e=t.attr(this.options.mobileImageAttr)),i=t.attr(this.options.gallery)||"default",this.images[i]||(this.images[i]=[]),this.images[i].push({src:e,label:t.attr(this.options.imageLabel)||"",downloadUrl:this.options.downloadButtonUrl&&t.attr(this.options.downloadButtonUrl)?t.attr(this.options.downloadButtonUrl):null}),"title"==this.options.imageLabel&&t.removeAttr("title"),t.data("jBox-image-gallery",i),t.data("jBox-image-id",this.images[i].length-1))}.bind(this),this.attachedElements&&this.attachedElements.length&&s.each(this.attachedElements,function(t,e){this.initImage(e)}.bind(this));var n=function(t,e,i,a){if(!s("#jBox-image-"+t+"-"+e).length){var o=s("
",{id:"jBox-image-"+t+"-"+e,class:"jBox-image-container"+(i?" jBox-image-"+t+"-current":"")}).css({backgroundSize:this.options.imageSize,opacity:a?1:0,zIndex:i?this.imageZIndex++:0}).appendTo(this.content);return this.swipeDetector(o).on("swipeLeft.sd swipeRight.sd",function(t){"swipeLeft"===t.type?this.showImage("next"):"swipeRight"===t.type&&this.showImage("prev")}.bind(this)),s("
",{id:"jBox-image-label-"+t+"-"+e,class:"jBox-image-label"+(i?" active":"")}).html(this.images[t][e].label).on("click tap",function(){s(this).toggleClass("expanded")}).appendTo(this.imageLabelContainer),i&&o.animate({opacity:1},a?0:this.options.imageFade),o}}.bind(this);this.downloadImage=function(t){var e=document.createElement("a");e.href=t,e.setAttribute("download",t.substring(t.lastIndexOf("/")+1)),document.body.appendChild(e),e.click()};var o=function(e,i,t,a){var o=n(e,i,t,a);o.addClass("jBox-image-loading"),s(' ').each(function(){var t=new Image;t.onload=function(){o.removeClass("jBox-image-loading"),o.css({backgroundImage:'url("'+this.images[e][i].src+'")'})}.bind(this),t.onerror=function(){o.removeClass("jBox-image-loading"),o.addClass("jBox-image-not-found")}.bind(this),t.src=this.images[e][i].src}.bind(this))}.bind(this);this.showImage=function(t){var e,i,a;if("open"!=t)e=this.currentImage.gallery,a=(a=this.currentImage.id+(+("prev"==t)?-1:1))>this.images[e].length-1?0:a<0?this.images[e].length-1:a;else{if(this.source)e=this.source.data("jBox-image-gallery"),a=this.source.data("jBox-image-id");else{if(!this.attachedElements||!this.attachedElements.length)return;e=s(this.attachedElements[0]).data("jBox-image-gallery"),a=s(this.attachedElements[0]).data("jBox-image-id")}this.images&&this.images[e]&&s(".jBox-image-pointer-prev, .jBox-image-pointer-next").css({display:1this.images[e].length-1?0:a<0?this.images[e].length-1:a,s("#jBox-image-"+e+"-"+a).length||o(e,a,!1,!1))},this.options.preloadFirstImage&&s(window).on("load",function(){this.showImage("open")}.bind(this))},_onAttach:function(t){this.initImage&&this.initImage(t)},_onCreated:function(){this.imageLabelWrapper=s('
').appendTo(this.wrapper),this.imagePrevButton=s('
').on("click tap",function(){this.showImage("prev")}.bind(this)),this.imageNextButton=s('
').on("click tap",function(){this.showImage("next")}.bind(this)),this.imageLabelContainer=s('
'),this.imageLabelWrapper.append(this.imagePrevButton).append(this.imageLabelContainer).append(this.imageNextButton),this.options.downloadButton&&(this.downloadButton=s("
",{class:"jBox-image-download-button-wrapper"}).appendTo(this.wrapper).append(this.options.downloadButtonText?s("
",{class:"jBox-image-download-button-text"}).html(this.options.downloadButtonText):null).append(s("
",{class:"jBox-image-download-button-icon"})).on("click tap",function(){var t;t=this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl||this.wrapper.find(".jBox-image-"+this.currentImage.gallery+"-current")[0].style.backgroundImage.slice(4,-1).replace(/["']/g,""),this.downloadImage(t)}.bind(this))),this.options.imageCounter&&(this.imageCounter=s("
",{class:"jBox-image-counter-container"}).insertAfter(this.imageLabelContainer),this.imageCounter.append(s(" ",{class:"jBox-image-counter-current"})).append(s(" ").html(this.options.imageCounterSeparator)).append(s(" ",{class:"jBox-image-counter-all"})))},_onOpen:function(){s(document).on("keyup.jBox-Image-"+this.id,function(t){37==t.keyCode&&this.showImage("prev"),39==t.keyCode&&this.showImage("next")}.bind(this)),this.showImage("open")},_onClose:function(){s(document).off("keyup.jBox-Image-"+this.id)},_onCloseComplete:function(){this.wrapper.find(".jBox-image-container").css("opacity",0)}})}
\ No newline at end of file
diff --git a/dist/plugins/jBox.Notice.css b/dist/plugins/jBox.Notice.css
new file mode 100755
index 0000000..91971fe
--- /dev/null
+++ b/dist/plugins/jBox.Notice.css
@@ -0,0 +1,122 @@
+.jBox-Notice {
+ transition: margin .2s;
+}
+
+.jBox-Notice .jBox-container {
+ border-radius: 4px;
+ box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.25), inset -1px -1px 0 0 rgba(0, 0, 0, 0.1);
+}
+
+.jBox-Notice .jBox-content {
+ border-radius: 4px;
+ padding: 12px 20px;
+}
+
+@media (max-width: 768px) {
+ .jBox-Notice .jBox-content {
+ padding: 10px 15px;
+ }
+}
+
+@media (max-width: 500px) {
+ .jBox-Notice .jBox-content {
+ padding: 8px 10px;
+ }
+}
+
+.jBox-Notice.jBox-hasTitle .jBox-content {
+ padding-top: 5px;
+}
+
+@media (max-width: 500px) {
+ .jBox-Notice.jBox-hasTitle .jBox-content {
+ padding-top: 0;
+ }
+}
+
+.jBox-Notice.jBox-hasTitle .jBox-title {
+ padding: 12px 20px 0;
+ font-weight: bold;
+}
+
+@media (max-width: 768px) {
+ .jBox-Notice.jBox-hasTitle .jBox-title {
+ padding: 10px 15px 0;
+ }
+}
+
+@media (max-width: 500px) {
+ .jBox-Notice.jBox-hasTitle .jBox-title {
+ padding: 8px 10px 0;
+ }
+}
+
+.jBox-Notice.jBox-closeButton-title .jBox-title {
+ padding-right: 55px;
+}
+
+.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+ width: 40px;
+}
+
+.jBox-Notice.jBox-Notice-black .jBox-container {
+ color: #fff;
+ background: #000;
+}
+
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-gray .jBox-container {
+ color: #222;
+ background: #f6f6f6;
+}
+
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #222;
+}
+
+.jBox-Notice.jBox-Notice-red .jBox-container {
+ color: #fff;
+ background: #d00;
+}
+
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-green .jBox-container {
+ color: #fff;
+ background: #5d0;
+}
+
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-blue .jBox-container {
+ color: #fff;
+ background: #49d;
+}
+
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+.jBox-Notice.jBox-Notice-yellow .jBox-container {
+ color: #000;
+ background: #fd0;
+}
+
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
+ fill: #fff;
+}
+
+/*# sourceMappingURL=jBox.Notice.css.map */
diff --git a/dist/plugins/jBox.Notice.js b/dist/plugins/jBox.Notice.js
new file mode 100755
index 0000000..f4eeecd
--- /dev/null
+++ b/dist/plugins/jBox.Notice.js
@@ -0,0 +1,173 @@
+/**
+ * jBox Notice plugin: Opens a popup notice
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxNoticeWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Notice', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-notice)
+
+ color: null, // Add a color to your notices, use 'gray' (default), 'black', 'red', 'green', 'blue' or 'yellow'
+ stack: true, // Set to false to disable notice-stacking
+ stackSpacing: 10, // Spacing between notices when they stack
+ autoClose: 6000, // Time in ms after which the notice will disappear
+ attributes: { // Defines where the notice will pop up
+ x: 'right', // 'left' or 'right'
+ y: 'top' // 'top' or 'bottom'
+ },
+ position: { // Defines the distance to the viewport boundary
+ x: 15,
+ y: 15
+ },
+ responsivePositions: { // Responsive positions
+ 500: { // The key defines the maximum width of the viewport, the values will replace the default position options
+ x: 5, // Start with the lowest viewport
+ y: 5
+ },
+ 768: {
+ x: 10,
+ y: 10
+ }
+ },
+ target: window,
+ fixed: true,
+ animation: 'zoomIn',
+ closeOnClick: 'box',
+ zIndex: 12000,
+
+
+ // Triggered when notice is initialized
+
+ _onInit: function ()
+ {
+ // Cache position values
+ this.defaultNoticePosition = jQuery.extend({}, this.options.position);
+
+ // Type Notice has its own adjust position function
+ this._adjustNoticePositon = function () {
+ var win = jQuery(window);
+ var windowDimensions = {
+ x: win.width(),
+ y: win.height()
+ };
+
+ // Reset default position
+ this.options.position = jQuery.extend({}, this.defaultNoticePosition);
+
+ // Adjust depending on viewport
+ jQuery.each(this.options.responsivePositions, function (viewport, position) {
+ if (windowDimensions.x <= viewport) {
+ this.options.position = position;
+ return false;
+ }
+ }.bind(this));
+
+ // Set new padding options
+ this.options.adjustDistance = {
+ top: this.options.position.y,
+ right: this.options.position.x,
+ bottom: this.options.position.y,
+ left: this.options.position.x
+ };
+ };
+
+ // If jBox grabs an element as content, crab a clone instead
+ this.options.content instanceof jQuery && (this.options.content = this.options.content.clone().attr('id', ''));
+
+ // Adjust paddings when window resizes
+ jQuery(window).on('resize.responsivejBoxNotice-' + this.id, function (ev) { if (this.isOpen) { this._adjustNoticePositon(); } }.bind(this));
+
+ this.open();
+ },
+
+
+ // Triggered when notice was created
+
+ _onCreated: function ()
+ {
+ // Add color class
+ this.wrapper.addClass('jBox-Notice-color jBox-Notice-' + (this.options.color || 'gray'));
+
+ // Store position in jBox wrapper
+ this.wrapper.data('jBox-Notice-position', this.options.attributes.x + '-' + this.options.attributes.y);
+ },
+
+
+ // Triggered when notice opens
+
+ _onOpen: function ()
+ {
+ // Bail if we're stacking
+ if (this.options.stack) {
+ return;
+ }
+
+ // Adjust position when opening
+ this._adjustNoticePositon();
+
+ // Loop through notices at same window corner destroy them
+ jQuery.each(jQuery('.jBox-Notice'), function (index, el)
+ {
+ el = jQuery(el);
+
+ // Abort if the element is this notice or when it's not at the same position
+ if (el.attr('id') == this.id || el.data('jBox-Notice-position') != this.options.attributes.x + '-' + this.options.attributes.y) {
+ return;
+ }
+
+ // Remove notice when we don't wont to stack them
+ if (!this.options.stack) {
+ el.data('jBox').close({ignoreDelay: true});
+ return;
+ }
+ }.bind(this));
+ },
+
+ // Triggered when resizing window etc.
+
+ _onPosition: function ()
+ {
+ var stacks = {};
+ jQuery.each(jQuery('.jBox-Notice'), function (index, el)
+ {
+ el = jQuery(el);
+ var pos = el.data('jBox-Notice-position');
+ if (!stacks[pos]) {
+ stacks[pos] = [];
+ }
+ stacks[pos].push(el);
+ });
+ for (var pos in stacks) {
+ var position = pos.split('-');
+ var direction = position[1];
+ stacks[pos].reverse();
+ var margin = 0;
+ for (var i in stacks[pos]) {
+ var el = jQuery(stacks[pos][i]);
+ el.css('margin-' + direction, margin);
+ margin += el.outerHeight() + this.options.stackSpacing;
+ }
+ }
+ },
+
+ // Remove notice from DOM and reposition other notices when closing finishes
+
+ _onCloseComplete: function ()
+ {
+ this.destroy();
+ this.options._onPosition.bind(this).call();
+ }
+
+ });
+
+};
+
+//# sourceMappingURL=jBox.Notice.js.map
diff --git a/dist/plugins/jBox.Notice.min.css b/dist/plugins/jBox.Notice.min.css
new file mode 100755
index 0000000..80ea41a
--- /dev/null
+++ b/dist/plugins/jBox.Notice.min.css
@@ -0,0 +1 @@
+.jBox-Notice{transition:margin .2s}.jBox-Notice .jBox-container{border-radius:4px;box-shadow:inset 1px 1px 0 0 rgba(255,255,255,.25),inset -1px -1px 0 0 rgba(0,0,0,.1)}.jBox-Notice .jBox-content{border-radius:4px;padding:12px 20px}@media (max-width:768px){.jBox-Notice .jBox-content{padding:10px 15px}}@media (max-width:500px){.jBox-Notice .jBox-content{padding:8px 10px}}.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:5px}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:0}}.jBox-Notice.jBox-hasTitle .jBox-title{padding:12px 20px 0;font-weight:700}@media (max-width:768px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:10px 15px 0}}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:8px 10px 0}}.jBox-Notice.jBox-closeButton-title .jBox-title{padding-right:55px}.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton{width:40px}.jBox-Notice.jBox-Notice-black .jBox-container{color:#fff;background:#000}.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-gray .jBox-container{color:#222;background:#f6f6f6}.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#222}.jBox-Notice.jBox-Notice-red .jBox-container{color:#fff;background:#d00}.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-green .jBox-container{color:#fff;background:#5d0}.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-blue .jBox-container{color:#fff;background:#49d}.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-yellow .jBox-container{color:#000;background:#fd0}.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}
\ No newline at end of file
diff --git a/dist/plugins/jBox.Notice.min.js b/dist/plugins/jBox.Notice.min.js
new file mode 100755
index 0000000..b46dee5
--- /dev/null
+++ b/dist/plugins/jBox.Notice.min.js
@@ -0,0 +1 @@
+function jBoxNoticeWrapper(t,a){new t.plugin("Notice",{color:null,stack:!0,stackSpacing:10,autoClose:6e3,attributes:{x:"right",y:"top"},position:{x:15,y:15},responsivePositions:{500:{x:5,y:5},768:{x:10,y:10}},target:window,fixed:!0,animation:"zoomIn",closeOnClick:"box",zIndex:12e3,_onInit:function(){this.defaultNoticePosition=a.extend({},this.options.position),this._adjustNoticePositon=function(){var t=a(window),o=t.width();t.height();this.options.position=a.extend({},this.defaultNoticePosition),a.each(this.options.responsivePositions,function(t,i){if(o<=t)return this.options.position=i,!1}.bind(this)),this.options.adjustDistance={top:this.options.position.y,right:this.options.position.x,bottom:this.options.position.y,left:this.options.position.x}},this.options.content instanceof a&&(this.options.content=this.options.content.clone().attr("id","")),a(window).on("resize.responsivejBoxNotice-"+this.id,function(t){this.isOpen&&this._adjustNoticePositon()}.bind(this)),this.open()},_onCreated:function(){this.wrapper.addClass("jBox-Notice-color jBox-Notice-"+(this.options.color||"gray")),this.wrapper.data("jBox-Notice-position",this.options.attributes.x+"-"+this.options.attributes.y)},_onOpen:function(){this.options.stack||(this._adjustNoticePositon(),a.each(a(".jBox-Notice"),function(t,i){(i=a(i)).attr("id")!=this.id&&i.data("jBox-Notice-position")==this.options.attributes.x+"-"+this.options.attributes.y&&(this.options.stack||i.data("jBox").close({ignoreDelay:!0}))}.bind(this)))},_onPosition:function(){var t,s={};for(t in a.each(a(".jBox-Notice"),function(t,i){var o=(i=a(i)).data("jBox-Notice-position");s[o]||(s[o]=[]),s[o].push(i)}),s){var i=t.split("-")[1];s[t].reverse();var o,n=0;for(o in s[t]){var e=a(s[t][o]);e.css("margin-"+i,n),n+=e.outerHeight()+this.options.stackSpacing}}},_onCloseComplete:function(){this.destroy(),this.options._onPosition.bind(this).call()}})}
\ No newline at end of file
diff --git a/Source/themes/NoticeFancy.css b/dist/themes/jBox.NoticeFancy.css
old mode 100644
new mode 100755
similarity index 68%
rename from Source/themes/NoticeFancy.css
rename to dist/themes/jBox.NoticeFancy.css
index 6ffb706..a957d2b
--- a/Source/themes/NoticeFancy.css
+++ b/dist/themes/jBox.NoticeFancy.css
@@ -1,10 +1,3 @@
-
-/* jBox theme: NoticeFancy */
-
-.jBox-NoticeFancy .jBox-container {
- border-radius: 5px;
-}
-
.jBox-NoticeFancy .jBox-content,
.jBox-NoticeFancy .jBox-title {
padding-left: 25px;
@@ -12,12 +5,9 @@
.jBox-NoticeFancy.jBox-Notice-color .jBox-container {
color: #fff;
- background: #222;
- text-shadow: 0 -1px 0 #000;
+ background: #000;
}
-/* Colored borders */
-
.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after {
content: '';
position: absolute;
@@ -26,7 +16,7 @@
bottom: 0;
width: 8px;
border-radius: 4px 0 0 4px;
- background-image: linear-gradient(45deg, rgba(255, 255, 255, .4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .4) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
background-size: 14px 14px;
}
@@ -44,9 +34,16 @@
}
.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after {
- background-color: #07d;
+ background-color: #49d;
}
.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after {
background-color: #fb0;
-}
\ No newline at end of file
+}
+
+.jBox-NoticeFancy .jBox-countdown {
+ left: 8px;
+ border-radius: 0 4px 0 0;
+}
+
+/*# sourceMappingURL=jBox.NoticeFancy.css.map */
diff --git a/dist/themes/jBox.NoticeFancy.min.css b/dist/themes/jBox.NoticeFancy.min.css
new file mode 100755
index 0000000..d0bf213
--- /dev/null
+++ b/dist/themes/jBox.NoticeFancy.min.css
@@ -0,0 +1 @@
+.jBox-NoticeFancy .jBox-content,.jBox-NoticeFancy .jBox-title{padding-left:25px}.jBox-NoticeFancy.jBox-Notice-color .jBox-container{color:#fff;background:#000}.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after{content:'';position:absolute;top:0;left:0;bottom:0;width:8px;border-radius:4px 0 0 4px;background-image:linear-gradient(45deg,rgba(255,255,255,.4) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.4) 75%,transparent 75%,transparent);background-size:14px 14px}.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after{background-color:#888}.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after{background-color:#e00}.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after{background-color:#6c0}.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after{background-color:#49d}.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after{background-color:#fb0}.jBox-NoticeFancy .jBox-countdown{left:8px;border-radius:0 4px 0 0}
\ No newline at end of file
diff --git a/Source/themes/TooltipBorder.css b/dist/themes/jBox.TooltipBorder.css
old mode 100644
new mode 100755
similarity index 52%
rename from Source/themes/TooltipBorder.css
rename to dist/themes/jBox.TooltipBorder.css
index 53a0d1d..59b70f7
--- a/Source/themes/TooltipBorder.css
+++ b/dist/themes/jBox.TooltipBorder.css
@@ -1,15 +1,11 @@
-
-/* jBox theme: TooltipBorder */
-
-.jBox-TooltipBorder .jBox-container {
- border-radius: 5px;
+.jBox-TooltipBorder .jBox-container,
+.jBox-TooltipBorder .jBox-pointer:after {
border: 2px solid #49d;
}
-/* Pointer */
-
.jBox-TooltipBorder .jBox-pointer:after {
- border: 2px solid #49d;
+ width: 22px;
+ height: 22px;
}
.jBox-TooltipBorder .jBox-pointer-top,
@@ -18,16 +14,26 @@
height: 13px;
}
+.jBox-TooltipBorder .jBox-pointer-top:after,
+.jBox-TooltipBorder .jBox-pointer-bottom:after {
+ left: 6px;
+}
+
.jBox-TooltipBorder .jBox-pointer-left,
.jBox-TooltipBorder .jBox-pointer-right {
width: 13px;
height: 34px;
}
-/* Close button */
+.jBox-TooltipBorder .jBox-pointer-left:after,
+.jBox-TooltipBorder .jBox-pointer-right:after {
+ top: 6px;
+}
.jBox-TooltipBorder.jBox-closeButton-box:before {
width: 28px;
height: 28px;
background: #49d;
}
+
+/*# sourceMappingURL=jBox.TooltipBorder.css.map */
diff --git a/dist/themes/jBox.TooltipBorder.min.css b/dist/themes/jBox.TooltipBorder.min.css
new file mode 100755
index 0000000..9be505b
--- /dev/null
+++ b/dist/themes/jBox.TooltipBorder.min.css
@@ -0,0 +1 @@
+.jBox-TooltipBorder .jBox-container,.jBox-TooltipBorder .jBox-pointer:after{border:2px solid #49d}.jBox-TooltipBorder .jBox-pointer:after{width:22px;height:22px}.jBox-TooltipBorder .jBox-pointer-bottom,.jBox-TooltipBorder .jBox-pointer-top{width:34px;height:13px}.jBox-TooltipBorder .jBox-pointer-bottom:after,.jBox-TooltipBorder .jBox-pointer-top:after{left:6px}.jBox-TooltipBorder .jBox-pointer-left,.jBox-TooltipBorder .jBox-pointer-right{width:13px;height:34px}.jBox-TooltipBorder .jBox-pointer-left:after,.jBox-TooltipBorder .jBox-pointer-right:after{top:6px}.jBox-TooltipBorder.jBox-closeButton-box:before{width:28px;height:28px;background:#49d}
\ No newline at end of file
diff --git a/Source/themes/TooltipBorderThick.css b/dist/themes/jBox.TooltipBorderThick.css
old mode 100644
new mode 100755
similarity index 86%
rename from Source/themes/TooltipBorderThick.css
rename to dist/themes/jBox.TooltipBorderThick.css
index ea34134..544fbb0
--- a/Source/themes/TooltipBorderThick.css
+++ b/dist/themes/jBox.TooltipBorderThick.css
@@ -1,17 +1,14 @@
-
-/* jBox theme: TooltipBorderThick */
-
.jBox-TooltipBorderThick .jBox-container {
box-shadow: none;
border-radius: 8px;
border: 4px solid #ccc;
}
-/* Pointer */
-
.jBox-TooltipBorderThick .jBox-pointer:after {
box-shadow: none;
border: 4px solid #ccc;
+ width: 24px;
+ height: 24px;
}
.jBox-TooltipBorderThick .jBox-pointer-top,
@@ -26,10 +23,10 @@
height: 38px;
}
-/* Close button */
-
.jBox-TooltipBorderThick.jBox-closeButton-box:before {
width: 32px;
height: 32px;
background: #ccc;
}
+
+/*# sourceMappingURL=jBox.TooltipBorderThick.css.map */
diff --git a/dist/themes/jBox.TooltipBorderThick.min.css b/dist/themes/jBox.TooltipBorderThick.min.css
new file mode 100755
index 0000000..e16523b
--- /dev/null
+++ b/dist/themes/jBox.TooltipBorderThick.min.css
@@ -0,0 +1 @@
+.jBox-TooltipBorderThick .jBox-container{box-shadow:none;border-radius:8px;border:4px solid #ccc}.jBox-TooltipBorderThick .jBox-pointer:after{box-shadow:none;border:4px solid #ccc;width:24px;height:24px}.jBox-TooltipBorderThick .jBox-pointer-bottom,.jBox-TooltipBorderThick .jBox-pointer-top{width:38px;height:13px}.jBox-TooltipBorderThick .jBox-pointer-left,.jBox-TooltipBorderThick .jBox-pointer-right{width:13px;height:38px}.jBox-TooltipBorderThick.jBox-closeButton-box:before{width:32px;height:32px;background:#ccc}
\ No newline at end of file
diff --git a/Source/themes/TooltipDark.css b/dist/themes/jBox.TooltipDark.css
old mode 100644
new mode 100755
similarity index 74%
rename from Source/themes/TooltipDark.css
rename to dist/themes/jBox.TooltipDark.css
index 2021fee..65a7c5a
--- a/Source/themes/TooltipDark.css
+++ b/dist/themes/jBox.TooltipDark.css
@@ -1,27 +1,20 @@
-
-/* jBox theme: TooltipDark */
-
.jBox-TooltipDark .jBox-container {
- border-radius: 3px;
+ border-radius: 4px;
background: #000;
color: #fff;
- box-shadow: 0 0 6px rgba(0, 0, 0, .4);
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
}
-/* Pointer */
-
.jBox-TooltipDark .jBox-pointer:after {
background: #000;
}
-/* Close button */
-
.jBox-TooltipDark .jBox-closeButton {
background: #000;
}
.jBox-TooltipDark.jBox-closeButton-box:before {
- box-shadow: 0 0 6px rgba(0, 0, 0, .4);
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
}
.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path {
@@ -35,3 +28,5 @@
.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path {
fill: #bbb;
}
+
+/*# sourceMappingURL=jBox.TooltipDark.css.map */
diff --git a/dist/themes/jBox.TooltipDark.min.css b/dist/themes/jBox.TooltipDark.min.css
new file mode 100755
index 0000000..46733e4
--- /dev/null
+++ b/dist/themes/jBox.TooltipDark.min.css
@@ -0,0 +1 @@
+.jBox-TooltipDark .jBox-container{border-radius:4px;background:#000;color:#fff;box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark .jBox-pointer:after{background:#000}.jBox-TooltipDark .jBox-closeButton{background:#000}.jBox-TooltipDark.jBox-closeButton-box:before{box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path{fill:#ddd}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path{fill:#fff}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path{fill:#bbb}
\ No newline at end of file
diff --git a/Source/themes/TooltipError.css b/dist/themes/jBox.TooltipError.css
old mode 100644
new mode 100755
similarity index 77%
rename from Source/themes/TooltipError.css
rename to dist/themes/jBox.TooltipError.css
index f94fe4a..0d58312
--- a/Source/themes/TooltipError.css
+++ b/dist/themes/jBox.TooltipError.css
@@ -1,15 +1,7 @@
-
-/* jBox theme: TooltipError */
-
.jBox-TooltipError {
pointer-events: none;
}
-.jBox-TooltipError .jBox-content {
- padding: 0 10px;
- line-height: 28px;
-}
-
.jBox-TooltipError .jBox-container {
border-radius: 2px;
background: #d00;
@@ -18,16 +10,9 @@
font-size: 13px;
}
-.jBox-TooltipError .jBox-pointer-top,
-.jBox-TooltipError .jBox-pointer-bottom {
- width: 22px;
- height: 8px;
-}
-
-.jBox-TooltipError .jBox-pointer-right,
-.jBox-TooltipError .jBox-pointer-left {
- width: 8px;
- height: 22px;
+.jBox-TooltipError .jBox-content {
+ padding: 0 10px;
+ line-height: 28px;
}
.jBox-TooltipError .jBox-pointer:after {
@@ -36,14 +21,19 @@
height: 20px;
}
-.jBox-TooltipError .jBox-pointer-top:after {
- left: 1px;
- top: 6px;
+.jBox-TooltipError .jBox-pointer-top, .jBox-TooltipError .jBox-pointer-bottom {
+ width: 22px;
+ height: 8px;
}
-.jBox-TooltipError .jBox-pointer-bottom:after {
+.jBox-TooltipError .jBox-pointer-right, .jBox-TooltipError .jBox-pointer-left {
+ width: 8px;
+ height: 22px;
+}
+
+.jBox-TooltipError .jBox-pointer-top:after {
left: 1px;
- bottom: 6px;
+ top: 6px;
}
.jBox-TooltipError .jBox-pointer-right:after {
@@ -51,7 +41,14 @@
right: 6px;
}
+.jBox-TooltipError .jBox-pointer-bottom:after {
+ left: 1px;
+ bottom: 6px;
+}
+
.jBox-TooltipError .jBox-pointer-left:after {
top: 1px;
left: 6px;
-}
\ No newline at end of file
+}
+
+/*# sourceMappingURL=jBox.TooltipError.css.map */
diff --git a/dist/themes/jBox.TooltipError.min.css b/dist/themes/jBox.TooltipError.min.css
new file mode 100755
index 0000000..36022b2
--- /dev/null
+++ b/dist/themes/jBox.TooltipError.min.css
@@ -0,0 +1 @@
+.jBox-TooltipError{pointer-events:none}.jBox-TooltipError .jBox-container{border-radius:2px;background:#d00;color:#fff;font-weight:700;font-size:13px}.jBox-TooltipError .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipError .jBox-pointer:after{background:#d00;width:20px;height:20px}.jBox-TooltipError .jBox-pointer-bottom,.jBox-TooltipError .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipError .jBox-pointer-left,.jBox-TooltipError .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipError .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipError .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipError .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipError .jBox-pointer-left:after{top:1px;left:6px}
\ No newline at end of file
diff --git a/Source/themes/TooltipSmall.css b/dist/themes/jBox.TooltipSmall.css
old mode 100644
new mode 100755
similarity index 74%
rename from Source/themes/TooltipSmall.css
rename to dist/themes/jBox.TooltipSmall.css
index 7f7f66c..debe4ed
--- a/Source/themes/TooltipSmall.css
+++ b/dist/themes/jBox.TooltipSmall.css
@@ -1,52 +1,49 @@
-
-/* jBox theme: TooltipSmall */
-
.jBox-TooltipSmall {
pointer-events: none;
}
+.jBox-TooltipSmall .jBox-container {
+ border-radius: 2px;
+}
+
.jBox-TooltipSmall .jBox-content {
padding: 0 10px;
line-height: 28px;
}
-.jBox-TooltipSmall .jBox-container {
- border-radius: 2px;
+.jBox-TooltipSmall .jBox-pointer:after {
+ width: 20px;
+ height: 20px;
}
-.jBox-TooltipSmall .jBox-pointer-top,
-.jBox-TooltipSmall .jBox-pointer-bottom {
+.jBox-TooltipSmall .jBox-pointer-top, .jBox-TooltipSmall .jBox-pointer-bottom {
width: 22px;
height: 8px;
}
-.jBox-TooltipSmall .jBox-pointer-right,
-.jBox-TooltipSmall .jBox-pointer-left {
+.jBox-TooltipSmall .jBox-pointer-right, .jBox-TooltipSmall .jBox-pointer-left {
width: 8px;
height: 22px;
}
-.jBox-TooltipSmall .jBox-pointer:after {
- width: 20px;
- height: 20px;
-}
-
.jBox-TooltipSmall .jBox-pointer-top:after {
left: 1px;
top: 6px;
}
-.jBox-TooltipSmall .jBox-pointer-bottom:after {
- left: 1px;
- bottom: 6px;
-}
-
.jBox-TooltipSmall .jBox-pointer-right:after {
top: 1px;
right: 6px;
}
+.jBox-TooltipSmall .jBox-pointer-bottom:after {
+ left: 1px;
+ bottom: 6px;
+}
+
.jBox-TooltipSmall .jBox-pointer-left:after {
top: 1px;
left: 6px;
-}
\ No newline at end of file
+}
+
+/*# sourceMappingURL=jBox.TooltipSmall.css.map */
diff --git a/dist/themes/jBox.TooltipSmall.min.css b/dist/themes/jBox.TooltipSmall.min.css
new file mode 100755
index 0000000..e3987dc
--- /dev/null
+++ b/dist/themes/jBox.TooltipSmall.min.css
@@ -0,0 +1 @@
+.jBox-TooltipSmall{pointer-events:none}.jBox-TooltipSmall .jBox-container{border-radius:2px}.jBox-TooltipSmall .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipSmall .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmall .jBox-pointer-bottom,.jBox-TooltipSmall .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmall .jBox-pointer-left,.jBox-TooltipSmall .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmall .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipSmall .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmall .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipSmall .jBox-pointer-left:after{top:1px;left:6px}
\ No newline at end of file
diff --git a/Source/themes/TooltipSmallGray.css b/dist/themes/jBox.TooltipSmallGray.css
old mode 100644
new mode 100755
similarity index 77%
rename from Source/themes/TooltipSmallGray.css
rename to dist/themes/jBox.TooltipSmallGray.css
index 9303606..3dc31ad
--- a/Source/themes/TooltipSmallGray.css
+++ b/dist/themes/jBox.TooltipSmallGray.css
@@ -1,14 +1,7 @@
-
-/* jBox theme: TooltipSmall */
-
.jBox-TooltipSmallGray {
pointer-events: none;
}
-.jBox-TooltipSmallGray .jBox-content {
- padding: 0 10px;
-}
-
.jBox-TooltipSmallGray .jBox-container {
font-size: 13px;
line-height: 24px;
@@ -16,41 +9,45 @@
background-image: linear-gradient(to bottom, #fafafa, #f2f2f2);
}
-.jBox-TooltipSmallGray .jBox-pointer-top,
-.jBox-TooltipSmallGray .jBox-pointer-bottom {
+.jBox-TooltipSmallGray .jBox-content {
+ padding: 0 10px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer:after {
+ width: 20px;
+ height: 20px;
+}
+
+.jBox-TooltipSmallGray .jBox-pointer-top, .jBox-TooltipSmallGray .jBox-pointer-bottom {
width: 22px;
height: 8px;
}
-.jBox-TooltipSmallGray .jBox-pointer-right,
-.jBox-TooltipSmallGray .jBox-pointer-left {
+.jBox-TooltipSmallGray .jBox-pointer-left, .jBox-TooltipSmallGray .jBox-pointer-right {
width: 8px;
height: 22px;
}
-.jBox-TooltipSmallGray .jBox-pointer:after {
- width: 20px;
- height: 20px;
-}
-
.jBox-TooltipSmallGray .jBox-pointer-top:after {
background: #fafafa;
left: 1px;
top: 6px;
}
+.jBox-TooltipSmallGray .jBox-pointer-right:after {
+ top: 1px;
+ right: 6px;
+}
+
.jBox-TooltipSmallGray .jBox-pointer-bottom:after {
background: #f2f2f2;
left: 1px;
bottom: 6px;
}
-.jBox-TooltipSmallGray .jBox-pointer-right:after {
- top: 1px;
- right: 6px;
-}
-
.jBox-TooltipSmallGray .jBox-pointer-left:after {
top: 1px;
left: 6px;
-}
\ No newline at end of file
+}
+
+/*# sourceMappingURL=jBox.TooltipSmallGray.css.map */
diff --git a/dist/themes/jBox.TooltipSmallGray.min.css b/dist/themes/jBox.TooltipSmallGray.min.css
new file mode 100755
index 0000000..e9a178c
--- /dev/null
+++ b/dist/themes/jBox.TooltipSmallGray.min.css
@@ -0,0 +1 @@
+.jBox-TooltipSmallGray{pointer-events:none}.jBox-TooltipSmallGray .jBox-container{font-size:13px;line-height:24px;border-radius:12px;background-image:linear-gradient(to bottom,#fafafa,#f2f2f2)}.jBox-TooltipSmallGray .jBox-content{padding:0 10px}.jBox-TooltipSmallGray .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmallGray .jBox-pointer-bottom,.jBox-TooltipSmallGray .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmallGray .jBox-pointer-left,.jBox-TooltipSmallGray .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmallGray .jBox-pointer-top:after{background:#fafafa;left:1px;top:6px}.jBox-TooltipSmallGray .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmallGray .jBox-pointer-bottom:after{background:#f2f2f2;left:1px;bottom:6px}.jBox-TooltipSmallGray .jBox-pointer-left:after{top:1px;left:6px}
\ No newline at end of file
diff --git a/documentation.html b/documentation.html
index 8018d43..db052ff 100755
--- a/documentation.html
+++ b/documentation.html
@@ -1,9 +1,9 @@
-jBox Documentation
+jBox documentation
-
+
-Redirecting to https://stephanwagner.me/jBox/documentation
+Redirecting to https://stephanwagner.me/jBox/documentation
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100755
index 0000000..3abf054
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,183 @@
+var gulp = require('gulp');
+var sass = require('gulp-sass')(require('sass'));
+var cleanCSS = require('gulp-clean-css');
+var concat = require('gulp-concat');
+var rename = require('gulp-rename');
+var uglify = require('gulp-uglify');
+var sourcemaps = require('gulp-sourcemaps');
+
+// Plugins
+var plugins = [
+ 'Confirm',
+ 'Image',
+ 'Notice'
+];
+
+// Themes
+var themes = [
+ 'NoticeFancy',
+ 'TooltipBorder',
+ 'TooltipBorderThick',
+ 'TooltipDark',
+ 'TooltipError',
+ 'TooltipSmall',
+ 'TooltipSmallGray'
+];
+
+// CSS
+var styles = [{
+ name: 'jBox',
+ src: ['./src/scss/jBox.scss'],
+ dest: './dist/'
+}, {
+ name: 'jBox.all',
+ src: [
+ './src/scss/jBox.scss',
+ './src/scss/plugins/*.scss',
+ './src/scss/themes/*.scss'
+ ],
+ dest: './dist/'
+}];
+
+for (let plugin of plugins) {
+ styles.push({
+ name: 'jBox.' + plugin,
+ src: ['./src/scss/plugins/jBox.' + plugin + '.scss'],
+ dest: './dist/plugins/'
+ });
+}
+
+for (let theme of themes) {
+ styles.push({
+ name: 'jBox.' + theme,
+ src: ['./src/scss/themes/jBox.' + theme + '.scss'],
+ dest: './dist/themes/'
+ });
+}
+
+// JavaScript
+var scripts = [{
+ name: 'jBox',
+ src: [
+ './src/js/jBox.js',
+ './src/js/umd.js'
+ ],
+ dest: './dist/'
+}, {
+ name: 'jBox.all',
+ src: [
+ './src/js/jBox.js',
+ './src/js/plugins/*.js',
+ './src/js/umd.js'
+ ],
+ dest: './dist/'
+}];
+
+for (let plugin of plugins) {
+ scripts.push({
+ name: 'jBox.' + plugin,
+ src: ['./src/js/plugins/jBox.' + plugin + '.js'],
+ dest: './dist/plugins/'
+ });
+}
+
+// Config tasks
+let defaultTasks = [];
+let buildTasks = [];
+let watchTasks = [];
+
+// Config CSS tasks
+for (const item of styles) {
+
+ // Concat CSS
+ const cssConcat = function () {
+ return gulp
+ .src(item.src)
+ .pipe(sourcemaps.init())
+ .pipe(sass({
+ outputStyle: 'expanded'
+ }).on('error', sass.logError))
+ .pipe(concat(item.name + '.css'))
+ .pipe(sourcemaps.write('./'))
+ .pipe(gulp.dest(item.dest));
+ };
+
+ // Store as a task
+ gulp.task('cssConcat-' + item.name, cssConcat);
+
+ // Add to default tasks
+ defaultTasks.push('cssConcat-' + item.name);
+
+ // Add to watch tasks
+ watchTasks.push({
+ src: item.src,
+ task: cssConcat
+ });
+
+ // Build CSS
+ const cssBuild = function () {
+ return gulp
+ .src(item.dest + item.name + '.css')
+ .pipe(rename(item.name + '.min.css'))
+ .pipe(cleanCSS())
+ .pipe(gulp.dest(item.dest));
+ };
+
+ // Store as a task
+ gulp.task('cssBuild-' + item.name, cssBuild);
+
+ // Add to build tasks
+ buildTasks.push('cssBuild-' + item.name);
+}
+
+// Config JavaScript tasks
+for (let item of scripts) {
+
+ // Concat JavaScript
+ const jsConcat = function () {
+ return gulp
+ .src(item.src)
+ .pipe(sourcemaps.init())
+ .pipe(concat(item.name + '.js'))
+ .pipe(sourcemaps.write('./'))
+ .pipe(gulp.dest(item.dest));
+ };
+
+ // Store as a task
+ gulp.task('jsConcat-' + item.name, jsConcat);
+
+ // Add to default tasks
+ defaultTasks.push('jsConcat-' + item.name);
+
+ // Add to watch tasks
+ watchTasks.push({
+ src: item.src,
+ task: jsConcat
+ });
+
+ // Build JavaScript
+ const jsBuild = function () {
+ return gulp
+ .src(item.dest + item.name + '.js')
+ .pipe(rename(item.name + '.min.js'))
+ .pipe(uglify())
+ .pipe(gulp.dest(item.dest));
+ };
+
+ // Store as a task
+ gulp.task('jsBuild-' + item.name, jsBuild);
+
+ // Add to build tasks
+ buildTasks.push('jsBuild-' + item.name);
+}
+
+// Watch tasks
+function watch() {
+ for (const watchTask of watchTasks) {
+ gulp.watch(watchTask.src, watchTask.task);
+ }
+}
+
+exports.default = gulp.series(defaultTasks);
+exports.watch = gulp.series(defaultTasks, watch);
+exports.build = gulp.series(defaultTasks, buildTasks);
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..ffc6a4a
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6594 @@
+{
+ "name": "jbox",
+ "version": "1.3.3",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.14.5"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.5.tgz",
+ "integrity": "sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz",
+ "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helpers": "^7.14.6",
+ "@babel/parser": "^7.14.6",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.1.2",
+ "semver": "^6.3.0",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz",
+ "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.14.5",
+ "@babel/helper-validator-option": "^7.14.5",
+ "browserslist": "^4.16.6",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz",
+ "integrity": "sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz",
+ "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-simple-access": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz",
+ "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz",
+ "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==",
+ "dev": true
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz",
+ "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz",
+ "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "dev": true
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz",
+ "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==",
+ "dev": true
+ },
+ "@babel/helpers": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz",
+ "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz",
+ "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==",
+ "dev": true
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/plugin-syntax-typescript": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz",
+ "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.23.0",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "dev": true
+ },
+ "@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ }
+ },
+ "@babel/types": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "@gulp-sourcemaps/identity-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz",
+ "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.4.1",
+ "normalize-path": "^3.0.0",
+ "postcss": "^7.0.16",
+ "source-map": "^0.6.0",
+ "through2": "^3.0.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ }
+ }
+ }
+ },
+ "@gulp-sourcemaps/map-sources": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz",
+ "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^2.0.1",
+ "through2": "^2.0.3"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "@gulpjs/messages": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz",
+ "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==",
+ "dev": true
+ },
+ "@gulpjs/to-absolute-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz",
+ "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==",
+ "dev": true,
+ "requires": {
+ "is-negated-glob": "^1.0.0"
+ }
+ },
+ "@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ }
+ }
+ },
+ "@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true
+ },
+ "@jest/console": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.2.tgz",
+ "integrity": "sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^27.0.2",
+ "jest-util": "^27.0.2",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/core": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.4.tgz",
+ "integrity": "sha512-+dsmV8VUs1h/Szb+rEWk8xBM1fp1I///uFy9nk3wXGvRsF2lBp8EVPmtWc+QFRb3MY2b7u2HbkGF1fzoDzQTLA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^27.0.2",
+ "@jest/reporters": "^27.0.4",
+ "@jest/test-result": "^27.0.2",
+ "@jest/transform": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.8.1",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-changed-files": "^27.0.2",
+ "jest-config": "^27.0.4",
+ "jest-haste-map": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-regex-util": "^27.0.1",
+ "jest-resolve": "^27.0.4",
+ "jest-resolve-dependencies": "^27.0.4",
+ "jest-runner": "^27.0.4",
+ "jest-runtime": "^27.0.4",
+ "jest-snapshot": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "jest-validate": "^27.0.2",
+ "jest-watcher": "^27.0.2",
+ "micromatch": "^4.0.4",
+ "p-each-series": "^2.1.0",
+ "rimraf": "^3.0.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "@jest/environment": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.3.tgz",
+ "integrity": "sha512-pN9m7fbKsop5vc3FOfH8NF7CKKdRbEZzcxfIo1n2TT6ucKWLFq0P6gCJH0GpnQp036++yY9utHOxpeT1WnkWTA==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^27.0.3",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "jest-mock": "^27.0.3"
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.3.tgz",
+ "integrity": "sha512-fQ+UCKRIYKvTCEOyKPnaPnomLATIhMnHC/xPZ7yT1Uldp7yMgMxoYIFidDbpSTgB79+/U+FgfoD30c6wg3IUjA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "@sinonjs/fake-timers": "^7.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^27.0.2",
+ "jest-mock": "^27.0.3",
+ "jest-util": "^27.0.2"
+ }
+ },
+ "@jest/globals": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.3.tgz",
+ "integrity": "sha512-OzsIuf7uf+QalqAGbjClyezzEcLQkdZ+7PejUrZgDs+okdAK8GwRCGcYCirHvhMBBQh60Jr3NlIGbn/KBPQLEQ==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^27.0.3",
+ "@jest/types": "^27.0.2",
+ "expect": "^27.0.2"
+ }
+ },
+ "@jest/reporters": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.4.tgz",
+ "integrity": "sha512-Xa90Nm3JnV0xCe4M6A10M9WuN9krb+WFKxV1A98Y4ePCw40n++r7uxFUNU7DT1i9Behj7fjrAIju9oU0t1QtCg==",
+ "dev": true,
+ "requires": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^27.0.2",
+ "@jest/test-result": "^27.0.2",
+ "@jest/transform": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.2",
+ "graceful-fs": "^4.2.4",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^4.0.3",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.0.2",
+ "jest-haste-map": "^27.0.2",
+ "jest-resolve": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "jest-worker": "^27.0.2",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.0",
+ "string-length": "^4.0.1",
+ "terminal-link": "^2.0.0",
+ "v8-to-istanbul": "^7.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jest/source-map": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.1.tgz",
+ "integrity": "sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/test-result": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.2.tgz",
+ "integrity": "sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ }
+ },
+ "@jest/test-sequencer": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.4.tgz",
+ "integrity": "sha512-6UFEVwdmxYdyNffBxVVZxmXEdBE4riSddXYSnFNH0ELFQFk/bvagizim8WfgJTqF4EKd+j1yFxvhb8BMHfOjSQ==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^27.0.2",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.0.2",
+ "jest-runtime": "^27.0.4"
+ }
+ },
+ "@jest/transform": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.2.tgz",
+ "integrity": "sha512-H8sqKlgtDfVog/s9I4GG2XMbi4Ar7RBxjsKQDUhn2XHAi3NG+GoQwWMER+YfantzExbjNqQvqBHzo/G2pfTiPw==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/types": "^27.0.2",
+ "babel-plugin-istanbul": "^6.0.0",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.0.2",
+ "jest-regex-util": "^27.0.1",
+ "jest-util": "^27.0.2",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.1",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.1",
+ "write-file-atomic": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "@jest/types": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
+ "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
+ "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/fake-timers": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
+ "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true
+ },
+ "@types/babel__core": {
+ "version": "7.1.14",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
+ "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "@types/babel__generator": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
+ "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__template": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
+ "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__traverse": {
+ "version": "7.11.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz",
+ "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "@types/graceful-fs": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
+ "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/istanbul-lib-coverage": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
+ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==",
+ "dev": true
+ },
+ "@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "@types/node": {
+ "version": "15.12.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.4.tgz",
+ "integrity": "sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA==",
+ "dev": true
+ },
+ "@types/prettier": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.0.tgz",
+ "integrity": "sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==",
+ "dev": true
+ },
+ "@types/stack-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
+ "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
+ "dev": true
+ },
+ "@types/yargs": {
+ "version": "16.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
+ "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "@types/yargs-parser": {
+ "version": "20.2.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz",
+ "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
+ "dev": true
+ },
+ "abab": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "dev": true
+ },
+ "acorn-globals": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+ "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ }
+ }
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ },
+ "agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "requires": {
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "dev": true,
+ "requires": {
+ "ansi-wrap": "^0.1.0"
+ }
+ },
+ "ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.21.3"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+ "dev": true
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "async-done": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz",
+ "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.4.4",
+ "once": "^1.4.0",
+ "stream-exhaust": "^1.0.2"
+ }
+ },
+ "async-settle": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz",
+ "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==",
+ "dev": true,
+ "requires": {
+ "async-done": "^2.0.0"
+ }
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "b4a": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz",
+ "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==",
+ "dev": true
+ },
+ "babel-jest": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.2.tgz",
+ "integrity": "sha512-9OThPl3/IQbo4Yul2vMz4FYwILPQak8XelX4YGowygfHaOl5R5gfjm4iVx4d8aUugkW683t8aq0A74E7b5DU1Q==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.0.0",
+ "babel-preset-jest": "^27.0.1",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
+ "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^4.0.0",
+ "test-exclude": "^6.0.0"
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz",
+ "integrity": "sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.0.0",
+ "@types/babel__traverse": "^7.0.6"
+ }
+ },
+ "babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ }
+ },
+ "babel-preset-jest": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz",
+ "integrity": "sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-jest-hoist": "^27.0.1",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ }
+ },
+ "bach": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz",
+ "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==",
+ "dev": true,
+ "requires": {
+ "async-done": "^2.0.0",
+ "async-settle": "^2.0.0",
+ "now-and-later": "^3.0.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "bare-events": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz",
+ "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==",
+ "dev": true,
+ "optional": true
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true
+ },
+ "bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dev": true,
+ "requires": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.1.1"
+ }
+ },
+ "browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true
+ },
+ "browserslist": {
+ "version": "4.16.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+ "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001219",
+ "colorette": "^1.2.2",
+ "electron-to-chromium": "^1.3.723",
+ "escalade": "^3.1.1",
+ "node-releases": "^1.1.71"
+ }
+ },
+ "bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "requires": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001239",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz",
+ "integrity": "sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
+ "ci-info": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
+ "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
+ "dev": true
+ },
+ "cjs-module-lexer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz",
+ "integrity": "sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw==",
+ "dev": true
+ },
+ "clean-css": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
+ "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
+ "dev": true,
+ "requires": {
+ "source-map": "~0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
+ "clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+ "dev": true
+ },
+ "clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+ "dev": true
+ },
+ "cloneable-readable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+ "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "process-nextick-args": "^2.0.0",
+ "readable-stream": "^2.3.5"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "colorette": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
+ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-with-sourcemaps": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz",
+ "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "copy-props": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz",
+ "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==",
+ "dev": true,
+ "requires": {
+ "each-props": "^3.0.0",
+ "is-plain-object": "^5.0.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "css": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
+ "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
+ "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0"
+ }
+ }
+ }
+ },
+ "cssom": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+ "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "requires": {
+ "cssom": "~0.3.6"
+ },
+ "dependencies": {
+ "cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ }
+ }
+ },
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "data-urls": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+ "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.3",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.0.0"
+ }
+ },
+ "debug-fabulous": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz",
+ "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==",
+ "dev": true,
+ "requires": {
+ "debug": "3.X",
+ "memoizee": "0.4.X",
+ "object-assign": "4.X"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ }
+ }
+ },
+ "decimal.js": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
+ "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "dev": true
+ },
+ "dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
+ "dev": true
+ },
+ "detect-newline": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz",
+ "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==",
+ "dev": true
+ },
+ "domexception": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+ "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "^5.0.0"
+ },
+ "dependencies": {
+ "webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "dev": true
+ }
+ }
+ },
+ "each-props": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz",
+ "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^5.0.0",
+ "object.defaults": "^1.1.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "electron-to-chromium": {
+ "version": "1.3.752",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
+ "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
+ "dev": true
+ },
+ "emittery": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz",
+ "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.53",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+ "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "next-tick": "~1.0.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escodegen": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+ "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+ "dev": true,
+ "requires": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "expect": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz",
+ "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "ansi-styles": "^5.0.0",
+ "jest-get-type": "^27.0.1",
+ "jest-matcher-utils": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-regex-util": "^27.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "ext": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+ "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+ "dev": true,
+ "requires": {
+ "type": "^2.0.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
+ "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==",
+ "dev": true
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "fast-fifo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
+ "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
+ "dev": true,
+ "requires": {
+ "fastest-levenshtein": "^1.0.7"
+ }
+ },
+ "fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "fb-watchman": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+ "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+ "dev": true,
+ "requires": {
+ "bser": "2.1.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "findup-sync": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
+ "dev": true,
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ },
+ "fined": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz",
+ "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^5.0.0",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.3.0",
+ "parse-filepath": "^1.0.2"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "flagged-respawn": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz",
+ "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==",
+ "dev": true
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
+ "dev": true
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "fs-mkdirp-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz",
+ "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.8",
+ "streamx": "^2.12.0"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ }
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "glob-stream": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz",
+ "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==",
+ "dev": true,
+ "requires": {
+ "@gulpjs/to-absolute-glob": "^4.0.0",
+ "anymatch": "^3.1.3",
+ "fastq": "^1.13.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "is-negated-glob": "^1.0.0",
+ "normalize-path": "^3.0.0",
+ "streamx": "^2.12.5"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.3"
+ }
+ }
+ }
+ },
+ "glob-watcher": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz",
+ "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==",
+ "dev": true,
+ "requires": {
+ "async-done": "^2.0.0",
+ "chokidar": "^3.5.3"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "glogg": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
+ "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+ "dev": true,
+ "requires": {
+ "sparkles": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "dev": true
+ },
+ "gulp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz",
+ "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==",
+ "dev": true,
+ "requires": {
+ "glob-watcher": "^6.0.0",
+ "gulp-cli": "^3.0.0",
+ "undertaker": "^2.0.0",
+ "vinyl-fs": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "glogg": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz",
+ "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==",
+ "dev": true,
+ "requires": {
+ "sparkles": "^2.1.0"
+ }
+ },
+ "gulp-cli": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz",
+ "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==",
+ "dev": true,
+ "requires": {
+ "@gulpjs/messages": "^1.1.0",
+ "chalk": "^4.1.2",
+ "copy-props": "^4.0.0",
+ "gulplog": "^2.2.0",
+ "interpret": "^3.1.1",
+ "liftoff": "^5.0.0",
+ "mute-stdout": "^2.0.0",
+ "replace-homedir": "^2.0.0",
+ "semver-greatest-satisfied-range": "^2.0.0",
+ "string-width": "^4.2.3",
+ "v8flags": "^4.0.0",
+ "yargs": "^16.2.0"
+ }
+ },
+ "gulplog": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz",
+ "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==",
+ "dev": true,
+ "requires": {
+ "glogg": "^2.2.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "sparkles": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz",
+ "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "gulp-clean-css": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz",
+ "integrity": "sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg==",
+ "dev": true,
+ "requires": {
+ "clean-css": "4.2.3",
+ "plugin-error": "1.0.1",
+ "through2": "3.0.1",
+ "vinyl-sourcemaps-apply": "0.2.1"
+ },
+ "dependencies": {
+ "through2": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
+ "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2 || 3"
+ }
+ }
+ }
+ },
+ "gulp-concat": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz",
+ "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=",
+ "dev": true,
+ "requires": {
+ "concat-with-sourcemaps": "^1.0.0",
+ "through2": "^2.0.0",
+ "vinyl": "^2.0.0"
+ }
+ },
+ "gulp-rename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz",
+ "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==",
+ "dev": true
+ },
+ "gulp-sass": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz",
+ "integrity": "sha512-7VT0uaF+VZCmkNBglfe1b34bxn/AfcssquLKVDYnCDJ3xNBaW7cUuI3p3BQmoKcoKFrs9jdzUxyb+u+NGfL4OQ==",
+ "dev": true,
+ "requires": {
+ "lodash.clonedeep": "^4.5.0",
+ "picocolors": "^1.0.0",
+ "plugin-error": "^1.0.1",
+ "replace-ext": "^2.0.0",
+ "strip-ansi": "^6.0.1",
+ "vinyl-sourcemaps-apply": "^0.2.1"
+ },
+ "dependencies": {
+ "replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ }
+ }
+ },
+ "gulp-sourcemaps": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz",
+ "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==",
+ "dev": true,
+ "requires": {
+ "@gulp-sourcemaps/identity-map": "^2.0.1",
+ "@gulp-sourcemaps/map-sources": "^1.0.0",
+ "acorn": "^6.4.1",
+ "convert-source-map": "^1.0.0",
+ "css": "^3.0.0",
+ "debug-fabulous": "^1.0.0",
+ "detect-newline": "^2.0.0",
+ "graceful-fs": "^4.0.0",
+ "source-map": "^0.6.0",
+ "strip-bom-string": "^1.0.0",
+ "through2": "^2.0.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "gulp-uglify": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz",
+ "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==",
+ "dev": true,
+ "requires": {
+ "array-each": "^1.0.1",
+ "extend-shallow": "^3.0.2",
+ "gulplog": "^1.0.0",
+ "has-gulplog": "^0.1.0",
+ "isobject": "^3.0.1",
+ "make-error-cause": "^1.1.1",
+ "safe-buffer": "^5.1.2",
+ "through2": "^2.0.0",
+ "uglify-js": "^3.0.5",
+ "vinyl-sourcemaps-apply": "^0.2.0"
+ }
+ },
+ "gulplog": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+ "dev": true,
+ "requires": {
+ "glogg": "^1.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-gulplog": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
+ "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=",
+ "dev": true,
+ "requires": {
+ "sparkles": "^1.0.0"
+ }
+ },
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "html-encoding-sniffer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+ "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
+ "dev": true,
+ "requires": {
+ "whatwg-encoding": "^1.0.5"
+ }
+ },
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "requires": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "dev": true,
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true
+ },
+ "immutable": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz",
+ "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==",
+ "dev": true
+ },
+ "import-local": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
+ "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-ci": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
+ "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^3.1.1"
+ }
+ },
+ "is-core-module": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
+ "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-negated-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true
+ },
+ "is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "dev": true
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "istanbul-lib-coverage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+ "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.7.5",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.0.0",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+ "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+ "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
+ "jest": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.4.tgz",
+ "integrity": "sha512-Px1iKFooXgGSkk1H8dJxxBIrM3tsc5SIuI4kfKYK2J+4rvCvPGr/cXktxh0e9zIPQ5g09kOMNfHQEmusBUf/ZA==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^27.0.4",
+ "import-local": "^3.0.2",
+ "jest-cli": "^27.0.4"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "jest-cli": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.4.tgz",
+ "integrity": "sha512-E0T+/i2lxsWAzV7LKYd0SB7HUAvePqaeIh5vX43/G5jXLhv1VzjYzJAGEkTfvxV774ll9cyE2ljcL73PVMEOXQ==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^27.0.4",
+ "@jest/test-result": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "import-local": "^3.0.2",
+ "jest-config": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "jest-validate": "^27.0.2",
+ "prompts": "^2.0.1",
+ "yargs": "^16.0.3"
+ }
+ },
+ "string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-changed-files": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.2.tgz",
+ "integrity": "sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "execa": "^5.0.0",
+ "throat": "^6.0.1"
+ }
+ },
+ "jest-circus": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.4.tgz",
+ "integrity": "sha512-QD+eblDiRphta630WRKewuASLs/oY1Zki2G4bccntRvrTHQ63ljwFR5TLduuK4Zg0ZPzW0+8o6AP7KRd1yKOjw==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^27.0.3",
+ "@jest/test-result": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "expect": "^27.0.2",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^27.0.2",
+ "jest-matcher-utils": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-runtime": "^27.0.4",
+ "jest-snapshot": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "pretty-format": "^27.0.2",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3",
+ "throat": "^6.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-config": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.4.tgz",
+ "integrity": "sha512-VkQFAHWnPQefdvHU9A+G3H/Z3NrrTKqWpvxgQz3nkUdkDTWeKJE6e//BL+R7z79dXOMVksYgM/z6ndtN0hfChg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/test-sequencer": "^27.0.4",
+ "@jest/types": "^27.0.2",
+ "babel-jest": "^27.0.2",
+ "chalk": "^4.0.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.1",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^3.0.0",
+ "jest-circus": "^27.0.4",
+ "jest-environment-jsdom": "^27.0.3",
+ "jest-environment-node": "^27.0.3",
+ "jest-get-type": "^27.0.1",
+ "jest-jasmine2": "^27.0.4",
+ "jest-regex-util": "^27.0.1",
+ "jest-resolve": "^27.0.4",
+ "jest-runner": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "jest-validate": "^27.0.2",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^27.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "jest-diff": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz",
+ "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.0.1",
+ "jest-get-type": "^27.0.1",
+ "pretty-format": "^27.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-docblock": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz",
+ "integrity": "sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^3.0.0"
+ },
+ "dependencies": {
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true
+ }
+ }
+ },
+ "jest-each": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.2.tgz",
+ "integrity": "sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^27.0.1",
+ "jest-util": "^27.0.2",
+ "pretty-format": "^27.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-environment-jsdom": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.3.tgz",
+ "integrity": "sha512-5KLmgv1bhiimpSA8oGTnZYk6g4fsNyZiA/6gI2tAZUgrufd7heRUSVh4gRokzZVEj8zlwAQYT0Zs6tuJSW/ECA==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^27.0.3",
+ "@jest/fake-timers": "^27.0.3",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "jest-mock": "^27.0.3",
+ "jest-util": "^27.0.2",
+ "jsdom": "^16.6.0"
+ }
+ },
+ "jest-environment-node": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.3.tgz",
+ "integrity": "sha512-co2/IVnIFL3cItpFULCvXFg9us4gvWXgs7mutAMPCbFhcqh56QAOdKhNzC2+RycsC/k4mbMj1VF+9F/NzA0ROg==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^27.0.3",
+ "@jest/fake-timers": "^27.0.3",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "jest-mock": "^27.0.3",
+ "jest-util": "^27.0.2"
+ }
+ },
+ "jest-get-type": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
+ "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.2.tgz",
+ "integrity": "sha512-37gYfrYjjhEfk37C4bCMWAC0oPBxDpG0qpl8lYg8BT//wf353YT/fzgA7+Dq0EtM7rPFS3JEcMsxdtDwNMi2cA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "@types/graceful-fs": "^4.1.2",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
+ "graceful-fs": "^4.2.4",
+ "jest-regex-util": "^27.0.1",
+ "jest-serializer": "^27.0.1",
+ "jest-util": "^27.0.2",
+ "jest-worker": "^27.0.2",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.7"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "jest-jasmine2": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.4.tgz",
+ "integrity": "sha512-yj3WrjjquZwkJw+eA4c9yucHw4/+EHndHWSqgHbHGQfT94ihaaQsa009j1a0puU8CNxPDk0c1oAPeOpdJUElwA==",
+ "dev": true,
+ "requires": {
+ "@babel/traverse": "^7.1.0",
+ "@jest/environment": "^27.0.3",
+ "@jest/source-map": "^27.0.1",
+ "@jest/test-result": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "expect": "^27.0.2",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^27.0.2",
+ "jest-matcher-utils": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-runtime": "^27.0.4",
+ "jest-snapshot": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "pretty-format": "^27.0.2",
+ "throat": "^6.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-leak-detector": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz",
+ "integrity": "sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^27.0.1",
+ "pretty-format": "^27.0.2"
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz",
+ "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^27.0.2",
+ "jest-get-type": "^27.0.1",
+ "pretty-format": "^27.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-message-util": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz",
+ "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^27.0.2",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^27.0.2",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "jest-mock": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.3.tgz",
+ "integrity": "sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "@types/node": "*"
+ }
+ },
+ "jest-pnp-resolver": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
+ "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
+ "dev": true
+ },
+ "jest-regex-util": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz",
+ "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.4.tgz",
+ "integrity": "sha512-BcfyK2i3cG79PDb/6gB6zFeFQlcqLsQjGBqznFCpA0L/3l1L/oOsltdUjs5eISAWA9HS9qtj8v2PSZr/yWxONQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "chalk": "^4.0.0",
+ "escalade": "^3.1.1",
+ "graceful-fs": "^4.2.4",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^27.0.2",
+ "jest-validate": "^27.0.2",
+ "resolve": "^1.20.0",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.4.tgz",
+ "integrity": "sha512-F33UPfw1YGWCV2uxJl7wD6TvcQn5IC0LtguwY3r4L7R6H4twpLkp5Q2ZfzRx9A2I3G8feiy0O0sqcn/Qoym71A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "jest-regex-util": "^27.0.1",
+ "jest-snapshot": "^27.0.4"
+ }
+ },
+ "jest-runner": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.4.tgz",
+ "integrity": "sha512-NfmvSYLCsCJk2AG8Ar2NAh4PhsJJpO+/r+g4bKR5L/5jFzx/indUpnVBdrfDvuqhGLLAvrKJ9FM/Nt8o1dsqxg==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^27.0.2",
+ "@jest/environment": "^27.0.3",
+ "@jest/test-result": "^27.0.2",
+ "@jest/transform": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.8.1",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-docblock": "^27.0.1",
+ "jest-environment-jsdom": "^27.0.3",
+ "jest-environment-node": "^27.0.3",
+ "jest-haste-map": "^27.0.2",
+ "jest-leak-detector": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-resolve": "^27.0.4",
+ "jest-runtime": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "jest-worker": "^27.0.2",
+ "source-map-support": "^0.5.6",
+ "throat": "^6.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-runtime": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.4.tgz",
+ "integrity": "sha512-voJB4xbAjS/qYPboV+e+gmg3jfvHJJY4CagFWBOM9dQKtlaiTjcpD2tWwla84Z7PtXSQPeIpXY0qksA9Dum29A==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^27.0.2",
+ "@jest/environment": "^27.0.3",
+ "@jest/fake-timers": "^27.0.3",
+ "@jest/globals": "^27.0.3",
+ "@jest/source-map": "^27.0.1",
+ "@jest/test-result": "^27.0.2",
+ "@jest/transform": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-mock": "^27.0.3",
+ "jest-regex-util": "^27.0.1",
+ "jest-resolve": "^27.0.4",
+ "jest-snapshot": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "jest-validate": "^27.0.2",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0",
+ "yargs": "^16.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-serializer": {
+ "version": "27.0.1",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.1.tgz",
+ "integrity": "sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "graceful-fs": "^4.2.4"
+ }
+ },
+ "jest-snapshot": {
+ "version": "27.0.4",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.4.tgz",
+ "integrity": "sha512-hnjrvpKGdSMvKfbHyaG5Kul7pDJGZvjVy0CKpzhu28MmAssDXS6GpynhXzgst1wBQoKD8c9b2VS2a5yhDLQRCA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.7.2",
+ "@babel/generator": "^7.7.2",
+ "@babel/parser": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.0.0",
+ "@jest/transform": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/babel__traverse": "^7.0.4",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^27.0.2",
+ "graceful-fs": "^4.2.4",
+ "jest-diff": "^27.0.2",
+ "jest-get-type": "^27.0.1",
+ "jest-haste-map": "^27.0.2",
+ "jest-matcher-utils": "^27.0.2",
+ "jest-message-util": "^27.0.2",
+ "jest-resolve": "^27.0.4",
+ "jest-util": "^27.0.2",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^27.0.2",
+ "semver": "^7.3.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+ },
+ "jest-util": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.2.tgz",
+ "integrity": "sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^3.0.0",
+ "picomatch": "^2.2.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-validate": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.2.tgz",
+ "integrity": "sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^27.0.1",
+ "leven": "^3.1.0",
+ "pretty-format": "^27.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-watcher": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.2.tgz",
+ "integrity": "sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^27.0.2",
+ "@jest/types": "^27.0.2",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "jest-util": "^27.0.2",
+ "string-length": "^4.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jest-worker": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz",
+ "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jquery": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
+ "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsdom": {
+ "version": "16.6.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz",
+ "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.5",
+ "acorn": "^8.2.4",
+ "acorn-globals": "^6.0.0",
+ "cssom": "^0.4.4",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^2.0.0",
+ "decimal.js": "^10.2.1",
+ "domexception": "^2.0.1",
+ "escodegen": "^2.0.0",
+ "form-data": "^3.0.0",
+ "html-encoding-sniffer": "^2.0.1",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.0",
+ "parse5": "6.0.1",
+ "saxes": "^5.0.1",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.0.0",
+ "w3c-hr-time": "^1.0.2",
+ "w3c-xmlserializer": "^2.0.0",
+ "webidl-conversions": "^6.1.0",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.5.0",
+ "ws": "^7.4.5",
+ "xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.0.tgz",
+ "integrity": "sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w==",
+ "dev": true
+ },
+ "form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ }
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
+ },
+ "kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true
+ },
+ "last-run": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz",
+ "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==",
+ "dev": true
+ },
+ "lead": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz",
+ "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==",
+ "dev": true
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "liftoff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz",
+ "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.2",
+ "findup-sync": "^5.0.0",
+ "fined": "^2.0.0",
+ "flagged-respawn": "^2.0.0",
+ "is-plain-object": "^5.0.0",
+ "rechoir": "^0.8.0",
+ "resolve": "^1.20.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "dev": true
+ },
+ "lru-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "~0.10.2"
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "make-error-cause": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz",
+ "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=",
+ "dev": true,
+ "requires": {
+ "make-error": "^1.2.0"
+ }
+ },
+ "makeerror": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
+ "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+ "dev": true,
+ "requires": {
+ "tmpl": "1.0.x"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
+ "dev": true
+ },
+ "memoizee": {
+ "version": "0.4.15",
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
+ "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.53",
+ "es6-weak-map": "^2.0.3",
+ "event-emitter": "^0.3.5",
+ "is-promise": "^2.2.2",
+ "lru-queue": "^0.1.0",
+ "next-tick": "^1.1.0",
+ "timers-ext": "^0.1.7"
+ },
+ "dependencies": {
+ "next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+ "dev": true
+ }
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
+ "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "dependencies": {
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ }
+ }
+ },
+ "mime-db": {
+ "version": "1.46.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz",
+ "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.29",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz",
+ "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.46.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "mute-stdout": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz",
+ "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "dev": true
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+ "dev": true
+ },
+ "node-modules-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
+ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "1.1.73",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
+ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "now-and-later": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz",
+ "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "nwsapi": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
+ "dev": true,
+ "requires": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "dependencies": {
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ }
+ }
+ },
+ "p-each-series": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
+ "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
+ "dev": true
+ },
+ "parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
+ "dev": true,
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true
+ },
+ "pirates": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
+ "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
+ "dev": true,
+ "requires": {
+ "node-modules-regexp": "^1.0.0"
+ }
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ }
+ }
+ },
+ "plugin-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^1.0.1",
+ "arr-diff": "^4.0.0",
+ "arr-union": "^3.1.0",
+ "extend-shallow": "^3.0.2"
+ }
+ },
+ "postcss": {
+ "version": "7.0.36",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
+ "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "27.0.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
+ "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.0.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "prompts": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
+ "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==",
+ "dev": true,
+ "requires": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true
+ },
+ "queue-tick": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
+ "dev": true
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.20.0"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "replace-ext": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "dev": true
+ },
+ "replace-homedir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz",
+ "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==",
+ "dev": true
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "resolve-options": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz",
+ "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==",
+ "dev": true,
+ "requires": {
+ "value-or-function": "^4.0.0"
+ }
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "sass": {
+ "version": "1.77.4",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.4.tgz",
+ "integrity": "sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==",
+ "dev": true,
+ "requires": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ }
+ },
+ "saxes": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+ "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+ "dev": true,
+ "requires": {
+ "xmlchars": "^2.2.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "optional": true
+ },
+ "semver-greatest-satisfied-range": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz",
+ "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==",
+ "dev": true,
+ "requires": {
+ "sver": "^1.8.3"
+ }
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "sparkles": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ }
+ }
+ },
+ "stream-composer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
+ "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==",
+ "dev": true,
+ "requires": {
+ "streamx": "^2.13.2"
+ }
+ },
+ "stream-exhaust": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+ "dev": true
+ },
+ "streamx": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz",
+ "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==",
+ "dev": true,
+ "requires": {
+ "bare-events": "^2.2.0",
+ "fast-fifo": "^1.3.2",
+ "queue-tick": "^1.0.1",
+ "text-decoder": "^1.1.0"
+ }
+ },
+ "string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "requires": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ }
+ }
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-bom-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
+ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
+ "dev": true
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-hyperlinks": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
+ "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "sver": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz",
+ "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.3.0"
+ }
+ },
+ "symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true
+ },
+ "teex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+ "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+ "dev": true,
+ "requires": {
+ "streamx": "^2.12.5"
+ }
+ },
+ "terminal-link": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
+ "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "supports-hyperlinks": "^2.0.0"
+ }
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "text-decoder": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz",
+ "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==",
+ "dev": true,
+ "requires": {
+ "b4a": "^1.6.4"
+ }
+ },
+ "throat": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
+ "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "timers-ext": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
+ "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
+ "dev": true,
+ "requires": {
+ "es5-ext": "~0.10.46",
+ "next-tick": "1"
+ }
+ },
+ "tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "to-through": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz",
+ "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==",
+ "dev": true,
+ "requires": {
+ "streamx": "^2.12.5"
+ }
+ },
+ "tough-cookie": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "dependencies": {
+ "universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true
+ }
+ }
+ },
+ "tr46": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+ "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.1"
+ }
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "uglify-js": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.1.tgz",
+ "integrity": "sha512-EWhx3fHy3M9JbaeTnO+rEqzCe1wtyQClv6q3YWq0voOj4E+bMZBErVS1GAHPDiRGONYq34M1/d8KuQMgvi6Gjw==",
+ "dev": true
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
+ "dev": true
+ },
+ "undertaker": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz",
+ "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==",
+ "dev": true,
+ "requires": {
+ "bach": "^2.0.1",
+ "fast-levenshtein": "^3.0.0",
+ "last-run": "^2.0.0",
+ "undertaker-registry": "^2.0.0"
+ }
+ },
+ "undertaker-registry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz",
+ "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==",
+ "dev": true
+ },
+ "url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "v8-to-istanbul": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
+ "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0",
+ "source-map": "^0.7.3"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ }
+ }
+ },
+ "v8flags": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
+ "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==",
+ "dev": true
+ },
+ "value-or-function": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz",
+ "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
+ "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ }
+ },
+ "vinyl-contents": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz",
+ "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==",
+ "dev": true,
+ "requires": {
+ "bl": "^5.0.0",
+ "vinyl": "^3.0.0"
+ },
+ "dependencies": {
+ "replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ }
+ }
+ }
+ },
+ "vinyl-fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz",
+ "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==",
+ "dev": true,
+ "requires": {
+ "fs-mkdirp-stream": "^2.0.1",
+ "glob-stream": "^8.0.0",
+ "graceful-fs": "^4.2.11",
+ "iconv-lite": "^0.6.3",
+ "is-valid-glob": "^1.0.0",
+ "lead": "^4.0.0",
+ "normalize-path": "3.0.0",
+ "resolve-options": "^2.0.0",
+ "stream-composer": "^1.0.2",
+ "streamx": "^2.14.0",
+ "to-through": "^3.0.0",
+ "value-or-function": "^4.0.0",
+ "vinyl": "^3.0.0",
+ "vinyl-sourcemap": "^2.0.0"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ },
+ "replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ }
+ }
+ }
+ },
+ "vinyl-sourcemap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz",
+ "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "^2.0.0",
+ "graceful-fs": "^4.2.10",
+ "now-and-later": "^3.0.0",
+ "streamx": "^2.12.5",
+ "vinyl": "^3.0.0",
+ "vinyl-contents": "^2.0.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ }
+ }
+ }
+ },
+ "vinyl-sourcemaps-apply": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.5.1"
+ }
+ },
+ "w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "dev": true,
+ "requires": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "w3c-xmlserializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+ "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+ "dev": true,
+ "requires": {
+ "xml-name-validator": "^3.0.0"
+ }
+ },
+ "walker": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
+ "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+ "dev": true,
+ "requires": {
+ "makeerror": "1.0.x"
+ }
+ },
+ "webidl-conversions": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+ "dev": true
+ },
+ "whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.6.0.tgz",
+ "integrity": "sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.7.0",
+ "tr46": "^2.1.0",
+ "webidl-conversions": "^6.1.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+ "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "dev": true
+ },
+ "xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index f636b64..249ffe7 100644
--- a/package.json
+++ b/package.json
@@ -1,22 +1,52 @@
{
"name": "jbox",
- "version": "0.4.7",
+ "version": "1.3.3",
"description": "jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.",
"keywords": [
- "jquery-plugin", "ecosystem:jquery", "tooltip", "modal", "window", "dialog", "confirm", "popup", "notice", "alert", "ui", "images", "lightbox"
+ "jquery-plugin",
+ "ecosystem:jquery",
+ "tooltip",
+ "modal",
+ "window",
+ "dialog",
+ "confirm",
+ "popup",
+ "notice",
+ "alert",
+ "ui",
+ "images",
+ "lightbox"
],
"homepage": "https://stephanwagner.me/jBox",
"repository": {
- "type" : "git",
- "url" : "https://github.com/StephanWagner/jBox.git"
+ "type": "git",
+ "url": "https://github.com/StephanWagner/jBox.git"
},
"bugs": {
"url": "https://github.com/StephanWagner/jBox/issues",
- "email" : "stephanwagner.me@gmail.com"
+ "email": "stephanwagner.me@gmail.com"
},
"author": "Stephan Wagner (https://stephanwagner.me)",
"license": "MIT",
+ "main": "dist/jBox.all.min.js",
+ "types": "src/js/jBox.d.ts",
"dependencies": {
- "jquery": ">=2.1"
+ "jquery": "^3.6.0"
+ },
+ "devDependencies": {
+ "gulp": "^5.0.0",
+ "gulp-clean-css": "^4.3.0",
+ "gulp-concat": "^2.6.1",
+ "gulp-rename": "^2.0.0",
+ "gulp-sass": "^5.1.0",
+ "gulp-sourcemaps": "^3.0.0",
+ "gulp-uglify": "^3.0.2",
+ "jest": "^27.0.4",
+ "sass": "^1.49.9"
+ },
+ "scripts": {
+ "watch": "gulp watch",
+ "build": "gulp build",
+ "test": "jest"
}
-}
\ No newline at end of file
+}
diff --git a/src/js/jBox.d.ts b/src/js/jBox.d.ts
new file mode 100755
index 0000000..afe6e88
--- /dev/null
+++ b/src/js/jBox.d.ts
@@ -0,0 +1,494 @@
+declare namespace jBox {
+ interface jBoxOptions {
+ /** Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...) */
+ id?: string;
+
+ /** The width of the content area */
+ width?: 'auto' | number;
+
+ /** The height of the content area */
+ height?: 'auto' | number;
+
+ /** Minimal width of content area */
+ minWidth?: number;
+
+ /** Minimal height of content area */
+ minHeight?: number;
+
+ /** Maximal width of content area */
+ maxWidth?: number;
+
+ /** Maximal height of content area */
+ maxHeight?: number;
+
+ /** Adjusts width to fit the viewport */
+ responsiveWidth?: boolean;
+
+ /** Adjusts height to fit the viewport */
+ responsiveHeight?: boolean;
+
+ /** Don't adjust width below this value (in pixel) */
+ responsiveMinWidth?: number;
+
+ /** Don't adjust height below this value (in pixel) */
+ responsiveMinHeight?: number;
+
+ /** A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip' */
+ attach?: JQuery;
+
+ /** Defines with which event the jBox opens or closes when interacting with the attached element */
+ trigger?: 'click' | 'mouseenter' | 'touchclick';
+
+ /** Prevent the default event when opening jBox, e.g. don't follow the href in a link */
+ preventDefault?: boolean;
+
+ /** Sets the content of your jBox. You can use jQuery elements to append elements (set CSS style display to none so the elements won't show up on your page) */
+ content?: string | JQuery;
+
+ /** Get the content from an attribute when jBox opens, e.g. 'data-content'. Use 'html' to get the attached elements HTML as content */
+ getContent?: string;
+
+ /** Adds a title to your jBox */
+ title?: string;
+
+ /** Get the title from an attribute when jBox opens, e.g. 'data-title' */
+ getTitle?: string;
+
+ /** Adds a footer to your jBox */
+ footer?: string;
+
+ /** Isolates scrolling to the content container */
+ isolateScroll?: boolean;
+
+ /** When you set an URL, jBox makes an AJAX request when it opens. You can add any jQuery ajax option, e.g. beforeSend, complete, success, etc. */
+ ajax?: jBoxAjaxOptions;
+
+ /** Cancels the ajax call when you close the jBox and it's not finished yet */
+ cancelAjaxOnClose?: boolean,
+
+ /** The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target */
+ target?: JQuery;
+
+ /** Set an object with the horizontal position x and the vertical position y, e.g. {x: 'right', y: 'center'}. You can also set numbers for an absolute position */
+ position?: { x: 'right' | 'left' | 'center' | number; y: 'top' | 'bottom' | 'center' | number };
+
+ /** Moves your jBox outside of the target element */
+ outside?: 'x' | 'y' | 'xy';
+
+ /** Offset to final position. You can set different values for x and y with an object, e.g. {x: 15, y: -10} */
+ offset?: number | { x: number; y: number };
+
+ /** Defines which CSS attributes should be used, e.g. {x: 'right', y: 'bottom'}. Note that right and bottom can only be used when your position values are integer, e.g. {x: 300, y: 20} */
+ attributes?: { x: 'right' | 'left' | 'center'; y: 'top' | 'bottom' | 'center' };
+
+ /** Your jBox will stay on position when scrolling */
+ fixed?: boolean;
+
+ /** Adjusts your jBoxes position if there is not enough space. The value 'flip' positions the jBox on the opposite outside position, the value 'move' works only with a pointer.
+ * Set to true to use both. This option overrides the reposition options */
+ adjustPosition?: 'flip' | 'move' | boolean;
+
+ /** By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling */
+ adjustTracker?: boolean;
+
+ /** The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5} */
+ adjustDistance?: number | { top?: number; right?: number; bottom?: number; left?: number };
+
+ /** Calculates new position when the window-size changes */
+ reposition?: boolean;
+
+ /** Calculates new position each time jBox opens (rather than only when it opens the first time) */
+ repositionOnOpen?: boolean;
+
+ /** Calculates new position when the content changes with .setContent() or .setTitle() */
+ repositionOnContent?: boolean;
+
+ /** Keeps current position if space permits. Applies only to 'Modal' type */
+ holdPosition?: boolean;
+
+ /** Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20' */
+ pointer?: boolean | 'left' | 'right' | 'top' | 'bottom' | 'center';
+
+ /** Setting something else than 'target' will add a pointer even if there is no target element set or found */
+ pointTo?: 'target' | 'left' | 'right' | 'top' | 'bottom';
+
+ /** Fade duration in ms, set 0 or false to disable */
+ fade?: number;
+
+ /** Animation when jBox opens or closes. To use different animations for opening and closing, use an object: {open: 'tada', close: 'flip'}.
+ * You can also set the direction of the move and slide animations: {open: 'move:right', close: 'slide:top'} */
+ animation?: jBoxAnimations | { open?: jBoxAnimations; close?: jBoxAnimations } | boolean;
+
+ /** Set a jBox theme class, e.g. 'TooltipDark' */
+ theme?: string;
+
+ /** Adds classes to the wrapper */
+ addClass?: string;
+
+ /** Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS) */
+ overlay?: boolean;
+
+ /** Add a class name to the overlay */
+ overlayClass?: null | string;
+
+ /** Use a high z-index, or set to 'auto' to move the jBox to the very top when it opens */
+ zIndex?: number | 'auto';
+
+ /** Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing */
+ delayOpen?: number;
+
+ /** Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away */
+ delayClose?: number;
+
+ /** Close jBox when pressing [esc] key */
+ closeOnEsc?: boolean;
+
+ /** Close jBox with a mouseclick: true closes when you click anywhere, 'overlay' when clicking on the overlay, 'box' when clicking on the jBox itself and 'body' when you click anywhere but the jBox */
+ closeOnClick?: boolean | 'body' | 'box' | 'overlay';
+
+ /** Close jBox when the mouse leaves the jBox area or the area of the attached element */
+ closeOnMouseleave?: boolean;
+
+ /** Adds a close button to your jBox. The value true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found */
+ closeButton?: boolean | 'overlay' | 'title' | 'box';
+
+ /** The element your jBox will be appended to. Any other element than $('body') is only useful for fixed positions or when position values are numbers */
+ appendTo?: JQuery;
+
+ /** Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time */
+ createOnInit?: boolean;
+
+ /** Blocks scrolling when jBox is open */
+ blockScroll?: boolean;
+
+ /** Adjust page elements to avoid content jumps when scrolling is blocked. See more here: https://github.com/StephanWagner/unscroll */
+ blockScrollAdjust?: boolean | string | Array>;
+
+ /** Makes your jBox draggable. Use title or provide the selector of any child element of jBox to use as the handle */
+ draggable?: boolean | 'title' | JQuery;
+
+ /** When you have multiple draggable jBoxes, the one you select will always move over the other ones */
+ dragOver?: boolean;
+
+ /** Time in ms when jBox will close automatically after it was opened */
+ autoClose?: number | boolean;
+
+ /** Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg'] */
+ preloadAudio?: boolean | string[];
+
+ /** The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'} */
+ audio?: string | { open?: string; close?: string };
+
+ /** The volume of the audio in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100} */
+ volume?: number | { open?: number; close?: number };
+
+ /** Fired when jBox is initialized. Note that you can use this in the event functions, it refers to your jBox object, e.g. onInit: function() { this.open(); } */
+ onInit?: () => void;
+
+ /** Fired when jBox attached itself to elements */
+ onAttach?: () => void;
+
+ /** Fired when jBox is positioned */
+ onPosition?: () => void;
+
+ /** Fired when jBox is created and is availible in DOM */
+ onCreated?: () => void;
+
+ /** Fired when jBox opens */
+ onOpen?: () => void;
+
+ /** Fired when jBox is completely open (when fading is finished) */
+ onOpenComplete?: () => void;
+
+ /** Fired when jBox closes */
+ onClose?: () => void;
+
+ /** Fired when jBox is completely closed (when fading finished) */
+ onCloseComplete?: () => void;
+
+ /** Fired when dragging starts */
+ onDragStart?: () => void;
+
+ /** Fired when dragging finished */
+ onDragEnd?: () => void;
+ }
+
+ /** Possible values for the 'animation' option */
+ type jBoxAnimations =
+ | 'zoomIn'
+ | 'zoomOut'
+ | 'pulse'
+ | 'move'
+ | 'slide'
+ | 'flip'
+ | 'tada'
+ | 'move:right'
+ | 'move:left'
+ | 'move:top'
+ | 'move:bottom'
+ | 'slide:right'
+ | 'slide:left'
+ | 'slide:top'
+ | 'slide:bottom';
+
+ /** Options for AJAX calls. */
+ interface jBoxAjaxOptions {
+ /** The URL to send the AJAX request to */
+ url?: string | null;
+
+ /** Data to send with your AJAX request, e.g. {id: 82, limit: 10} */
+ data?: string | {};
+
+ /** Resend the AJAX request when jBox opens. Use true to send the AJAX request call only once for every element or 'strict' to resend every time jBox opens */
+ reload?: boolean | 'strict';
+
+ /** The attribute in the source element where the AJAX request will look for the URL, e.g. 'data-url' */
+ getURL?: string;
+
+ /** The attribute in the source element where the AJAX request will look for the data, e.g. 'data-ajax' */
+ getData?: string;
+
+ /** Automatically set the response as new content when the AJAX request is finished */
+ setContent?: boolean;
+
+ /** Add a class to the wrapper when jBox is loading, set to class name or true to use the default class name 'jBox-loading' */
+ loadingClass?: boolean | string,
+
+ /** Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '
' */
+ spinner?: boolean | string;
+
+ /** Milliseconds to wait until spinner appears */
+ spinnerDelay?: number;
+
+ /** Repositions jBox when the spinner is added or removed */
+ spinnerReposition?: boolean;
+ }
+
+ /** Additional options for the Confirm plugin */
+ interface jBoxConfirmOptions extends jBoxOptions {
+ /** Text for the submit button */
+ confirmButton?: string;
+
+ /** Text for the cancel button */
+ cancelButton?: string;
+
+ /** Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found */
+ confirm?: () => void;
+
+ /** Function to execute when clicking the cancel button */
+ cancel?: () => void;
+
+ /** Close jBox when the user clicks the confirm button */
+ closeOnConfirm: boolean;
+ }
+
+ /** Additional options for the Image plugin */
+ interface jBoxImageOptions extends jBoxOptions {
+ /** The attribute to get the image source from, e.g. 'href' for a link: */
+ src?: string;
+
+ /** The attribute to set the galleries, e.g. 'data-jbox-gallery'. When changing this option, make sure you check the option attach, as jBox Image gets attached to [data-jbox-gallery] by default. */
+ gallery?: string;
+
+ /** The attribute where jBox gets the image label from, e.g. 'title' */
+ imageLabel?: string;
+
+ /** The fade duration for images in ms */
+ imageFade?: number;
+
+ /** How to display the images. Use CSS styles of background-position, e.g. 'cover', '50% auto' */
+ imageSize?: 'cover' | 'contain' | 'auto' | string;
+
+ /** Set to true to add an image counter, e.g. 4/20 */
+ imageCounter?: boolean;
+
+ /** HTML to separate the current image number from all image numbers, e.g. '/' or ' of ' */
+ imageCounterSeparator: string;
+
+ /** Adds a download button */
+ downloadButton?: boolean;
+
+ /** Text for the download button */
+ downloadButtonText?: string | null;
+
+ /** The attribute at the source element where to find the image to download, e.g. data-download="/path_to_image/image.jpg". If none provided, the currently active image will be downloaded */
+ downloadButtonUrl?: string | null;
+
+ /** The attribute to look for an mobile version of the image */
+ mobileImageAttr?: string | null;
+
+ /** The upper breakpoint to load the mobile image */
+ mobileImageBreakpoint?: number | null;
+
+ /** Preload the first image when page is loaded */
+ preloadFirstImage?: boolean;
+ }
+
+ /** Additional options for the Notice plugin */
+ interface jBoxNoticeOptions extends jBoxOptions {
+ /** Add a color to your notices */
+ color?: 'black' | 'red' | 'green' | 'blue' | 'yellow';
+
+ /** Set to false to disable notice-stacking */
+ stack?: boolean;
+
+ /** Spacing between notices when they stack */
+ stackSpacing?: number;
+
+ /** When hovering the notice it won't close */
+ delayOnHover?: boolean;
+
+ /** Adds a progress bar showing the time it will take until the notice closes */
+ showCountdown?: boolean;
+ }
+
+
+}
+
+/** Connects the name of the plugin with the type of its options */
+declare interface jBoxOptionsMap {
+ Tooltip: jBox.jBoxOptions;
+ Modal: jBox.jBoxOptions;
+ Mouse: jBox.jBoxOptions;
+ Confirm: jBox.jBoxConfirmOptions;
+ Notice: jBox.jBoxNoticeOptions;
+ Image: jBox.jBoxImageOptions;
+}
+
+interface IgnoreDelay {
+/** Whether to open or close immediately (true) or respect the original delay settings. */
+ignoreDelay?: boolean;
+}
+
+/** The core jBox class. Create instances using 'new' e.g. new jBox('Tooltip', { attach: '.tooltip'. }) */
+declare class jBox {
+ constructor(type: T, options: jBoxOptionsMap[T]);
+
+ /**
+ * Opens the jBox. You can set a new target with the option target, e.g. {target: $('#newTarget')}.
+ * If your jBox has an opening delay, you can force it to open immediately with the option ignoreDelay,
+ * e.g. {ignoreDelay: true}. To set new AJAX content when opening the jBox, you can pass an AJAX object,
+ * e.g. {ajax: {url: 'https://reqres.in/api/users'}}
+ */
+ open(options?: jBoxOptionsMap[T] & IgnoreDelay): void;
+
+ /**
+ * Closes the jBox. If your jBox has a closing delay, you can force it to close immediately with the option
+ * ignoreDelay, e.g. {ignoreDelay: true}
+ */
+ close(options?: jBoxOptionsMap[T] & IgnoreDelay): void;
+
+ /**
+ * Calls the method open when jBox is closed and close when it is open
+ */
+ toggle(options?: jBoxOptionsMap[T] & IgnoreDelay): void;
+
+ /** Sets the CSS width of the content container.
+ * Optional you can set a second argument to disable the automatic repositioning of jBox, e.g. .setWidth(200, true)
+ */
+ setWidth(value: number, disableAutoPosition?: boolean): void;
+
+ /** Sets the CSS height of the content container.
+ * Optional you can set a second argument to disable the automatic repositioning of jBox, e.g. .setWidth(200, true)
+ */
+ setHeight(value: number, disableAutoPosition?: boolean): void;
+
+ /**
+ * Attaches your jBox to elements. Providing a jQuery selector is optional.
+ * If you don't tell this method which elements to use, it will use the selector defined in the options.
+ * This method should be called when elements, which should open or close a jBox, are being created in runtime
+ */
+ attach(element: JQuery): void;
+
+ /**
+ * Removes the open and close function from elements.
+ */
+ detach(element: JQuery): void;
+ /**
+ * Sets the title of your jBox. If there is no title yet, it will be created.
+ * jBox will reposition if dimensions change, to disable, pass true as second argument:
+ * @example .setTitle('myTitle', true)
+ */
+ setTitle(title: string, disableAutoPosition?: boolean): void;
+
+ /**
+ * Sets the content of your jBox. You can use jQuery elements to append elements
+ * (set CSS style display to none so the elements won't show up on your page).
+ * jBox will reposition if dimensions change, to disable, pass true as second argument:
+ * @example .setContent('myContent', true)
+ */
+ setContent(content: string, disableAutoPosition?: boolean): void;
+
+ /**
+ * Reloads the AJAX request. You can pass the options url and data, e.g. {url: '/example.php', data: 'id=82'} or any jQuery ajax Option.
+ */
+ ajax(options: jBox.jBoxAjaxOptions): void;
+
+ /**
+ * Abort running ajax call
+ */
+ cancelAjax(): void;
+
+ /**
+ * Plays an audio file. Don't add the file extension, jBox will look for an .mp3 and an .ogg file.
+ */
+ audio(url: string, volume: number): void;
+
+ /**
+ * Recalculates your jBoxes position. You can set a new target with the option target, e.g. {target: $('#newTarget')}
+ */
+ position(options: jBoxOptionsMap[T]): void;
+
+ /**
+ * Animates for your jBox or any other element. The animation method is independent from the option animation.
+ * By default this method will animate the jBox wrapper, to animate another element set the option element, e.g. {element: $('#animateMe')}.
+ * To execute a function when the animation is finished use the option complete, e.g. {complete: function () { $('#animateMe').remove(); }}
+ */
+ animate(
+ animation:
+ | 'tada'
+ | 'tadaSmall'
+ | 'flash'
+ | 'shake'
+ | 'pulseUp'
+ | 'pulseDown'
+ | 'popIn'
+ | 'popOut'
+ | 'fadeIn'
+ | 'fadeOut'
+ | 'slideUp'
+ | 'slideRight'
+ | 'slideLeft'
+ | 'slideDown',
+ options?: { element?: JQuery; complete?: () => void }
+ ): void;
+
+ /**
+ * Disables your jBox, you won't be able to open or close it until enabled.
+ */
+ disable(): void;
+
+ /**
+ * Enables your jBox, so you can close and open it again.
+ */
+ enable(): void;
+
+ /**
+ * Disables and hides the jBox. This doesnt affect the overlay.
+ */
+ hide(): void;
+
+ /**
+ * Enables and shows your jBox again.
+ */
+ show(): void;
+
+ /**
+ * Destroys your jBox and removes it from DOM.
+ */
+ destroy(): void;
+}
+
+export = jBox;
+
+export as namespace jBox;
diff --git a/src/js/jBox.js b/src/js/jBox.js
new file mode 100755
index 0000000..6624b7a
--- /dev/null
+++ b/src/js/jBox.js
@@ -0,0 +1,2308 @@
+/**
+ * jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jQuery 3.5.0 (https://code.jquery.com/jquery-3.5.0.min.js)
+ *
+ * Documentation: https://stephanwagner.me/jBox/documentation
+ *
+ * Demos: https://stephanwagner.me/jBox/demos
+ */
+
+function jBoxWrapper(jQuery) {
+
+
+ var jBox = function jBox(type, options) {
+
+
+ // Options (https://stephanwagner.me/jBox/options)
+
+ this.options = {
+
+ // jBox ID
+ id: null, // Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...)
+
+ // Dimensions
+ width: 'auto', // The width of the content area, e.g. 'auto', 200, '80%'
+ height: 'auto', // The height of the content area
+ minWidth: null, // Minimal width
+ minHeight: null, // Minimal height
+ maxWidth: null, // Maximal width
+ maxHeight: null, // Maximal height
+
+ // Responsive dimensions
+ responsiveWidth: true, // Adjusts the width to fit the viewport
+ responsiveHeight: true, // Adjusts the height to fit the viewport
+ responsiveMinWidth: 100, // Don't adjust width below this value (in pixel)
+ responsiveMinHeight: 100, // Don't adjust height below this value (in pixel)
+
+ // Attach
+ attach: null, // A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip'
+ trigger: 'click', // The event to open or close your jBox, use 'click', 'touchclick' or 'mouseenter'
+ preventDefault: false, // Prevent the default event when opening jBox, e.g. don't follow the href in a link
+
+ // Content
+ content: null, // You can use HTML or a jQuery element, e.g. jQuery('#jBox-content'). The elements will be appended to the content element and then made visible, so hide them with style="display: none" beforehand
+ getContent: null, // Get the content from an attribute when jBox opens, e.g. getContent: 'data-content'. Use 'html' to get the attached elements HTML as content
+ title: null, // Adds a title to your jBox
+ getTitle: null, // Get the title from an attribute when jBox opens, e.g. getTitle: 'data-title'
+ footer: null, // Adds a footer to your jBox
+ isolateScroll: true, // Isolates scrolling to the content container
+
+ // AJAX
+ ajax: { // Setting an URL will make an AJAX request when jBox opens. Optional you can add any jQuery AJAX option (http://api.jquery.com/jquery.ajax/)
+ url: null, // The URL to send the AJAX request to
+ data: '', // Data to send with your AJAX request, e.g. {id: 82, limit: 10}
+ reload: false, // Resend the AJAX request when jBox opens. Use true to send the AJAX request only once for every attached element or 'strict' to resend every time jBox opens
+ getURL: 'data-url', // The attribute in the source element where the AJAX request will look for the URL, e.g. data-url="https://reqres.in/api/users"
+ getData: 'data-ajax', // The attribute in the source element where the AJAX request will look for the data, e.g. data-ajax="id=82&limit=10"
+ setContent: true, // Automatically set the response as new content when the AJAX request is finished
+ loadingClass: true, // Add a class to the wrapper when jBox is loading, set to class name or true to use the default class name 'jBox-loading'
+ spinner: true, // Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '
'
+ spinnerDelay: 300, // Milliseconds to wait until spinner appears
+ spinnerReposition: true // Repositions jBox when the spinner is added or removed
+ },
+ cancelAjaxOnClose: true, // Cancels the ajax call when jBox closes and it hasn't finished loading yet
+
+ // Position
+ target: null, // The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target
+ position: {
+ x: 'center', // Horizontal position, use a number, 'left', 'right' or 'center'
+ y: 'center' // Vertical position, use a number, 'top', 'bottom' or 'center'
+ },
+ outside: null, // Use 'x', 'y', or 'xy' to move your jBox outside of the target element
+ offset: 0, // Offset to final position, you can set different values for x and y with an object, e.g. {x: 20, y: 10}
+ attributes: { // Note that attributes can only be 'left' or 'right' when using numbers for position, e.g. {x: 300, y: 20}
+ x: 'left', // Horizontal position, use 'left' or 'right'
+ y: 'top' // Vertical position, use 'top' or 'bottom'
+ },
+ fixed: false, // Your jBox will stay on position when scrolling
+ adjustPosition: true, // Adjusts your jBoxes position if there is not enough space, use 'flip', 'move' or true for both. This option overrides the reposition options
+ adjustTracker: false, // By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling
+ adjustDistance: 5, // The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5}
+ reposition: true, // Calculates new position when the window-size changes
+ repositionOnOpen: true, // Calculates new position each time jBox opens (rather than only when it opens the first time)
+ repositionOnContent: true, // Calculates new position when the content changes with .setContent() or .setTitle()
+ holdPosition: true, // Keeps current position if space permits. Applies only to 'Modal' type.
+
+ // Pointer
+ pointer: false, // Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20'
+ pointTo: 'target', // Setting something else than 'target' will add a pointer even if there is no target element set or found. Use 'top', 'right', 'bottom' or 'left'
+
+ // Animations
+ fade: 180, // Fade duration in ms, set to 0 or false to disable
+ animation: null, // Animation when opening or closing, use 'pulse', 'zoomIn', 'zoomOut', 'move', 'slide', 'flip', 'tada' (CSS inspired from Daniel Edens Animate.css: http://daneden.me/animate)
+
+ // Appearance
+ theme: 'Default', // Set a jBox theme class
+ addClass: null, // Adds classes to the wrapper
+ overlay: false, // Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS)
+ overlayClass: null, // Add a class name to the overlay
+ zIndex: 10000, // Use a high z-index, or set to 'auto' to bring to front on open
+
+ // Delays
+ delayOpen: 0, // Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing
+ delayClose: 0, // Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away
+
+ // Closing
+ closeOnEsc: false, // Close jBox when pressing [esc] key
+ closeOnClick: false, // Close jBox with mouseclick. Use true (click anywhere), 'box' (click on jBox itself), 'overlay' (click on the overlay), 'body' (click anywhere but jBox)
+ closeOnMouseleave: false, // Close jBox when the mouse leaves the jBox area or the area of the attached element
+ closeButton: false, // Adds a close button to your jBox. Use 'title', 'box', 'overlay' or true (true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found)
+
+ // Other options
+ appendTo: jQuery('body'), // The element your jBox will be appended to. Any other element than jQuery('body') is only useful for fixed positions or when position values are numbers
+ createOnInit: false, // Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time
+ blockScroll: false, // Blocks scrolling when jBox is open
+ blockScrollAdjust: true, // Adjust page elements to avoid content jumps when scrolling is blocked. See more here: https://github.com/StephanWagner/unscroll
+ draggable: false, // Make your jBox draggable (use 'true', 'title' or provide an element as handle) (inspired from Chris Coyiers CSS-Tricks http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/)
+ dragOver: true, // When you have multiple draggable jBoxes, the one you select will always move over the other ones
+ autoClose: false, // Time in ms when jBox will close automatically after it was opened
+ delayOnHover: false, // Delay auto-closing while mouse is hovered
+ showCountdown: false, // Display a nice progress-indicator when autoClose is enabled
+
+ // Audio // You can use the integrated audio function whenever you'd like to play an audio file, e.g. onInit: function () { this.audio('url_to_audio_file_without_file_extension', 75); }
+ preloadAudio: true, // Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg']
+ audio: null, // The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'}
+ volume: 100, // The volume in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100}
+
+ // Events // Note that you can use 'this' in all event functions, it refers to your jBox object (e.g. onInit: function () { this.open(); })
+ onInit: null, // Fired when jBox is initialized
+ onAttach: null, // Fired when jBox attached itself to elements, the attached element will be passed as a parameter, e.g. onAttach: function (element) { element.css({color: 'red'}); }
+ onPosition: null, // Fired when jBox is positioned
+ onCreated: null, // Fired when jBox is created and availible in DOM
+ onOpen: null, // Fired when jBox opens
+ onOpenComplete: null, // Fired when jBox is completely open (when fading is finished)
+ onClose: null, // Fired when jBox closes
+ onCloseComplete: null, // Fired when jBox is completely closed (when fading is finished)
+ onDragStart: null, // Fired when dragging starts
+ onDragEnd: null // Fired when dragging finished
+ };
+
+
+ // Default plugin options
+
+ this._pluginOptions = {
+
+ // Default options for tooltips
+ 'Tooltip': {
+ getContent: 'title',
+ trigger: 'mouseenter',
+ position: {
+ x: 'center',
+ y: 'top'
+ },
+ outside: 'y',
+ pointer: true
+ },
+
+ // Default options for mouse tooltips
+ 'Mouse': {
+ responsiveWidth: false,
+ responsiveHeight: false,
+ adjustPosition: 'flip',
+ target: 'mouse',
+ trigger: 'mouseenter',
+ position: {
+ x: 'right',
+ y: 'bottom'
+ },
+ outside: 'xy',
+ offset: 5
+ },
+
+ // Default options for modal windows
+ 'Modal': {
+ target: jQuery(window),
+ fixed: true,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: 'overlay',
+ closeButton: true,
+ overlay: true,
+ animation: 'zoomIn'
+ },
+ };
+
+
+ // Merge options
+
+ this.options = jQuery.extend(true, this.options, this._pluginOptions[type] ? this._pluginOptions[type] : jBox._pluginOptions[type], options);
+
+
+ // Set the jBox type
+
+ jQuery.type(type) == 'string' && (this.type = type);
+
+
+ // Checks if the user is on a touch device, borrowed from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
+
+ this.isTouchDevice = (function () {
+ var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
+ var mq = function (query) {
+ return window.matchMedia(query).matches;
+ }
+
+ if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
+ return true;
+ }
+
+ var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
+ return mq(query);
+ })();
+
+
+ // Add close event for body click when we are on touch device and jBox triggers on mouseenter
+
+ if (this.isTouchDevice && this.options.trigger === 'mouseenter' && this.options.closeOnClick === false) {
+ this.options.closeOnClick = 'body';
+ }
+
+
+ // Local function to fire events
+
+ this._fireEvent = function (event, pass)
+ {
+ this.options['_' + event] && (this.options['_' + event].bind(this))(pass);
+ this.options[event] && (this.options[event].bind(this))(pass);
+ };
+
+
+ // Get a unique jBox ID
+
+ this.options.id === null && (this.options.id = 'jBox' + jBox._getUniqueID());
+ this.id = this.options.id;
+
+
+ // Correct impossible options
+
+ ((this.options.position.x == 'center' && this.options.outside == 'x') || (this.options.position.y == 'center' && this.options.outside == 'y')) && (this.options.outside = null);
+ this.options.pointTo == 'target' && (!this.options.outside || this.options.outside == 'xy') && (this.options.pointer = false);
+
+
+ // Correct multiple choice options
+
+ jQuery.type(this.options.offset) != 'object' ? (this.options.offset = {x: this.options.offset, y: this.options.offset}) : (this.options.offset = jQuery.extend({x: 0, y: 0}, this.options.offset));
+ jQuery.type(this.options.adjustDistance) != 'object' ? (this.options.adjustDistance = {top: this.options.adjustDistance, right: this.options.adjustDistance, bottom: this.options.adjustDistance, left: this.options.adjustDistance}) : (this.options.adjustDistance = jQuery.extend({top: 5, left: 5, right: 5, bottom: 5}, this.options.adjustDistance));
+
+
+ // Save default outside position
+
+ this.outside = this.options.outside && this.options.outside != 'xy' ? this.options.position[this.options.outside] : false;
+
+
+ // Save where the jBox is aligned to
+
+ this.align = this.outside ? this.outside : (this.options.position.y != 'center' && jQuery.type(this.options.position.y) != 'number' ? this.options.position.x : (this.options.position.x != 'center' && jQuery.type(this.options.position.x) != 'number' ? this.options.position.y : this.options.attributes.x));
+
+
+ // Adjust option zIndex
+
+ jBox.zIndexMax = Math.max(jBox.zIndexMax || 0, this.options.zIndex === 'auto' ? 10000 : this.options.zIndex);
+ if (this.options.zIndex === 'auto') {
+ this.adjustZIndexOnOpen = true;
+ jBox.zIndexMax += 2;
+ this.options.zIndex = jBox.zIndexMax;
+ this.trueModal = this.options.overlay;
+ }
+
+ // Internal positioning functions
+
+ this._getOpp = function (opp) { return {left: 'right', right: 'left', top: 'bottom', bottom: 'top', x: 'y', y: 'x'}[opp]; };
+ this._getXY = function (xy) { return {left: 'x', right: 'x', top: 'y', bottom: 'y', center: 'x'}[xy]; };
+ this._getTL = function (tl) { return {left: 'left', right: 'left', top: 'top', bottom: 'top', center: 'left', x: 'left', y: 'top'}[tl]; };
+
+
+ // Get a dimension value in integer pixel dependent on appended element
+
+ this._getInt = function (value, dimension) {
+ if (value == 'auto') return 'auto';
+ if (value && jQuery.type(value) == 'string' && value.slice(-1) == '%') {
+ return jQuery(window)[dimension == 'height' ? 'innerHeight' : 'innerWidth']() * parseInt(value.replace('%', '')) / 100;
+ }
+ return value;
+ };
+
+
+ // Create an svg element
+
+ this._createSVG = function (type, options)
+ {
+ var svg = document.createElementNS('http://www.w3.org/2000/svg', type);
+ jQuery.each(options, function (index, item) {
+ svg.setAttribute(item[0], (item[1] || ''));
+ });
+ return svg;
+ };
+
+
+ // Isolate scrolling in a container
+
+ this._isolateScroll = function (el)
+ {
+ // Abort if element not found
+ if (!el || !el.length) return;
+
+ el.on('DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll', function (ev) {
+ var delta = ev.wheelDelta || (ev.originalEvent && ev.originalEvent.wheelDelta) || -ev.detail;
+ var overflowBottom = this.scrollTop + el.outerHeight() - this.scrollHeight >= 0;
+ var overflowTop = this.scrollTop <= 0;
+ ((delta < 0 && overflowBottom) || (delta > 0 && overflowTop)) && ev.preventDefault();
+ });
+ };
+
+
+ // Set the title width to content width
+
+ this._setTitleWidth = function ()
+ {
+ // Abort if there is no title or width of content is auto
+ if (!this.titleContainer || (this.content[0].style.width == 'auto' && !this.content[0].style.maxWidth)) return null;
+
+ // Expose wrapper to get actual width
+ if (this.wrapper.css('display') == 'none') {
+ this.wrapper.css('display', 'block');
+ var contentWidth = this.content.outerWidth();
+ this.wrapper.css('display', 'none');
+ } else {
+ var contentWidth = this.content.outerWidth();
+ }
+
+ // Set max-width only
+ this.titleContainer.css({maxWidth: (Math.max(contentWidth, parseInt(this.content[0].style.maxWidth)) || null)});
+ }
+
+
+ // Make jBox draggable
+
+ this._draggable = function ()
+ {
+ // Abort if jBox is not draggable
+ if (!this.options.draggable) return false;
+
+ // Get the handle where jBox will be dragged with
+ var handle = this.options.draggable == 'title' ? this.titleContainer : (this.options.draggable instanceof jQuery ? this.options.draggable : (jQuery.type(this.options.draggable) == 'string' ? jQuery(this.options.draggable) : this.wrapper));
+
+ // Abort if no handle or if draggable was set already
+ if (!handle || !(handle instanceof jQuery) || !handle.length || handle.data('jBox-draggable')) {
+ return false;
+ }
+
+ // Add mouse events
+ handle.addClass('jBox-draggable').data('jBox-draggable', true).on('touchstart mousedown', function (ev)
+ {
+ if (ev.button == 2 || jQuery(ev.target).hasClass('jBox-noDrag') || jQuery(ev.target).parents('.jBox-noDrag').length) {
+ // Hacky fix for jBox not closing on mobile devices when using draggable
+ if (ev.type == 'touchstart' && (jQuery(ev.target).hasClass('jBox-closeButton') || jQuery(ev.target).parents('.jBox-closeButton').length)) {
+ this.close({ignoreDelay: true});
+ }
+ return;
+ }
+
+ var pageX;
+ var pageY;
+
+ if (ev.type == 'touchstart' && ev.touches && ev.touches[0]) {
+ pageX = ev.touches[0].pageX;
+ pageY = ev.touches[0].pageY;
+ } else {
+ pageX = ev.pageX;
+ pageY = ev.pageY;
+ }
+
+ // Store current mouse position
+ this.draggingStartX = pageX;
+ this.draggingStartY = pageY;
+
+ // Adjust z-index when dragging jBox over another draggable jBox
+ if (this.options.dragOver && !this.trueModal && parseInt(this.wrapper.css('zIndex'), 10) <= jBox.zIndexMaxDragover) {
+ jBox.zIndexMaxDragover += 1;
+ this.wrapper.css('zIndex', jBox.zIndexMaxDragover);
+ }
+
+ var drg_h = this.wrapper.outerHeight();
+ var drg_w = this.wrapper.outerWidth();
+ var pos_y = this.wrapper.offset().top + drg_h - pageY;
+ var pos_x = this.wrapper.offset().left + drg_w - pageX;
+
+ jQuery(document).on('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id, function (ev) {
+
+ var movingPageX;
+ var movingPageY;
+
+ if (ev.type == 'touchmove' && ev.touches && ev.touches[0]) {
+ movingPageX = ev.touches[0].pageX;
+ movingPageY = ev.touches[0].pageY;
+ } else {
+ movingPageX = ev.pageX;
+ movingPageY = ev.pageY;
+ }
+
+ // Fire onDragStart event when jBox moves
+ if (!this.dragging && this.draggingStartX != movingPageX && this.draggingStartY != movingPageY) {
+ this._fireEvent('onDragStart');
+ this.dragging = true;
+ }
+
+ // Adjust position
+ this.wrapper.offset({
+ top: movingPageY + pos_y - drg_h,
+ left: movingPageX + pos_x - drg_w
+ });
+ }.bind(this));
+ ev.preventDefault();
+
+ }.bind(this)).on('touchend mouseup', function () {
+ // Remove drag event
+ jQuery(document).off('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id);
+
+ // Fire onDragEnd event
+ this.dragging && this._fireEvent('onDragEnd');
+
+ // Reset dragging reference
+ this.dragging = false;
+
+ if ((this.type == 'Modal' || this.type == 'Confirm') && this.options.holdPosition) {
+ // Drag end captures new position
+ var jBoxOffset = jQuery('#' + this.id).offset(),
+ pos = {
+ x: jBoxOffset.left - jQuery(document).scrollLeft(),
+ y: jBoxOffset.top - jQuery(document).scrollTop()
+ };
+ this.position({position: pos, offset: {x: 0, y: 0}});
+ }
+ }.bind(this));
+
+ // Get highest z-index
+ if (!this.trueModal) {
+ jBox.zIndexMaxDragover = !jBox.zIndexMaxDragover ? this.options.zIndex : Math.max(jBox.zIndexMaxDragover, this.options.zIndex);
+ }
+
+ return this;
+ };
+
+ // Create jBox
+
+ this._create = function ()
+ {
+ // Abort if jBox was created already
+ if (this.wrapper) return;
+
+ // Create wrapper
+ this.wrapper = jQuery('
', {
+ id: this.id,
+ 'class': 'jBox-wrapper' + (this.type ? ' jBox-' + this.type : '') + (this.options.theme ? ' jBox-' + this.options.theme : '') + (this.options.addClass ? ' ' + this.options.addClass : '')
+ }).css({
+ position: (this.options.fixed ? 'fixed' : 'absolute'),
+ display: 'none',
+ opacity: 0,
+ zIndex: this.options.zIndex
+
+ // Save the jBox instance in the wrapper, so you can get access to your jBox when you only have the element
+ }).data('jBox', this);
+
+ // Add mouseleave event, only close jBox when the new target is not the source element
+ this.options.closeOnMouseleave && this.wrapper.on('mouseleave', function (ev) {
+ !this.source || !(ev.relatedTarget == this.source[0] || jQuery.inArray(this.source[0], jQuery(ev.relatedTarget).parents('*')) !== -1) && this.close();
+ }.bind(this));
+
+ // Add closeOnClick: 'box' events
+ (this.options.closeOnClick == 'box') && this.wrapper.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
+
+ // Create container
+ this.container = jQuery('
').appendTo(this.wrapper);
+
+ // Create content
+ this.content = jQuery('
').appendTo(this.container);
+
+ // Create footer
+ this.options.footer && (this.footer = jQuery('').append(this.options.footer).appendTo(this.container));
+
+ // Isolate scrolling
+ this.options.isolateScroll && this._isolateScroll(this.content);
+
+ // Create close button
+ if (this.options.closeButton) {
+ var closeButtonSVG = this._createSVG('svg', [['viewBox', '0 0 24 24']]);
+ closeButtonSVG.appendChild(this._createSVG('path', [['d', 'M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z']]));
+ this.closeButton = jQuery('
').on('click tap', function (ev) { this.close({ignoreDelay: true}); }.bind(this)).append(closeButtonSVG);
+
+ // Add close button to jBox container
+ if (this.options.closeButton == 'box' || (this.options.closeButton === true && !this.options.overlay && !this.options.title && !this.options.getTitle)) {
+ this.wrapper.addClass('jBox-closeButton-box');
+ this.closeButton.appendTo(this.container);
+ }
+ }
+
+ // Append jBox to DOM
+ this.wrapper.appendTo(this.options.appendTo);
+
+ // Fix adjustDistance if there is a close button in the box
+ this.wrapper.find('.jBox-closeButton').length && jQuery.each(['top', 'right', 'bottom', 'left'], function (index, pos) {
+ this.wrapper.find('.jBox-closeButton').css(pos) && this.wrapper.find('.jBox-closeButton').css(pos) != 'auto' && (this.options.adjustDistance[pos] = Math.max(this.options.adjustDistance[pos], this.options.adjustDistance[pos] + (((parseInt(this.wrapper.find('.jBox-closeButton').css(pos)) || 0) + (parseInt(this.container.css('border-' + pos + '-width')) || 0)) * -1)));
+ }.bind(this));
+
+ // Create pointer
+ if (this.options.pointer) {
+
+ // Get pointer vars and save globally
+ this.pointer = {
+ position: (this.options.pointTo != 'target') ? this.options.pointTo : this._getOpp(this.outside),
+ xy: (this.options.pointTo != 'target') ? this._getXY(this.options.pointTo) : this._getXY(this.outside),
+ align: 'center',
+ offset: 0
+ };
+
+ this.pointer.element = jQuery('
').appendTo(this.wrapper);
+ this.pointer.dimensions = {
+ x: this.pointer.element.outerWidth(),
+ y: this.pointer.element.outerHeight()
+ };
+
+ if (jQuery.type(this.options.pointer) == 'string') {
+ var split = this.options.pointer.split(':');
+ split[0] && (this.pointer.align = split[0]);
+ split[1] && (this.pointer.offset = parseInt(split[1]));
+ }
+ this.pointer.alignAttribute = (this.pointer.xy == 'x' ? (this.pointer.align == 'bottom' ? 'bottom' : 'top') : (this.pointer.align == 'right' ? 'right' : 'left'));
+
+ // Set wrapper CSS
+ this.wrapper.css('padding-' + this.pointer.position, this.pointer.dimensions[this.pointer.xy]);
+
+ // Set pointer CSS
+ this.pointer.element.css(this.pointer.alignAttribute, (this.pointer.align == 'center' ? '50%' : 0)).css('margin-' + this.pointer.alignAttribute, this.pointer.offset);
+ this.pointer.margin = {};
+ this.pointer.margin['margin-' + this.pointer.alignAttribute] = this.pointer.offset;
+
+ // Add a transform to fix centered position
+ (this.pointer.align == 'center') && this.pointer.element.css('transform', 'translate(' + (this.pointer.xy == 'y' ? (this.pointer.dimensions.x * -0.5 + 'px') : 0) + ', ' + (this.pointer.xy == 'x' ? (this.pointer.dimensions.y * -0.5 + 'px') : 0) + ')');
+
+ this.pointer.element.css((this.pointer.xy == 'x' ? 'width' : 'height'), parseInt(this.pointer.dimensions[this.pointer.xy]) + parseInt(this.container.css('border-' + this.pointer.alignAttribute + '-width')));
+
+ // Add class to wrapper for CSS access
+ this.wrapper.addClass('jBox-pointerPosition-' + this.pointer.position);
+ }
+
+ // Set title and content
+ this.setContent(this.options.content, true);
+ this.setTitle(this.options.title, true);
+
+ this.options.draggable && this._draggable();
+
+ // Fire onCreated event
+ this._fireEvent('onCreated');
+ };
+
+
+ // Create jBox onInit
+
+ this.options.createOnInit && this._create();
+
+
+ // Attach jBox
+
+ this.options.attach && this.attach();
+
+
+ // Attach document and window events
+
+ this._attachEvents = function ()
+ {
+ // Cancel countdown on mouseenter if delayOnHover
+ this.options.delayOnHover && jQuery('#' + this.id).on('mouseenter', function (ev) { this.isHovered = true; }.bind(this));
+
+ // Resume countdown on mouseleave if delayOnHover
+ this.options.delayOnHover && jQuery('#' + this.id).on('mouseleave', function (ev) { this.isHovered = false; }.bind(this));
+
+ // Positioning events
+ if ((this.options.adjustPosition || this.options.reposition) && !this.fixed && this.outside) {
+
+ // Trigger position events when scrolling
+ this.options.adjustTracker && jQuery(window).on('scroll.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
+
+ // Trigger position events when resizing
+ (this.options.adjustPosition || this.options.reposition) && jQuery(window).on('resize.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
+ }
+
+ // Mousemove events
+ this.options.target == 'mouse' && jQuery('body').on('mousemove.jBox-' + this.id, function (ev) { this.position({mouseTarget: {top: ev.pageY, left: ev.pageX}}); }.bind(this));
+ };
+
+
+ // Detach document and window events
+
+ this._detachEvents = function ()
+ {
+ // Closing event: closeOnEsc
+ this.options.closeOnEsc && jQuery(document).off('keyup.jBox-' + this.id);
+
+ // Closing event: closeOnClick
+ (this.options.closeOnClick === true || this.options.closeOnClick == 'body') && jQuery(document).off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+
+ // Positioning events
+ this.options.adjustTracker && jQuery(window).off('scroll.jBox-' + this.id);
+ (this.options.adjustPosition || this.options.reposition) && jQuery(window).off('resize.jBox-' + this.id);
+
+ // Mousemove events
+ this.options.target == 'mouse' && jQuery('body').off('mousemove.jBox-' + this.id);
+ };
+
+
+ // Show overlay
+
+ this._showOverlay = function ()
+ {
+ // Create the overlay if wasn't created already
+ if (!this.overlay) {
+
+ // Create element and append to the element where jBox is appended to
+ this.overlay = jQuery('
').addClass('jBox-overlay' + (this.type ? ' jBox-overlay-' + this.type : '')).css({
+ display: 'none',
+ opacity: 0,
+ zIndex: this.options.zIndex - 1
+ }).appendTo(this.options.appendTo);
+
+ // Add a class name to the overlay
+ this.options.overlayClass && this.overlay.addClass(this.options.overlayClass);
+
+ // Add close button to overlay
+ (this.options.closeButton == 'overlay' || this.options.closeButton === true) && this.overlay.append(this.closeButton);
+
+ // Add closeOnClick: 'overlay' events
+ this.options.closeOnClick == 'overlay' && this.overlay.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
+
+ // Adjust option adjustDistance if there is a close button in the overlay
+ jQuery('#' + this.id + '-overlay .jBox-closeButton').length && (this.options.adjustDistance.top = Math.max(jQuery('#' + this.id + '-overlay .jBox-closeButton').outerHeight(), this.options.adjustDistance.top));
+ }
+
+ // Adjust zIndex
+ if (this.adjustZIndexOnOpen === true) {
+ this.overlay.css('zIndex', parseInt(this.wrapper.css('zIndex'), 10) - 1);
+ }
+
+ // Abort if overlay is already visible
+ if (this.overlay.css('display') == 'block') return;
+
+ // Show overlay
+ this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 1}, {
+ queue: false,
+ duration: this.options.fade,
+ start: function () { this.overlay.css({display: 'block'}); }.bind(this)
+ })) : this.overlay.css({display: 'block', opacity: 1});
+ };
+
+
+ // Hide overlay
+
+ this._hideOverlay = function ()
+ {
+ // Abort if the overlay wasn't created yet
+ if (!this.overlay) return;
+
+ // Hide overlay if no other jBox needs it
+ this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 0}, {
+ queue: false,
+ duration: this.options.fade,
+ complete: function () { this.overlay.css({display: 'none'}); }.bind(this)
+ })) : this.overlay.css({display: 'none', opacity: 0});
+ };
+
+
+ // Get the correct jBox dimensions by moving jBox out of viewport
+
+ this._exposeDimensions = function ()
+ {
+ // Move wrapper out of viewport
+ this.wrapper.css({
+ top: -10000,
+ left: -10000,
+ right: 'auto',
+ bottom: 'auto'
+ });
+
+ // Get jBox dimensions
+ var jBoxDimensions = {
+ x: this.wrapper.outerWidth(),
+ y: this.wrapper.outerHeight()
+ };
+
+ // Reset position to viewport
+ this.wrapper.css({
+ top: 'auto',
+ left: 'auto'
+ });
+
+ return jBoxDimensions;
+ };
+
+
+ // Generate CSS for animations and append to header
+
+ this._generateAnimationCSS = function ()
+ {
+ // Get open and close animations if none provided
+ (jQuery.type(this.options.animation) != 'object') && (this.options.animation = {
+ pulse: {open: 'pulse', close: 'zoomOut'},
+ zoomIn: {open: 'zoomIn', close: 'zoomIn'},
+ zoomOut: {open: 'zoomOut', close: 'zoomOut'},
+ move: {open: 'move', close: 'move'},
+ slide: {open: 'slide', close: 'slide'},
+ flip: {open: 'flip', close: 'flip'},
+ tada: {open: 'tada', close: 'zoomOut'}
+ }[this.options.animation]);
+
+ // Abort if animation not found
+ if (!this.options.animation) return null;
+
+ // Get direction var
+ this.options.animation.open && (this.options.animation.open = this.options.animation.open.split(':'));
+ this.options.animation.close && (this.options.animation.close = this.options.animation.close.split(':'));
+ this.options.animation.openDirection = this.options.animation.open[1] ? this.options.animation.open[1] : null;
+ this.options.animation.closeDirection = this.options.animation.close[1] ? this.options.animation.close[1] : null;
+ this.options.animation.open && (this.options.animation.open = this.options.animation.open[0]);
+ this.options.animation.close && (this.options.animation.close = this.options.animation.close[0]);
+
+ // Add 'Open' and 'Close' to animation names
+ this.options.animation.open && (this.options.animation.open += 'Open');
+ this.options.animation.close && (this.options.animation.close += 'Close');
+
+ // All animations
+ var animations = {
+ pulse: {
+ duration: 350,
+ css: [['0%', 'scale(1)'], ['50%', 'scale(1.1)'], ['100%', 'scale(1)']]
+ },
+ zoomInOpen: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(0.9)'], ['100%', 'scale(1)']]
+ },
+ zoomInClose: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1)'], ['100%', 'scale(0.9)']]
+ },
+ zoomOutOpen: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1.1)'], ['100%', 'scale(1)']]
+ },
+ zoomOutClose: {
+ duration: (this.options.fade || 180),
+ css: [['0%', 'scale(1)'], ['100%', 'scale(1.1)']]
+ },
+ moveOpen: {
+ duration: (this.options.fade || 180),
+ positions: {top: {'0%': -12}, right: {'0%': 12}, bottom: {'0%': 12}, left: {'0%': -12}},
+ css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
+ },
+ moveClose: {
+ duration: (this.options.fade || 180),
+ timing: 'ease-in',
+ positions: {top: {'100%': -12}, right: {'100%': 12}, bottom: {'100%': 12}, left: {'100%': -12}},
+ css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
+ },
+ slideOpen: {
+ duration: 400,
+ positions: {top: {'0%': -400}, right: {'0%': 400}, bottom: {'0%': 400}, left: {'0%': -400}},
+ css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
+ },
+ slideClose: {
+ duration: 400,
+ timing: 'ease-in',
+ positions: {top: {'100%': -400}, right: {'100%': 400}, bottom: {'100%': 400}, left: {'100%': -400}},
+ css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
+ },
+ flipOpen: {
+ duration: 600,
+ css: [['0%', 'perspective(400px) rotateX(90deg)'], ['40%', 'perspective(400px) rotateX(-15deg)'], ['70%', 'perspective(400px) rotateX(15deg)'], ['100%', 'perspective(400px) rotateX(0deg)']]
+ },
+ flipClose: {
+ duration: (this.options.fade || 300),
+ css: [['0%', 'perspective(400px) rotateX(0deg)'], ['100%', 'perspective(400px) rotateX(90deg)']]
+ },
+ tada: {
+ duration: 800,
+ css: [['0%', 'scale(1)'], ['10%, 20%', 'scale(0.9) rotate(-3deg)'], ['30%, 50%, 70%, 90%', 'scale(1.1) rotate(3deg)'], ['40%, 60%, 80%', 'scale(1.1) rotate(-3deg)'], ['100%', 'scale(1) rotate(0)']]
+ }
+ };
+
+ // Set Open and Close names for standalone animations
+ jQuery.each(['pulse', 'tada'], function (index, item) { animations[item + 'Open'] = animations[item + 'Close'] = animations[item]; });
+
+ // Function to generate the CSS for the keyframes
+ var generateKeyframeCSS = function (ev, position)
+ {
+ // Generate keyframes CSS
+ var keyframe_css = '@keyframes jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
+ jQuery.each(animations[this.options.animation[ev]].css, function (index, item) {
+ var translate = position ? item[1].replace('%XY', this._getXY(position).toUpperCase()) : item[1];
+ animations[this.options.animation[ev]].positions && (translate = translate.replace('%V', animations[this.options.animation[ev]].positions[position][item[0]]));
+ keyframe_css += item[0] + ' {transform:' + translate + ';}';
+
+ }.bind(this));
+ keyframe_css += '}';
+
+ // Generate class CSS
+ keyframe_css += '.jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
+ keyframe_css += 'animation-duration: ' + animations[this.options.animation[ev]].duration + 'ms;';
+ keyframe_css += 'animation-name: jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ';';
+ keyframe_css += animations[this.options.animation[ev]].timing ? ('animation-timing-function: ' + animations[this.options.animation[ev]].timing + ';') : '';
+ keyframe_css += '}';
+
+ return keyframe_css;
+ }.bind(this);
+
+ // Generate css for each event and positions
+ this._animationCSS = '';
+ jQuery.each(['open', 'close'], function (index, ev)
+ {
+ // No CSS needed for closing with no fade
+ if (!this.options.animation[ev] || !animations[this.options.animation[ev]] || (ev == 'close' && !this.options.fade)) return '';
+
+ // Generate CSS
+ animations[this.options.animation[ev]].positions ?
+ jQuery.each(['top', 'right', 'bottom', 'left'], function (index2, position) { this._animationCSS += generateKeyframeCSS(ev, position); }.bind(this)) :
+ this._animationCSS += generateKeyframeCSS(ev);
+ }.bind(this));
+
+ };
+
+
+ // Add css for animations
+
+ this.options.animation && this._generateAnimationCSS();
+
+
+ // Block body clicks for 10ms to prevent extra event triggering
+
+ this._blockBodyClick = function ()
+ {
+ this.blockBodyClick = true;
+ setTimeout(function () { this.blockBodyClick = false; }.bind(this), 10);
+ };
+
+
+ // Animations
+
+ this._animate = function (ev)
+ {
+ // The event which triggers the animation
+ !ev && (ev = this.isOpen ? 'open' : 'close');
+
+ // Don't animate when closing with no fade duration
+ if (!this.options.fade && ev == 'close') return null;
+
+ // Get the current position, use opposite if jBox is flipped
+ var animationDirection = (this.options.animation[ev + 'Direction'] || ((this.align != 'center') ? this.align : this.options.attributes.x));
+ this.flipped && this._getXY(animationDirection) == (this._getXY(this.align)) && (animationDirection = this._getOpp(animationDirection));
+
+ // Add event and position classes
+ var classnames = 'jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + ' jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + '-' + animationDirection;
+ this.wrapper.addClass(classnames);
+
+ // Get duration of animation
+ var animationDuration = parseFloat(this.wrapper.css('animation-duration')) * 1000;
+ ev == 'close' && (animationDuration = Math.min(animationDuration, this.options.fade));
+
+ // Remove animation classes when animation is finished
+ setTimeout(function () {
+ this.wrapper && this.wrapper.removeClass(classnames);
+ }.bind(this), animationDuration);
+ };
+
+
+ // Abort an animation
+
+ this._abortAnimation = function ()
+ {
+ // Remove all animation classes
+ var classes = this.wrapper.attr('class').split(' ').filter(function (c) {
+ return c.lastIndexOf('jBox-' + this.id + '-animation', 0) !== 0;
+ }.bind(this));
+ this.wrapper.attr('class', classes.join(' '));
+ };
+
+
+ // Adjust dimensions when browser is resized
+
+ if (this.options.responsiveWidth || this.options.responsiveHeight)
+ {
+ // Responsive positioning overrides options adjustPosition and reposition
+ // TODO: Only add this resize event when the other one from adjustPosition and reposition was not set
+ jQuery(window).on('resize.responsivejBox-' + this.id, function (ev) { if (this.isOpen) { this.position(); } }.bind(this));
+ }
+
+
+ // Fix audio options
+
+ jQuery.type(this.options.preloadAudio) === 'string' && (this.options.preloadAudio = [this.options.preloadAudio]);
+ jQuery.type(this.options.audio) === 'string' && (this.options.audio = {open: this.options.audio});
+ jQuery.type(this.options.volume) === 'number' && (this.options.volume = {open: this.options.volume, close: this.options.volume});
+
+ if (this.options.preloadAudio === true && this.options.audio) {
+ this.options.preloadAudio = [];
+ jQuery.each(this.options.audio, function (index, url) {
+ this.options.preloadAudio.push(url + '.mp3');
+ this.options.preloadAudio.push(url + '.ogg');
+ }.bind(this));
+ }
+
+
+ // Preload audio files
+
+ this.options.preloadAudio.length && jQuery.each(this.options.preloadAudio, function (index, url) {
+ var audio = new Audio();
+ audio.src = url;
+ audio.preload = 'auto';
+ });
+
+
+ // Fire onInit event
+
+ this._fireEvent('onInit');
+
+
+ return this;
+ };
+
+
+ // Attach jBox to elements
+
+ jBox.prototype.attach = function (elements, trigger)
+ {
+ // Get elements from options if none passed
+ !elements && (elements = this.options.attach);
+
+ // Convert selectors to jQuery objects
+ jQuery.type(elements) == 'string' && (elements = jQuery(elements));
+
+ // Get trigger event from options if not passed
+ !trigger && (trigger = this.options.trigger);
+
+ // Loop through elements and attach jBox
+ elements && elements.length && jQuery.each(elements, function (index, el) {
+ el = jQuery(el);
+
+ // Only attach if the element wasn't attached to this jBox already
+ if (!el.data('jBox-attached-' + this.id)) {
+
+ // Remove title attribute and store content on element
+ (this.options.getContent == 'title' && el.attr('title') != undefined) && el.data('jBox-getContent', el.attr('title')).removeAttr('title');
+
+ // Add Element to collection
+ this.attachedElements || (this.attachedElements = []);
+ this.attachedElements.push(el[0]);
+
+ // Add click or mouseenter event, click events can prevent default as well
+ el.on(trigger + '.jBox-attach-' + this.id, function (ev)
+ {
+ // Clear timer
+ this.timer && clearTimeout(this.timer);
+
+ // Block opening when jbox is open and the source element is triggering
+ if (trigger == 'mouseenter' && this.isOpen && this.source[0] == el[0]) return;
+
+ // Only close jBox if you click the current target element, otherwise open at new target
+ if (this.isOpen && this.source && this.source[0] != el[0]) var forceOpen = true;
+
+ // Set new source element
+ this.source = el;
+
+ // Set new target
+ !this.options.target && (this.target = el);
+
+ // Prevent default action on click
+ trigger == 'click' && this.options.preventDefault && ev.preventDefault();
+
+ // Toggle or open jBox
+ this[trigger == 'click' && !forceOpen ? 'toggle' : 'open']();
+
+ }.bind(this));
+
+ // Add close event for trigger event mouseenter
+ (this.options.trigger == 'mouseenter') && el.on('mouseleave', function (ev)
+ {
+ // Abort if jBox wasn't created yet
+ if (!this.wrapper) return null;
+
+ // If we have set closeOnMouseleave, do not close jBox when leaving attached element and mouse is over jBox
+ if (!this.options.closeOnMouseleave || !(ev.relatedTarget == this.wrapper[0] || jQuery(ev.relatedTarget).parents('#' + this.id).length)) this.close();
+ }.bind(this));
+
+ // Store
+ el.data('jBox-attached-' + this.id, trigger);
+
+ // Fire onAttach event
+ this._fireEvent('onAttach', el);
+ }
+
+ }.bind(this));
+
+ return this;
+ };
+
+
+ // Detach jBox from elements
+
+ jBox.prototype.detach = function (elements)
+ {
+ // Get elements from stores elements if none passed
+ !elements && (elements = this.attachedElements || []);
+
+ elements && elements.length && jQuery.each(elements, function (index, el) {
+ el = jQuery(el);
+
+ // Remove events
+ if (el.data('jBox-attached-' + this.id)) {
+ el.off(el.data('jBox-attached-' + this.id) + '.jBox-attach-' + this.id);
+ el.data('jBox-attached-' + this.id, null);
+ }
+ // Remove element from collection
+ this.attachedElements = jQuery.grep(this.attachedElements, function (value) {
+ return value != el[0];
+ });
+ }.bind(this));
+
+ return this;
+ };
+
+
+ // Set title
+
+ jBox.prototype.setTitle = function (title, ignore_positioning)
+ {
+ // Abort if title to set
+ if (title == null || title == undefined) return this;
+
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Get the width and height of wrapper, only if they change we need to reposition
+ var wrapperHeight = this.wrapper.outerHeight();
+ var wrapperWidth = this.wrapper.outerWidth();
+
+ // Create title elements if they weren't created already
+ if (!this.title) {
+ this.titleContainer = jQuery('
');
+ this.title = jQuery('
').appendTo(this.titleContainer);
+ if (this.options.closeButton == 'title' || (this.options.closeButton === true && !this.options.overlay)) {
+ this.wrapper.addClass('jBox-closeButton-title');
+ this.closeButton.appendTo(this.titleContainer);
+ }
+ this.titleContainer.insertBefore(this.content);
+ this._setTitleWidth();
+ }
+
+ // Add or remove wrapper class
+ this.wrapper[title ? 'addClass' : 'removeClass']('jBox-hasTitle');
+
+ // Set title html
+ this.title.html(title);
+
+ // Adjust width of title
+ wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
+
+ // Make jBox draggable
+ this.options.draggable && this._draggable();
+
+ // Reposition if dimensions changed
+ !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
+
+ return this;
+ };
+
+
+ // Set content
+
+ jBox.prototype.setContent = function (content, ignore_positioning)
+ {
+ // Abort if no content to set
+ if (content == null || content == undefined) return this;
+
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Get the width and height of wrapper, only if they change we need to reposition
+ var wrapperHeight = this.wrapper.outerHeight();
+ var wrapperWidth = this.wrapper.outerWidth();
+
+ // Move all appended containers to body
+ this.content.children('[data-jbox-content-appended]').appendTo('body').css({display: 'none'});
+
+ // Set the new content
+ switch (jQuery.type(content)) {
+ case 'string':
+ this.content.html(content);
+ break;
+ case 'object':
+ if (content && (content instanceof jQuery || content.constructor.prototype.jquery)) {
+ this.content.html('');
+ content.attr('data-jbox-content-appended', 1).appendTo(this.content).css({display: 'block'});
+ } else {
+ this.content.html(JSON.stringify(content));
+ }
+ break;
+ }
+
+ // Adjust title width
+ wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
+
+ // Make jBox draggable
+ this.options.draggable && this._draggable();
+
+ // Reposition if dimensions changed
+ !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
+
+ return this;
+ };
+
+
+ // Set jBox dimensions
+
+ jBox.prototype.setDimensions = function (type, value, pos)
+ {
+ // Create jBox if it wasn't created already
+ !this.wrapper && this._create();
+
+ // Default value is 'auto'
+ value == undefined && (value = 'auto');
+
+ // Set CSS of content and title
+ this.content.css(type, this._getInt(value));
+
+ // Adjust title width
+ type == 'width' && this._setTitleWidth();
+
+ // Update options
+ this.options[type] = value;
+
+ // Reposition by default
+ (pos == undefined || pos) && this.position();
+ };
+
+
+ // Set jBox width or height
+
+ jBox.prototype.setWidth = function (value, pos) { this.setDimensions('width', value, pos); };
+ jBox.prototype.setHeight = function (value, pos) { this.setDimensions('height', value, pos); };
+
+
+ // Position jBox
+
+ jBox.prototype.position = function (options)
+ {
+ // Options are required
+ !options && (options = {});
+
+ // Combine passed options with jBox options
+ options = jQuery.extend(true, this.options, options);
+
+ // Get the target
+ this.target = options.target || this.target || jQuery(window);
+
+ // Make sure target is a jQuery element
+ !(this.target instanceof jQuery || this.target == 'mouse') && (this.target = jQuery(this.target));
+
+ // Abort if target is missing
+ if (!this.target.length) return this;
+
+ // Reset content css to get original dimensions
+ this.content.css({
+ width: this._getInt(options.width, 'width'),
+ height: this._getInt(options.height, 'height'),
+ minWidth: this._getInt(options.minWidth, 'width'),
+ minHeight: this._getInt(options.minHeight, 'height'),
+ maxWidth: this._getInt(options.maxWidth, 'width'),
+ maxHeight: this._getInt(options.maxHeight, 'height'),
+ });
+
+ // Reset width of title
+ this._setTitleWidth();
+
+ // Get jBox dimensions
+ var jBoxDimensions = this._exposeDimensions();
+
+ // Check if target has fixed position, store in elements data
+ this.target != 'mouse' && !this.target.data('jBox-' + this.id + '-fixed') && this.target.data('jBox-' + this.id + '-fixed', (this.target[0] != jQuery(window)[0] && (this.target.css('position') == 'fixed' || this.target.parents().filter(function () { return jQuery(this).css('position') == 'fixed'; }).length > 0)) ? 'fixed' : 'static');
+
+ // Get the window dimensions
+ var windowDimensions = {
+ x: jQuery(window).outerWidth(),
+ y: jQuery(window).outerHeight(),
+ top: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollTop()),
+ left: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollLeft())
+ };
+ windowDimensions.bottom = windowDimensions.top + windowDimensions.y;
+ windowDimensions.right = windowDimensions.left + windowDimensions.x;
+
+ // Get target offset
+ try { var targetOffset = this.target.offset(); } catch (e) { var targetOffset = {top: 0, left: 0}; };
+
+ // When the target is fixed and jBox is fixed, remove scroll offset
+ if (this.target != 'mouse' && this.target.data('jBox-' + this.id + '-fixed') == 'fixed' && options.fixed) {
+ targetOffset.top = targetOffset.top - jQuery(window).scrollTop();
+ targetOffset.left = targetOffset.left - jQuery(window).scrollLeft();
+ }
+
+ // Get target dimensions
+ var targetDimensions = {
+ x: this.target == 'mouse' ? 12 : this.target.outerWidth(),
+ y: this.target == 'mouse' ? 20 : this.target.outerHeight(),
+ top: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.top : (targetOffset ? targetOffset.top : 0),
+ left: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.left : (targetOffset ? targetOffset.left : 0)
+ };
+
+ // Check if jBox is outside
+ var outside = options.outside && !(options.position.x == 'center' && options.position.y == 'center');
+
+ // Get the available space on all sides
+ var availableSpace = {
+ x: windowDimensions.x - options.adjustDistance.left - options.adjustDistance.right, // TODO: substract position.x when they are numbers
+ y: windowDimensions.y - options.adjustDistance.top - options.adjustDistance.bottom, // TODO: substract position.x when they are numbers
+ left: !outside ? 0 : (targetDimensions.left - jQuery(window).scrollLeft() - options.adjustDistance.left),
+ right: !outside ? 0 : (windowDimensions.x - targetDimensions.left + jQuery(window).scrollLeft() - targetDimensions.x - options.adjustDistance.right),
+ top: !outside ? 0 : (targetDimensions.top - jQuery(window).scrollTop() - this.options.adjustDistance.top),
+ bottom: !outside ? 0 : (windowDimensions.y - targetDimensions.top + jQuery(window).scrollTop() - targetDimensions.y - options.adjustDistance.bottom),
+ };
+
+ // Get the default outside position, check if box will be flipped
+ var jBoxOutsidePosition = {
+ x: (options.outside == 'x' || options.outside == 'xy') && jQuery.type(options.position.x) != 'number' ? options.position.x : null,
+ y: (options.outside == 'y' || options.outside == 'xy') && jQuery.type(options.position.y) != 'number' ? options.position.y : null
+ };
+ var flip = {x: false, y: false};
+ (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
+ (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
+
+ // Adjust responsive dimensions
+ if (options.responsiveWidth || options.responsiveHeight) {
+
+ // Adjust width and height according to default outside position
+ var adjustResponsiveWidth = function ()
+ {
+ if (options.responsiveWidth && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x || 'x']) {
+ var contentWidth = availableSpace[jBoxOutsidePosition.x || 'x'] - (this.pointer && outside && options.outside == 'x' ? this.pointer.dimensions.x : 0) - parseInt(this.container.css('border-left-width')) - parseInt(this.container.css('border-right-width'));
+ this.content.css({
+ width: contentWidth > this.options.responsiveMinWidth ? contentWidth : null,
+ minWidth: contentWidth < parseInt(this.content.css('minWidth')) ? 0 : null
+ });
+ this._setTitleWidth();
+ }
+ jBoxDimensions = this._exposeDimensions();
+
+ }.bind(this);
+ options.responsiveWidth && adjustResponsiveWidth();
+
+ // After adjusting width, check if jBox will be flipped for y
+ options.responsiveWidth && !flip.y && (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
+
+ // Adjust width and height according to default outside position
+ var adjustResponsiveHeight = function ()
+ {
+ if (options.responsiveHeight && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y || 'y']) {
+
+ // Expose wrapper to get correct title height
+ var exposeTitleFooterHeight = function () {
+ if (!this.titleContainer && !this.footer) return 0;
+ if (this.wrapper.css('display') == 'none') {
+ this.wrapper.css('display', 'block');
+ var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
+ this.wrapper.css('display', 'none');
+ } else {
+ var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
+ }
+ return height || 0;
+ }.bind(this);
+
+ var contentHeight = availableSpace[jBoxOutsidePosition.y || 'y'] - (this.pointer && outside && options.outside == 'y' ? this.pointer.dimensions.y : 0) - exposeTitleFooterHeight() - parseInt(this.container.css('border-top-width')) - parseInt(this.container.css('border-bottom-width'));
+ this.content.css({height: contentHeight > this.options.responsiveMinHeight ? contentHeight : null});
+ this._setTitleWidth();
+ }
+ jBoxDimensions = this._exposeDimensions();
+
+ }.bind(this);
+ options.responsiveHeight && adjustResponsiveHeight();
+
+ // After adjusting height, check if jBox will be flipped for x
+ options.responsiveHeight && !flip.x && (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
+
+ // Adjust width and height if jBox will be flipped
+ if (options.adjustPosition && options.adjustPosition != 'move') {
+ flip.x && adjustResponsiveWidth();
+ flip.y && adjustResponsiveHeight();
+ }
+ }
+
+ // Store new positioning vars in local var
+ var pos = {};
+
+ // Calculate positions
+ var setPosition = function (p)
+ {
+ // Set number positions
+ if (jQuery.type(options.position[p]) == 'number') {
+ pos[options.attributes[p]] = options.position[p];
+ return;
+ }
+
+ // We have a target, so use 'left' or 'top' as attributes
+ var a = options.attributes[p] = (p == 'x' ? 'left' : 'top');
+
+ // Start at target position
+ pos[a] = targetDimensions[a];
+
+ // Set centered position
+ if (options.position[p] == 'center') {
+ pos[a] += Math.ceil((targetDimensions[p] - jBoxDimensions[p]) / 2);
+
+ // If the target is the window, adjust centered position depending on adjustDistance
+ (this.target != 'mouse' && this.target[0] && this.target[0] == jQuery(window)[0]) && (pos[a] += (options.adjustDistance[a] - options.adjustDistance[this._getOpp(a)]) * 0.5);
+ return;
+ }
+
+ // Move inside
+ (a != options.position[p]) && (pos[a] += targetDimensions[p] - jBoxDimensions[p]);
+
+ // Move outside
+ (options.outside == p || options.outside == 'xy') && (pos[a] += jBoxDimensions[p] * (a != options.position[p] ? 1 : -1));
+
+ }.bind(this);
+
+ // Set position including offset
+ setPosition('x');
+ setPosition('y');
+
+ // Adjust position depending on pointer align
+ if (this.pointer && options.pointTo == 'target' && jQuery.type(options.position.x) != 'number' && jQuery.type(options.position.y) != 'number') {
+
+ var adjustWrapper = 0;
+
+ // Where is the pointer aligned? Add or substract accordingly
+ switch (this.pointer.align) {
+ case 'center':
+ if (options.position[this._getOpp(options.outside)] != 'center') {
+ adjustWrapper += (jBoxDimensions[this._getOpp(options.outside)] / 2);
+ }
+ break;
+ default:
+ switch (options.position[this._getOpp(options.outside)]) {
+ case 'center':
+ adjustWrapper += ((jBoxDimensions[this._getOpp(options.outside)] / 2) - (this.pointer.dimensions[this._getOpp(options.outside)] / 2)) * (this.pointer.align == this._getTL(this.pointer.align) ? 1 : -1);
+ break;
+ default:
+ adjustWrapper += (this.pointer.align != options.position[this._getOpp(options.outside)]) ?
+
+ // If pointer align is different to position align
+ (jBoxDimensions[this._getOpp(options.outside)] * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1)) + ((this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? -1 : 1)) :
+
+ // If pointer align is same as position align
+ (this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1);
+ break;
+ }
+ break;
+ }
+
+ adjustWrapper *= (options.position[this._getOpp(options.outside)] == this.pointer.alignAttribute ? -1 : 1);
+ adjustWrapper += this.pointer.offset * (this.pointer.align == this._getOpp(this._getTL(this.pointer.align)) ? 1 : -1);
+
+ pos[this._getTL(this._getOpp(this.pointer.xy))] += adjustWrapper;
+ }
+
+ // Add final offset
+ pos[options.attributes.x] += options.offset.x;
+ pos[options.attributes.y] += options.offset.y;
+
+ // Set CSS
+ this.wrapper.css(pos);
+
+ // Adjust position
+ if (options.adjustPosition) {
+
+ // Reset cached pointer position
+ if (this.positionAdjusted) {
+ this.pointer && this.wrapper.css('padding', 0).css('padding-' + this._getOpp(this.outside), this.pointer.dimensions[this._getXY(this.outside)]).removeClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).addClass('jBox-pointerPosition-' + this.pointer.position);
+ this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + this._getOpp(this.outside)).css(this.pointer.margin);
+ this.positionAdjusted = false;
+ this.flipped = false;
+ }
+
+ // Find out where the jBox is out of view area
+ var outYT = (windowDimensions.top > pos.top - (options.adjustDistance.top || 0)),
+ outXR = (windowDimensions.right < pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0)),
+ outYB = (windowDimensions.bottom < pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0)),
+ outXL = (windowDimensions.left > pos.left - (options.adjustDistance.left || 0)),
+ outX = outXL ? 'left' : (outXR ? 'right' : null),
+ outY = outYT ? 'top' : (outYB ? 'bottom' : null),
+ out = outX || outY;
+
+ // Only continue if jBox is out of view area
+ if (out) {
+
+ if ((this.type == 'Modal' || this.type == 'Confirm')
+ && jQuery.type(this.options.position.x) == 'number'
+ && jQuery.type(this.options.position.y) == 'number'
+ ) {
+ var diffX = 0, diffY = 0;
+ if (this.options.holdPosition) {
+
+ // Adjust left or right
+ if (outXL) {
+ diffX = windowDimensions.left - (pos.left - (options.adjustDistance.left || 0));
+ } else if (outXR) {
+ diffX = windowDimensions.right - (pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0));
+ }
+
+ // Adjust top or bottom
+ if (outYT) {
+ diffY = windowDimensions.top - (pos.top - (options.adjustDistance.top || 0));
+ } else if (outYB) {
+ diffY = windowDimensions.bottom - (pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0));
+ }
+
+ this.options.position.x = Math.max(windowDimensions.top, this.options.position.x + diffX);
+ this.options.position.y = Math.max(windowDimensions.left, this.options.position.y + diffY);
+
+ setPosition('x');
+ setPosition('y');
+ this.wrapper.css(pos);
+ }
+ // Fire onPosition event
+ this._fireEvent('onPosition');
+
+ return this;
+ }
+
+ // Function to flip position
+ if (options.adjustPosition === true || options.adjustPosition === 'flip') {
+ var flipJBox = function (xy) {
+ this.wrapper.css(this._getTL(xy), pos[this._getTL(xy)] + ((jBoxDimensions[this._getXY(xy)] + (options.offset[this._getXY(xy)] * (xy == 'top' || xy == 'left' ? -2 : 2)) + targetDimensions[this._getXY(xy)]) * (xy == 'top' || xy == 'left' ? 1 : -1)));
+ this.pointer && this.wrapper.removeClass('jBox-pointerPosition-' + this.pointer.position).addClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).css('padding', 0).css('padding-' + xy, this.pointer.dimensions[this._getXY(xy)]);
+ this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + xy);
+ this.positionAdjusted = true;
+ this.flipped = true;
+ }.bind(this);
+
+ // Flip jBox
+ flip.x && flipJBox(this.options.position.x);
+ flip.y && flipJBox(this.options.position.y);
+ }
+
+ // Move jBox (only possible with pointer)
+ var outMove = (this._getXY(this.outside) == 'x') ? outY : outX;
+
+ if (this.pointer && options.pointTo == 'target' && options.adjustPosition != 'flip' && this._getXY(outMove) == this._getOpp(this._getXY(this.outside))) {
+
+ // Get the maximum space we have availible to adjust
+ if (this.pointer.align == 'center') {
+ var spaceAvail = (jBoxDimensions[this._getXY(outMove)] / 2) - (this.pointer.dimensions[this._getOpp(this.pointer.xy)] / 2) - (parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) * (outMove != this._getTL(outMove) ? -1 : 1));
+ } else {
+ var spaceAvail = (outMove == this.pointer.alignAttribute) ?
+ parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) :
+ jBoxDimensions[this._getXY(outMove)] - parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - this.pointer.dimensions[this._getXY(outMove)];
+ }
+
+ // Get the overlapping space
+ var spaceDiff = (outMove == this._getTL(outMove)) ?
+ windowDimensions[this._getTL(outMove)] - pos[this._getTL(outMove)] + options.adjustDistance[outMove] :
+ (windowDimensions[this._getOpp(this._getTL(outMove))] - pos[this._getTL(outMove)] - options.adjustDistance[outMove] - jBoxDimensions[this._getXY(outMove)]) * -1;
+
+ // Add overlapping space on left or top window edge
+ if (outMove == this._getOpp(this._getTL(outMove)) && pos[this._getTL(outMove)] - spaceDiff < windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)]) {
+ spaceDiff -= windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)] - (pos[this._getTL(outMove)] - spaceDiff);
+ }
+
+ // Only adjust the maximum availible
+ spaceDiff = Math.min(spaceDiff, spaceAvail);
+
+ // Move jBox
+ if (spaceDiff <= spaceAvail && spaceDiff > 0) {
+ this.pointer.element.css('margin-' + this.pointer.alignAttribute, parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - (spaceDiff * (outMove != this.pointer.alignAttribute ? -1 : 1)));
+ this.wrapper.css(this._getTL(outMove), pos[this._getTL(outMove)] + (spaceDiff * (outMove != this._getTL(outMove) ? -1 : 1)));
+ this.positionAdjusted = true;
+ }
+ }
+ }
+ }
+
+ // Fire onPosition event
+ this._fireEvent('onPosition');
+
+ return this;
+ };
+
+
+ // Block scrolling
+ // Borrowed from https://github.com/StephanWagner/unscroll
+
+ jBox.prototype.unscroll = function (elements) {
+
+ // Store reusable vars
+ this.set = function (id, value) {
+ if (!window.unscrollStore) {
+ window.unscrollStore = {};
+ }
+ window.unscrollStore[id] = value;
+ };
+
+ // Get reusable vars
+ this.get = function (id) {
+ return window.unscrollStore ? window.unscrollStore[id] : null;
+ };
+
+ // Get the width of the scroll bar in pixel
+ this.getScrollbarWidth = function () {
+ if (this.get('scrollbarWidth')) {
+ return this.get('scrollbarWidth') + 'px';
+ }
+ var scrollElement = document.createElement('div');
+ scrollElement.style.width = '100px';
+ scrollElement.style.height = '100px';
+ scrollElement.style.overflow = 'scroll';
+ scrollElement.style.position = 'absolute';
+ scrollElement.style.top = '-10000';
+
+ document.body.appendChild(scrollElement);
+ var scrollbarWidth = scrollElement.offsetWidth - scrollElement.clientWidth;
+ document.body.removeChild(scrollElement);
+
+ this.set('scrollbarWidth', scrollbarWidth);
+ return scrollbarWidth + 'px';
+ }
+
+ // Add unscroll class to head
+ function addUnscrollClassName() {
+ if (document.getElementById('unscroll-class-name')) {
+ return;
+ }
+ var css = '.unscrollable { overflow: hidden !important; }',
+ head = document.head || document.getElementsByTagName('head')[0],
+ style = document.createElement('style');
+ style.type = 'text/css';
+ style.setAttribute('id', 'unscroll-class-name');
+ style.appendChild(document.createTextNode(css));
+ head.appendChild(style);
+ }
+
+ // Get the elements to adjust, force body element
+ this.getElementsToAdjust = function (elements) {
+ !elements && (elements = []);
+
+ if (typeof elements === 'string') {
+ elements = [
+ [elements, 'padding-right']
+ ];
+ }
+
+ elements.forEach(function (element, index) {
+ if (typeof element === 'string') {
+ elements[index] = [element, 'padding-right'];
+ }
+ });
+
+ var bodyFound = false;
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i][0].indexOf('body') !== -1) {
+ bodyFound = true;
+ }
+ };
+
+ if (bodyFound === false) {
+ elements.push(['body', 'padding-right']);
+ }
+
+ return elements;
+ }
+
+ this.pageHasScrollbar = function () {
+ return this.getScrollbarWidth() && document.body.offsetHeight > window.innerHeight;
+ }
+
+ // Clean up elements
+ if (this.pageHasScrollbar()) {
+ elements = this.getElementsToAdjust(elements);
+
+ // Loop through elements and adjust accordingly
+ for (var i = 0; i < elements.length; i++) {
+ var elementsDOM = document.querySelectorAll(elements[i][0]);
+ for (var j = 0; j < elementsDOM.length; j++) {
+ if (elementsDOM[j].getAttribute('data-unscroll')) {
+ return;
+ }
+ var attribute = elements[i][1];
+ var computedStyles = window.getComputedStyle(elementsDOM[j]);
+ var computedStyle = computedStyles.getPropertyValue(attribute);
+ elementsDOM[j].setAttribute('data-unscroll', attribute);
+ if (!computedStyle) {
+ computedStyle = '0px';
+ }
+ var operator = attribute == 'padding-right' || attribute == 'right' ? '+' : '-';
+ elementsDOM[j].style[attribute] = 'calc(' + computedStyle + ' ' + operator + ' ' + this.getScrollbarWidth() + ')';
+ }
+ }
+ }
+
+ // Make the page unscrollable
+ addUnscrollClassName();
+ document.body.classList.add('unscrollable');
+ }
+
+ jBox.prototype.unscroll.reset = function () {
+ var elements = document.querySelectorAll('[data-unscroll]');
+
+ for (var i = 0; i < elements.length; i++) {
+ var attribute = elements[i].getAttribute('data-unscroll');
+ elements[i].style[attribute] = null;
+ elements[i].removeAttribute('data-unscroll');
+ }
+ document.body.classList.remove('unscrollable');
+ }
+
+
+ // Open jBox
+
+ jBox.prototype.open = function (options)
+ {
+ // Create blank options if none passed
+ !options && (options = {});
+
+ // Abort if jBox was destroyed
+ if (this.isDestroyed) return this;
+
+ // Construct jBox if not already constructed
+ !this.wrapper && this._create();
+
+ // Add css to header if not added already
+ !this._styles && (this._styles = jQuery('
').append(this._animationCSS).appendTo(jQuery('head')));
+
+ // Abort any opening or closing timer
+ this.timer && clearTimeout(this.timer);
+
+ // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body'
+ this._blockBodyClick();
+
+ // Block opening
+ if (this.isDisabled) return this;
+
+ // Closing event: closeOnEsc
+ this.options.closeOnEsc && jQuery(document).on('keyup.jBox-' + this.id, function (ev) { if (ev.keyCode == 27) { this.close({ignoreDelay: true}); }}.bind(this));
+
+ // Closing event: closeOnClick
+ if (this.options.closeOnClick === true || this.options.closeOnClick === 'body') {
+ jQuery('body').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function (ev) {
+ if (this.blockBodyClick || (this.options.closeOnClick == 'body' && (ev.target == this.wrapper[0] || this.wrapper.has(ev.target).length))) return;
+ this.close({ignoreDelay: true});
+ }.bind(this));
+
+ // Fix for iOS event bubbling issue
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+ this.isTouchDevice && jQuery('body > *').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function () {
+ return true;
+ });
+ }
+
+ // Opening function
+ var open = function () {
+
+ // Adjust zIndex
+ if (this.adjustZIndexOnOpen === true) {
+ jBox.zIndexMax = Math.max(
+ parseInt(this.wrapper.css('zIndex'), 10),
+ this.options.zIndex,
+ jBox.zIndexMax || 0,
+ jBox.zIndexMaxDragover || 0
+ ) + 2;
+ this.wrapper.css('zIndex', jBox.zIndexMax);
+ this.options.zIndex = jBox.zIndexMax;
+ }
+
+ // Set title from source element
+ this.source && this.options.getTitle && (this.source.attr(this.options.getTitle) && this.setTitle(this.source.attr(this.options.getTitle), true));
+
+ // Set content from source element
+ this.source && this.options.getContent && (this.source.data('jBox-getContent') ? this.setContent(this.source.data('jBox-getContent'), true) : (this.source.attr(this.options.getContent) ? this.setContent(this.source.attr(this.options.getContent), true) : (this.options.getContent == 'html' ? this.setContent(this.source.html(), true) : null)));
+
+ // Fire onOpen event
+ this._fireEvent('onOpen');
+
+ // Get content from ajax
+ if ((this.options.ajax && (this.options.ajax.url || (this.source && this.source.attr(this.options.ajax.getURL))) && (!this.ajaxLoaded || this.options.ajax.reload)) || (options.ajax && (options.ajax.url || options.ajax.data))) {
+ // Send the content from stored data if there is any, otherwise load new data
+ (this.options.ajax.reload != 'strict' && this.source && this.source.data('jBox-ajax-data') && !(options.ajax && (options.ajax.url || options.ajax.data))) ? this.setContent(this.source.data('jBox-ajax-data')) : this.ajax((options.ajax || null), true);
+ }
+
+ // Set position
+ (!this.positionedOnOpen || this.options.repositionOnOpen) && this.position(options) && (this.positionedOnOpen = true);
+
+ // Abort closing
+ this.isClosing && this._abortAnimation();
+
+ // Open functions to call when jBox is closed
+ if (!this.isOpen) {
+
+ // jBox is open now
+ this.isOpen = true;
+
+ // Automatically close jBox after some time
+ this.options.autoClose && (this.options.delayClose = this.options.autoClose) && this.close();
+
+ // Attach events
+ this._attachEvents();
+
+ // Block scrolling
+ if (this.options.blockScroll) {
+ if (this.options.blockScrollAdjust) {
+ if (jBox.blockScrollScopes) {
+ jBox.blockScrollScopes++;
+ } else {
+ jBox.blockScrollScopes = 1;
+ this.unscroll(Array.isArray(this.options.blockScrollAdjust) || typeof this.options.blockScrollAdjust === 'string' ? this.options.blockScrollAdjust : null);
+ }
+ } else {
+ jQuery('body').addClass('jBox-blockScroll-' + this.id);
+ }
+ }
+
+ // Show overlay
+ if (this.options.overlay) {
+ this._showOverlay();
+
+ // TODO Optimize: We have to position here again, because if the overlay has a close button, the upper adjustDistance will be wrong
+ this.position();
+ }
+
+ // Only animate if jBox is completely closed
+ this.options.animation && !this.isClosing && this._animate('open');
+
+ // Play audio file
+ this.options.audio && this.options.audio.open && this.audio(this.options.audio.open, this.options.volume.open);
+
+ // Fading animation or show immediately
+ if (this.options.fade) {
+ this.wrapper.stop().animate({opacity: 1}, {
+ queue: false,
+ duration: this.options.fade,
+ start: function () {
+ this.isOpening = true;
+ this.wrapper.css({display: 'block'});
+ }.bind(this),
+ complete: function () {
+ this._fireEvent('onOpenComplete');
+ }.bind(this),
+ always: function () {
+ this.isOpening = false;
+
+ // Delay positioning for ajax to prevent positioning during animation
+ setTimeout(function () { this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false); }.bind(this), 10);
+ }.bind(this)
+ });
+ } else {
+ this.wrapper.css({display: 'block', opacity: 1});
+ this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false);
+ this._fireEvent('onOpenComplete');
+ }
+ }
+ }.bind(this);
+
+ // Open jBox
+ this.options.delayOpen && !this.isOpen && !this.isClosing && !options.ignoreDelay ? (this.timer = setTimeout(open, this.options.delayOpen)) : open();
+
+ return this;
+ };
+
+
+ // Close jBox
+
+ jBox.prototype.close = function (options)
+ {
+ // Create blank options if none passed
+ options || (options = {});
+
+ // Remove close events
+ jQuery('body').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+ this.isTouchDevice && jQuery('body > *').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
+
+ // Abort if jBox was destroyed or is currently closing
+ if (this.isDestroyed || this.isClosing) return this;
+
+ // Abort opening
+ this.timer && clearTimeout(this.timer);
+
+ // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body' is true
+ this._blockBodyClick();
+
+ // Block closing
+ if (this.isDisabled) return this;
+
+ // Close function
+ var close = function () {
+
+ // Fire onClose event
+ this._fireEvent('onClose');
+
+ // Cancel the ajax call
+ if (this.options.cancelAjaxOnClose) {
+ this.cancelAjax();
+ }
+
+ // Only close if jBox is open
+ if (this.isOpen) {
+
+ // jBox is not open anymore
+ this.isOpen = false;
+
+ // Detach events
+ this._detachEvents();
+
+ // Unblock scrolling
+ if (this.options.blockScroll) {
+ if (this.options.blockScrollAdjust) {
+ jBox.blockScrollScopes = jBox.blockScrollScopes ? --jBox.blockScrollScopes : 0;
+ !jBox.blockScrollScopes && this.unscroll.reset();
+ } else {
+ jQuery('body').removeClass('jBox-blockScroll-' + this.id);
+ }
+ }
+
+ // Hide overlay
+ this.options.overlay && this._hideOverlay();
+
+ // Only animate if jBox is compleately closed
+ this.options.animation && !this.isOpening && this._animate('close');
+
+ // Play audio file
+ this.options.audio && this.options.audio.close && this.audio(this.options.audio.close, this.options.volume.close);
+
+ // Get fade duration
+ var fadeDuration = this.isTouchDevice && this.options.target == 'mouse' ? 0 : this.options.fade;
+
+ // Fading animation or show immediately
+ if (fadeDuration) {
+ this.wrapper.stop().animate({opacity: 0}, {
+ queue: false,
+ duration: fadeDuration,
+ start: function () {
+ this.isClosing = true;
+ }.bind(this),
+ complete: function () {
+ this.wrapper.css({display: 'none'});
+ this._fireEvent('onCloseComplete');
+ }.bind(this),
+ always: function () {
+ this.isClosing = false;
+ }.bind(this)
+ });
+ } else {
+ this.wrapper.css({display: 'none', opacity: 0});
+ this._fireEvent('onCloseComplete');
+ }
+ }
+ }.bind(this);
+
+ // Close jBox
+ if (options.ignoreDelay || (this.isTouchDevice && this.options.target == 'mouse')) {
+ close();
+ } else if ((this.options.delayOnHover || this.options.showCountdown) && this.options.delayClose > 10) {
+ var self = this;
+ var remaining = this.options.delayClose;
+ var prevFrame = Date.now();
+ if (this.options.showCountdown && !this.inner) {
+ var outer = jQuery('
');
+ this.inner = jQuery('
');
+ outer.prepend(this.inner);
+ jQuery('#' + this.id).append(outer);
+ }
+ this.countdown = function(){
+ var dateNow = Date.now();
+ if (!self.isHovered) {
+ remaining -= dateNow - prevFrame;
+ }
+ prevFrame = dateNow;
+ if (remaining > 0) {
+ if (self.options.showCountdown) {
+ self.inner.css('width', (remaining * 100 / self.options.delayClose) + '%');
+ }
+ window.requestAnimationFrame(self.countdown);
+ } else {
+ close();
+ }
+ };
+ window.requestAnimationFrame(this.countdown);
+ } else {
+ this.timer = setTimeout(close, Math.max(this.options.delayClose, 10));
+ }
+
+ return this;
+ };
+
+
+ // Open or close jBox
+
+ jBox.prototype.toggle = function (options)
+ {
+ this[this.isOpen ? 'close' : 'open'](options);
+ return this;
+ };
+
+
+ // Block opening and closing
+
+ jBox.prototype.disable = function ()
+ {
+ this.isDisabled = true;
+ return this;
+ };
+
+
+ // Unblock opening and closing
+
+ jBox.prototype.enable = function ()
+ {
+ this.isDisabled = false;
+ return this;
+ };
+
+
+ // Hide jBox
+
+ jBox.prototype.hide = function ()
+ {
+ this.disable();
+ if (this.wrapper) {
+ this.cacheWrapperDisplay = this.wrapper.css('display');
+ this.wrapper.css({display: 'none'});
+ }
+ if (this.overlay) {
+ this.cacheOverlayDisplay = this.overlay.css('display');
+ this.overlay.css({display: 'none'});
+ }
+ return this;
+ };
+
+
+ // Show jBox
+
+ jBox.prototype.show = function ()
+ {
+ this.enable();
+ if (this.wrapper && this.cacheWrapperDisplay) {
+ this.wrapper.css({display: this.cacheWrapperDisplay});
+ this.cacheWrapperDisplay = null;
+ }
+ if (this.overlay && this.cacheOverlayDisplay) {
+ this.overlay.css({display: this.cacheOverlayDisplay});
+ this.cacheOverlayDisplay = null;
+ }
+ return this;
+ };
+
+
+ // Get content from ajax
+
+ jBox.prototype.ajax = function (options, opening)
+ {
+ options || (options = {});
+
+ // Add data or url from source element if none set in options
+ jQuery.each([['getData', 'data'], ['getURL', 'url']], function (index, item) {
+ (this.options.ajax[item[0]] && !options[item[1]] && this.source && this.source.attr(this.options.ajax[item[0]]) != undefined) && (options[item[1]] = this.source.attr(this.options.ajax[item[0]]) || '');
+ }.bind(this));
+
+ // Clone the system options
+ var sysOptions = jQuery.extend(true, {}, this.options.ajax);
+
+ // Abort running ajax call
+ this.cancelAjax();
+
+ // Extract events
+ var beforeSend = options.beforeSend || sysOptions.beforeSend || function () {};
+ var complete = options.complete || sysOptions.complete || function () {};
+ var success = options.success || sysOptions.success || function () {};
+ var error = options.error || sysOptions.error || function () {};
+
+ // Merge options
+ var userOptions = jQuery.extend(true, sysOptions, options);
+
+ // Set new beforeSend event
+ userOptions.beforeSend = function (xhr)
+ {
+ // jBox is loading
+ userOptions.loadingClass && this.wrapper.addClass(userOptions.loadingClass === true ? 'jBox-loading' : userOptions.loadingClass);
+
+ // Add loading spinner
+ userOptions.spinner && (this.spinnerDelay = setTimeout(function ()
+ {
+ // Add class for loading spinner
+ this.wrapper.addClass('jBox-loading-spinner');
+
+ // Reposition jBox
+ // TODO: Only reposition if dimensions change
+ userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Add spinner to container
+ this.spinner = jQuery(userOptions.spinner !== true ? userOptions.spinner : '
').appendTo(this.container);
+
+ // Fix spinners position if there is a title
+ this.titleContainer && this.spinner.css('position') == 'absolute' && this.spinner.css({transform: 'translateY(' + (this.titleContainer.outerHeight() * 0.5) + 'px)'});
+
+ }.bind(this), (this.content.html() == '' ? 0 : (userOptions.spinnerDelay || 0))));
+
+ // Fire users beforeSend event
+ (beforeSend.bind(this))(xhr);
+
+ }.bind(this);
+
+ // Set up new complete event
+ userOptions.complete = function (response)
+ {
+ // Abort spinner timeout
+ this.spinnerDelay && clearTimeout(this.spinnerDelay);
+
+ // jBox finished loading
+ this.wrapper.removeClass('jBox-loading jBox-loading-spinner jBox-loading-spinner-delay');
+
+ // Remove spinner
+ this.spinner && this.spinner.length && this.spinner.remove() && userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Store that ajax loading finished
+ this.ajaxLoaded = true;
+
+ // Fire users complete event
+ (complete.bind(this))(response);
+
+ }.bind(this);
+
+ // Set up new success event
+ userOptions.success = function (response)
+ {
+ // Set content
+ userOptions.setContent && this.setContent(response, true) && (opening ? (this.positionOnFadeComplete = true) : this.position());
+
+ // Store content in source element
+ userOptions.setContent && this.source && this.source.data('jBox-ajax-data', response);
+
+ // Fire users success event
+ (success.bind(this))(response);
+
+ }.bind(this);
+
+ // Add error event
+ userOptions.error = function (response) { (error.bind(this))(response); }.bind(this);
+
+ // Send new ajax request
+ this.ajaxRequest = jQuery.ajax(userOptions);
+
+ return this;
+ };
+
+
+ // Abort an ajax call
+
+ jBox.prototype.cancelAjax = function () {
+ if (this.ajaxRequest) {
+ this.ajaxRequest.abort();
+ this.ajaxLoaded = false;
+ }
+ };
+
+
+ // Play an audio file
+
+ jBox.prototype.audio = function (url, volume)
+ {
+ // URL is required
+ if (!url) return this;
+
+ // Create intern audio object if it wasn't created already
+ !jBox._audio && (jBox._audio = {});
+
+ // Create an audio element specific to this audio file if it doesn't exist already
+ if (!jBox._audio[url]) {
+ var audio = jQuery(' ');
+ jQuery(' ', {src: url + '.mp3'}).appendTo(audio);
+ jQuery(' ', {src: url + '.ogg'}).appendTo(audio);
+ jBox._audio[url] = audio[0];
+ }
+
+ // Set volume
+ jBox._audio[url].volume = Math.min(((volume != undefined ? volume : 100) / 100), 1);
+
+ // Try to pause current audio
+ try {
+ jBox._audio[url].pause();
+ jBox._audio[url].currentTime = 0;
+ } catch (e) {}
+
+ // Play audio
+ jBox._audio[url].play();
+
+ return this;
+ };
+
+ // Apply custom animations to jBox (being used in playground demos)
+
+ jBox._animationSpeeds = {
+ 'tada': 1000,
+ 'tadaSmall': 1000,
+ 'flash': 500,
+ 'shake': 400,
+ 'pulseUp': 250,
+ 'pulseDown': 250,
+ 'popIn': 250,
+ 'popOut': 250,
+ 'fadeIn': 200,
+ 'fadeOut': 200,
+ 'slideUp': 400,
+ 'slideRight': 400,
+ 'slideLeft': 400,
+ 'slideDown': 400
+ };
+
+ jBox.prototype.animate = function (animation, options)
+ {
+ // Options are required
+ !options && (options = {});
+
+ // Timout needs to be an object
+ !this.animationTimeout && (this.animationTimeout = {});
+
+ // Use jBox wrapper by default
+ !options.element && (options.element = this.wrapper);
+
+ // Give the element an unique id
+ !options.element.data('jBox-animating-id') && options.element.data('jBox-animating-id', jBox._getUniqueElementID());
+
+ // Abort if element is animating
+ if (options.element.data('jBox-animating')) {
+ options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null);
+ this.animationTimeout[options.element.data('jBox-animating-id')] && clearTimeout(this.animationTimeout[options.element.data('jBox-animating-id')]);
+ }
+
+ // Animate the element
+ options.element.addClass('jBox-animated-' + animation).data('jBox-animating', 'jBox-animated-' + animation);
+ this.animationTimeout[options.element.data('jBox-animating-id')] = setTimeout((function() { options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null); options.complete && options.complete(); }), jBox._animationSpeeds[animation]);
+ };
+
+ // https://gist.github.com/AlexEmashev/ee8302b5036b01362f63dab35948401f
+ jBox.prototype.swipeDetector = function (swipeTarget, options) {
+ // States: 0 - no swipe, 1 - swipe started, 2 - swipe released
+ var swipeState = 0;
+ // Coordinates when swipe started
+ var startX = 0;
+ var startY = 0;
+ // Distance of swipe
+ var pixelOffsetX = 0;
+ var pixelOffsetY = 0;
+
+ var defaultSettings = {
+ // Amount of pixels, when swipe don't count.
+ swipeThreshold: 70,
+ // Flag that indicates that plugin should react only on touch events.
+ // Not on mouse events too.
+ useOnlyTouch: false
+ };
+
+ // Initializer
+ (function init() {
+ options = jQuery.extend(defaultSettings, options);
+ // Support touch and mouse as well.
+ swipeTarget.on("mousedown touchstart", swipeStart);
+ jQuery("html").on("mouseup touchend", swipeEnd);
+ jQuery("html").on("mousemove touchmove", swiping);
+ })();
+
+ function swipeStart(event) {
+ if (options.useOnlyTouch && !event.originalEvent.touches) {
+ return;
+ }
+
+ if (event.originalEvent.touches) {
+ event = event.originalEvent.touches[0];
+ }
+
+ if (swipeState === 0) {
+ swipeState = 1;
+ startX = event.clientX;
+ startY = event.clientY;
+ }
+ }
+
+ function swipeEnd(event) {
+ if (swipeState === 2) {
+ swipeState = 0;
+
+ if (
+ Math.abs(pixelOffsetX) > Math.abs(pixelOffsetY) &&
+ Math.abs(pixelOffsetX) > options.swipeThreshold
+ ) {
+ // Horizontal Swipe
+ if (pixelOffsetX < 0) {
+ swipeTarget.trigger(jQuery.Event("swipeLeft.sd"));
+ } else {
+ swipeTarget.trigger(jQuery.Event("swipeRight.sd"));
+ }
+ } else if (Math.abs(pixelOffsetY) > options.swipeThreshold) {
+ // Vertical swipe
+ if (pixelOffsetY < 0) {
+ swipeTarget.trigger(jQuery.Event("swipeUp.sd"));
+ } else {
+ swipeTarget.trigger(jQuery.Event("swipeDown.sd"));
+ }
+ }
+ }
+ }
+
+ function swiping(event) {
+ // If swipe don't occuring, do nothing.
+ if (swipeState !== 1) return;
+
+ if (event.originalEvent.touches) {
+ event = event.originalEvent.touches[0];
+ }
+
+ var swipeOffsetX = event.clientX - startX;
+ var swipeOffsetY = event.clientY - startY;
+
+ if (
+ Math.abs(swipeOffsetX) > options.swipeThreshold ||
+ Math.abs(swipeOffsetY) > options.swipeThreshold
+ ) {
+ swipeState = 2;
+ pixelOffsetX = swipeOffsetX;
+ pixelOffsetY = swipeOffsetY;
+ }
+ }
+
+ return swipeTarget; // Return element available for chaining.
+ }
+
+
+ // Destroy jBox and remove it from DOM
+
+ jBox.prototype.destroy = function ()
+ {
+ // Detach from attached elements
+ this.detach();
+
+ // If jBox is open, close without delay
+ this.isOpen && this.close({ignoreDelay: true});
+
+ // Remove wrapper
+ this.wrapper && this.wrapper.remove();
+
+ // Remove overlay
+ this.overlay && this.overlay.remove();
+
+ // Remove styles
+ this._styles && this._styles.remove();
+
+ // Tell the jBox instance it is destroyed
+ this.isDestroyed = true;
+
+ return this;
+ };
+
+
+ // Get a unique ID for jBoxes
+
+ jBox._getUniqueID = (function ()
+ {
+ var i = 1;
+ return function () { return i++; };
+ }());
+
+
+ // Get a unique ID for animating elements
+
+ jBox._getUniqueElementID = (function ()
+ {
+ var i = 1;
+ return function () { return i++; };
+ }());
+
+
+ // Function to create jBox plugins
+
+ jBox._pluginOptions = {};
+ jBox.plugin = function (type, options)
+ {
+ jBox._pluginOptions[type] = options;
+ };
+
+
+ // Make jBox usable with jQuery selectors
+
+ jQuery.fn.jBox = function (type, options) {
+ // Variables type and object are required
+ !type && (type = {});
+ !options && (options = {});
+
+ // Return a new instance of jBox with the selector as attached element
+ return new jBox(type, jQuery.extend(options, {
+ attach: this
+ }));
+ };
+
+ return jBox;
+
+};
diff --git a/Source/plugins/Confirm/jBox.Confirm.js b/src/js/plugins/jBox.Confirm.js
old mode 100644
new mode 100755
similarity index 58%
rename from Source/plugins/Confirm/jBox.Confirm.js
rename to src/js/plugins/jBox.Confirm.js
index 1b25806..0d02aa8
--- a/Source/plugins/Confirm/jBox.Confirm.js
+++ b/src/js/plugins/jBox.Confirm.js
@@ -1,27 +1,26 @@
/**
* jBox Confirm plugin: Add a confirm dialog to links, buttons, etc.
*
- * Author: Stephan Wagner (https://stephanwagner.me)
+ * Author: Stephan Wagner (https://stephanwagner.me)
*
* License: MIT (https://opensource.org/licenses/MIT)
*
- * Requires: jBox (https://code.jboxcdn.com/jBox.min.js)
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
*/
-jQuery(document).ready(function () {
-
- new jBoxPlugin('Confirm', {
-
-
+function jBoxConfirmWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Confirm', {
+
+
// Options (https://stephanwagner.me/jBox/options#options-confirm)
-
+
confirmButton: 'Submit', // Text for the submit button
cancelButton: 'Cancel', // Text for the cancel button
confirm: null, // Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found
cancel: null, // Function to execute when clicking the cancel button
closeOnConfirm: true, // Close jBox when the user clicks the confirm button
target: window,
- addClass: 'jBox-Modal',
fixed: true,
attach: '[data-confirm]',
getContent: 'data-confirm',
@@ -35,40 +34,62 @@ jQuery(document).ready(function () {
overlay: true,
animation: 'zoomIn',
preventDefault: true,
-
-
+
+
// Triggered when jBox is attached to the element
-
+
_onAttach: function (el)
{
// Extract the href or the onclick event if no submit event is passed
if (!this.options.confirm) {
- var submit = el.attr('onclick') ? el.attr('onclick') : (el.attr('href') ? (el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");' : 'window.location.href = "' + el.attr('href') + '";') : '');
+ var submit = el.attr('onclick') ? el.attr('onclick') : (
+ el.attr('href') ? (
+ el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");' : 'window.location.href = "' + el.attr('href') + '";'
+ ) : '');
el.prop('onclick', null).data('jBox-Confirm-submit', submit);
}
},
-
-
+
+
// Triggered when jBox was created
-
+
_onCreated: function ()
{
+ // Add modal class to mimic jBox modal
+ this.wrapper.addClass('jBox-Modal');
+
// Add a footer to the jBox container
this.footer = jQuery('');
- jQuery('
').html(this.options.cancelButton).click(function () { this.options.cancel && this.options.cancel(); this.close(); }.bind(this)).appendTo(this.footer);
- this.submitButton = jQuery('
').html(this.options.confirmButton).appendTo(this.footer);
+
+ jQuery('
')
+ .html(this.options.cancelButton)
+ .on('click tap', function () {
+ this.options.cancel && this.options.cancel(this.source);
+ this.close();
+ }.bind(this))
+ .appendTo(this.footer);
+
+ this.submitButton = jQuery('
')
+ .html(this.options.confirmButton)
+ .appendTo(this.footer);
+
this.footer.appendTo(this.container);
},
-
-
+
+
// Triggered when jBox is opened
-
+
_onOpen: function ()
{
// Set the new action for the submit button
- this.submitButton.off('click.jBox-Confirm' + this.id).on('click.jBox-Confirm' + this.id, function () { this.options.confirm ? this.options.confirm() : eval(this.source.data('jBox-Confirm-submit')); this.options.closeOnConfirm && this.close(); }.bind(this));
+ this.submitButton
+ .off('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id)
+ .on('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id, function () {
+ this.options.confirm ? this.options.confirm(this.source) : eval(this.source.data('jBox-Confirm-submit'));
+ this.options.closeOnConfirm && this.close();
+ }.bind(this));
}
-
+
});
-
-});
\ No newline at end of file
+
+};
diff --git a/src/js/plugins/jBox.Image.js b/src/js/plugins/jBox.Image.js
new file mode 100755
index 0000000..0d35da0
--- /dev/null
+++ b/src/js/plugins/jBox.Image.js
@@ -0,0 +1,356 @@
+/**
+ * jBox Image plugin: Adds a lightbox to your images
+ *
+ * Author: Stephan Wagner (https://stephanwagner.me)
+ *
+ * License: MIT (https://opensource.org/licenses/MIT)
+ *
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
+ */
+
+function jBoxImageWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Image', {
+
+
+ // Options (https://stephanwagner.me/jBox/options#options-image)
+
+ src: 'href', // The attribute where jBox gets the image source from, e.g. href="/path_to_image/image.jpg"
+ gallery: 'data-jbox-image', // The attribute to set the galleries, e.g. data-jbox-image="gallery1"
+ imageLabel: 'title', // The attribute where jBox gets the image label from, e.g. title="My label"
+ imageFade: 360, // The fade duration for images in ms
+ imageSize: 'contain', // How to display the images. Use CSS background-position values, e.g. 'cover', 'contain', 'auto', 'initial', '50% 50%'
+ imageCounter: false, // Set to true to add an image counter, e.g. 4/20
+ imageCounterSeparator: '/', // HTML to separate the current image number from all image numbers, e.g. '/' or ' of '
+ downloadButton: false, // Adds a download button
+ downloadButtonText: null, // Text for the download button
+ downloadButtonUrl: null, // The attribute at the source element where to find the image to download, e.g. data-download="/path_to_image/image.jpg". If none provided, the currently active image will be downloaded
+ mobileImageAttr: null, // The attribute to look for an mobile version of the image
+ mobileImageBreakpoint: null, // The upper breakpoint to load the mobile image
+ preloadFirstImage: false, // Preload the first image when page is loaded
+ target: window,
+ attach: '[data-jbox-image]',
+ fixed: true,
+ blockScroll: true,
+ closeOnEsc: true,
+ closeOnClick: 'button',
+ closeButton: true,
+ overlay: true,
+ animation: 'zoomIn',
+ preventDefault: true,
+ width: '100%',
+ height: '100%',
+ adjustDistance: {
+ top: 40,
+ right: 0,
+ bottom: 40,
+ left: 0
+ },
+
+
+ // Triggered when jBox is initialized
+
+ _onInit: function ()
+ {
+ // Initial images and z-index
+ this.images = this.currentImage = {};
+ this.imageZIndex = 1;
+
+ this.initImage = function (item) {
+ item = jQuery(item);
+
+ // Abort if the item was added to a gallery already
+ if (item.data('jBox-image-gallery')) {
+ return;
+ }
+
+ // Get the image src
+ var src = item.attr(this.options.src);
+
+ // Update responsive image src
+ if (this.options.mobileImageAttr && this.options.mobileImageBreakpoint && item.attr(this.options.mobileImageAttr)) {
+ if (jQuery(window).width() <= this.options.mobileImageBreakpoint) {
+ src = item.attr(this.options.mobileImageAttr);
+ }
+ }
+
+ // Add item to a gallery
+ var gallery = item.attr(this.options.gallery) || 'default';
+ !this.images[gallery] && (this.images[gallery] = []);
+ this.images[gallery].push({
+ src: src,
+ label: (item.attr(this.options.imageLabel) || ''),
+ downloadUrl: this.options.downloadButtonUrl && item.attr(this.options.downloadButtonUrl) ? item.attr(this.options.downloadButtonUrl) : null
+ });
+
+ // Remove the title attribute so it won't show the browsers tooltip
+ this.options.imageLabel == 'title' && item.removeAttr('title');
+
+ // Store data in source element for easy access
+ item.data('jBox-image-gallery', gallery);
+ item.data('jBox-image-id', (this.images[gallery].length - 1));
+ }.bind(this);
+
+ // Loop through images, sort and save in global variable
+ this.attachedElements && this.attachedElements.length && jQuery.each(this.attachedElements, function (index, item) {
+ this.initImage(item);
+ }.bind(this));
+
+ // Helper to inject the image into content area
+ var appendImage = function (gallery, id, show, instant) {
+ // Abort if image was appended already
+ if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
+ return;
+ }
+
+ // Create image container
+ var image = jQuery('
', {
+ id: 'jBox-image-' + gallery + '-' + id,
+ 'class': 'jBox-image-container' + (show ? ' jBox-image-' + gallery + '-current' : '')
+ }).css({
+ backgroundSize: this.options.imageSize,
+ opacity: (instant ? 1 : 0),
+ zIndex: (show ? this.imageZIndex++ : 0)
+ }).appendTo(this.content);
+
+ // Add swipe events
+ this.swipeDetector(image)
+ .on("swipeLeft.sd swipeRight.sd", function (event) {
+ if (event.type === "swipeLeft") {
+ this.showImage('next');
+ } else if (event.type === "swipeRight") {
+ this.showImage('prev');
+ }
+ }.bind(this));
+
+ // Create labels
+ jQuery('
', {
+ id: 'jBox-image-label-' + gallery + '-' + id,
+ 'class': 'jBox-image-label' + (show ? ' active' : '')
+ })
+ .html(this.images[gallery][id].label)
+ .on('click tap', function () {
+ jQuery(this).toggleClass('expanded');
+ })
+ .appendTo(this.imageLabelContainer);
+
+ // Show image
+ show && image.animate({opacity: 1}, instant ? 0 : this.options.imageFade);
+
+ return image;
+ }.bind(this);
+
+ // Function to download an image
+ this.downloadImage = function (imageUrl) {
+ var link = document.createElement('a');
+ link.href = imageUrl;
+ link.setAttribute('download', imageUrl.substring(imageUrl.lastIndexOf('/')+1));
+ document.body.appendChild(link);
+ link.click();
+ };
+
+ // Helper to show new image label
+ var showLabel = function (gallery, id) {
+ jQuery('.jBox-image-label.active').removeClass('active expanded');
+ jQuery('#jBox-image-label-' + gallery + '-' + id).addClass('active');
+ };
+
+ // Helper to load image
+ var loadImage = function (gallery, id, show, instant) {
+ var imageContainer = appendImage(gallery, id, show, instant);
+ imageContainer.addClass('jBox-image-loading');
+
+ jQuery(' ').each(function () {
+ var tmpImg = new Image();
+ tmpImg.onload = function () {
+ imageContainer.removeClass('jBox-image-loading');
+ imageContainer.css({backgroundImage: 'url("' + this.images[gallery][id].src + '")'});
+ }.bind(this);
+
+ tmpImg.onerror = function () {
+ imageContainer.removeClass('jBox-image-loading');
+ imageContainer.addClass('jBox-image-not-found');
+ }.bind(this);
+
+ tmpImg.src = this.images[gallery][id].src;
+ }.bind(this));
+ }.bind(this);
+
+ // Show images when they are loaded or load them if not
+ this.showImage = function (img) {
+ // Get the gallery and the image id from the next or the previous image
+ var gallery;
+ var id;
+
+ if (img != 'open') {
+ gallery = this.currentImage.gallery;
+ id = this.currentImage.id + (1 * (img == 'prev') ? -1 : 1);
+ id = id > (this.images[gallery].length - 1) ? 0 : (id < 0 ? (this.images[gallery].length - 1) : id);
+
+ // Or get image data from source element
+ } else {
+ // Get gallery and image id from source element
+ if (this.source) {
+ gallery = this.source.data('jBox-image-gallery');
+ id = this.source.data('jBox-image-id');
+
+ // Get gallery and image id attached elements
+ } else if (this.attachedElements && this.attachedElements.length) {
+ gallery = jQuery(this.attachedElements[0]).data('jBox-image-gallery');
+ id = jQuery(this.attachedElements[0]).data('jBox-image-id');
+ } else {
+ return;
+ }
+
+ // Remove or show the next and prev buttons
+ if (this.images && this.images[gallery]) {
+ jQuery('.jBox-image-pointer-prev, .jBox-image-pointer-next').css({display: (this.images[gallery].length > 1 ? 'block' : 'none')});
+ }
+ }
+
+ // If there is a current image already shown, hide it
+ if (jQuery('.jBox-image-' + gallery + '-current').length) {
+ jQuery('.jBox-image-' + gallery + '-current').removeClass('jBox-image-' + gallery + '-current').animate({opacity: 0}, (img == 'open') ? 0 : this.options.imageFade);
+ }
+
+ // Set new current image
+ this.currentImage = {gallery: gallery, id: id};
+
+ // Show image if it already exists
+ if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
+ jQuery('#jBox-image-' + gallery + '-' + id).addClass('jBox-image-' + gallery + '-current').css({zIndex: this.imageZIndex++, opacity: 0}).animate({opacity: 1}, (img == 'open') ? 0 : this.options.imageFade);
+
+ // Load image
+ } else {
+ loadImage(gallery, id, true, (img === 'open'));
+ }
+
+ // Show label
+ showLabel(gallery, id);
+
+ // Update the image counter numbers
+ if (this.imageCounter) {
+ if (this.images[gallery] && this.images[gallery].length > 1) {
+ this.wrapper.addClass('jBox-image-has-counter');
+ this.imageCounter.find('.jBox-image-counter-all').html(this.images[gallery].length);
+ this.imageCounter.find('.jBox-image-counter-current').html(id + 1);
+ } else {
+ this.wrapper.removeClass('jBox-image-has-counter');
+ }
+ }
+
+ // Preload next image
+ if (this.images[gallery] && this.images[gallery].length - 1) {
+ var next_id = id + 1;
+ next_id = next_id > (this.images[gallery].length - 1) ? 0 : (next_id < 0 ? (this.images[gallery].length - 1) : next_id);
+
+ if (!jQuery('#jBox-image-' + gallery + '-' + next_id).length) {
+ loadImage(gallery, next_id, false, false);
+ }
+ }
+ };
+
+ // Preload image
+ if (this.options.preloadFirstImage) {
+ jQuery(window).on('load', function() {
+ this.showImage('open');
+ }.bind(this));
+ }
+ },
+
+
+ // Triggered when jBox attaches a new element
+
+ _onAttach: function (item) {
+ this.initImage && this.initImage(item);
+ },
+
+
+ // Triggered when jBox was created
+
+ _onCreated: function ()
+ {
+ // Create image label and navigation buttons
+ this.imageLabelWrapper = jQuery('
').appendTo(this.wrapper);
+
+ this.imagePrevButton = jQuery('
')
+ .on('click tap', function () {
+ this.showImage('prev');
+ }.bind(this));
+
+ this.imageNextButton = jQuery('
')
+ .on('click tap', function () {
+ this.showImage('next');
+ }.bind(this));
+
+ this.imageLabelContainer = jQuery('
');
+
+ this.imageLabelWrapper
+ .append(this.imagePrevButton)
+ .append(this.imageLabelContainer)
+ .append(this.imageNextButton);
+
+ // Append the download button
+ if (this.options.downloadButton) {
+ this.downloadButton = jQuery('
', {'class': 'jBox-image-download-button-wrapper'})
+ .appendTo(this.wrapper)
+ .append(
+ this.options.downloadButtonText ? jQuery('
', {'class': 'jBox-image-download-button-text'}).html(this.options.downloadButtonText) : null
+ )
+ .append(
+ jQuery('
', {'class': 'jBox-image-download-button-icon'})
+ ).on('click tap', function () {
+ if (this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl) {
+ var currentImageUrl = this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl;
+ } else {
+ var currentImage = this.wrapper.find('.jBox-image-' + this.currentImage.gallery + '-current');
+ var currentImageStyle = currentImage[0].style.backgroundImage;
+ var currentImageUrl = currentImageStyle.slice(4, -1).replace(/["']/g, '');
+ }
+ this.downloadImage(currentImageUrl);
+ }.bind(this));
+ }
+
+ // Creating the image counter containers
+ if (this.options.imageCounter) {
+ this.imageCounter = jQuery('
', {'class': 'jBox-image-counter-container'}).insertAfter(this.imageLabelContainer);
+ this.imageCounter.append(jQuery(' ', {'class': 'jBox-image-counter-current'})).append(jQuery(' ').html(this.options.imageCounterSeparator)).append(jQuery(' ', {'class': 'jBox-image-counter-all'}));
+ }
+ },
+
+
+ // Triggered when jBox opens
+
+ _onOpen: function ()
+ {
+ // Add key events
+ jQuery(document).on('keyup.jBox-Image-' + this.id, function (ev) {
+ (ev.keyCode == 37) && this.showImage('prev');
+ (ev.keyCode == 39) && this.showImage('next');
+ }.bind(this));
+
+ // Load the image from the attached element
+ this.showImage('open');
+ },
+
+
+ // Triggered when jBox closes
+
+ _onClose: function ()
+ {
+ // Remove key events
+ jQuery(document).off('keyup.jBox-Image-' + this.id);
+ },
+
+
+ // Triggered when jBox finished closing
+
+ _onCloseComplete: function ()
+ {
+ // Hide all image containers
+ this.wrapper.find('.jBox-image-container').css('opacity', 0);
+ }
+
+ });
+
+};
diff --git a/Source/plugins/Notice/jBox.Notice.js b/src/js/plugins/jBox.Notice.js
old mode 100644
new mode 100755
similarity index 72%
rename from Source/plugins/Notice/jBox.Notice.js
rename to src/js/plugins/jBox.Notice.js
index 33c12c6..c32eea5
--- a/Source/plugins/Notice/jBox.Notice.js
+++ b/src/js/plugins/jBox.Notice.js
@@ -1,20 +1,20 @@
/**
* jBox Notice plugin: Opens a popup notice
*
- * Author: Stephan Wagner (https://stephanwagner.me)
+ * Author: Stephan Wagner (https://stephanwagner.me)
*
* License: MIT (https://opensource.org/licenses/MIT)
*
- * Requires: jBox (https://code.jboxcdn.com/jBox.min.js)
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
*/
-jQuery(document).ready(function () {
-
- new jBoxPlugin('Notice', {
-
-
+function jBoxNoticeWrapper(jBox, jQuery) {
+
+ new jBox.plugin('Notice', {
+
+
// Options (https://stephanwagner.me/jBox/options#options-notice)
-
+
color: null, // Add a color to your notices, use 'gray' (default), 'black', 'red', 'green', 'blue' or 'yellow'
stack: true, // Set to false to disable notice-stacking
stackSpacing: 10, // Spacing between notices when they stack
@@ -42,15 +42,15 @@ jQuery(document).ready(function () {
animation: 'zoomIn',
closeOnClick: 'box',
zIndex: 12000,
-
-
+
+
// Triggered when notice is initialized
-
+
_onInit: function ()
{
// Cache position values
this.defaultNoticePosition = jQuery.extend({}, this.options.position);
-
+
// Type Notice has its own adjust position function
this._adjustNoticePositon = function () {
var win = jQuery(window);
@@ -58,10 +58,10 @@ jQuery(document).ready(function () {
x: win.width(),
y: win.height()
};
-
+
// Reset default position
this.options.position = jQuery.extend({}, this.defaultNoticePosition);
-
+
// Adjust depending on viewport
jQuery.each(this.options.responsivePositions, function (viewport, position) {
if (windowDimensions.x <= viewport) {
@@ -69,7 +69,7 @@ jQuery(document).ready(function () {
return false;
}
}.bind(this));
-
+
// Set new padding options
this.options.adjustDistance = {
top: this.options.position.y,
@@ -78,66 +78,94 @@ jQuery(document).ready(function () {
left: this.options.position.x
};
};
-
+
// If jBox grabs an element as content, crab a clone instead
this.options.content instanceof jQuery && (this.options.content = this.options.content.clone().attr('id', ''));
-
+
// Adjust paddings when window resizes
jQuery(window).on('resize.responsivejBoxNotice-' + this.id, function (ev) { if (this.isOpen) { this._adjustNoticePositon(); } }.bind(this));
-
+
this.open();
},
-
-
+
+
// Triggered when notice was created
-
+
_onCreated: function ()
{
// Add color class
this.wrapper.addClass('jBox-Notice-color jBox-Notice-' + (this.options.color || 'gray'));
-
+
// Store position in jBox wrapper
this.wrapper.data('jBox-Notice-position', this.options.attributes.x + '-' + this.options.attributes.y);
},
-
-
+
+
// Triggered when notice opens
-
+
_onOpen: function ()
{
+ // Bail if we're stacking
+ if (this.options.stack) {
+ return;
+ }
+
// Adjust position when opening
this._adjustNoticePositon();
-
- // Loop through notices at same window corner and either move or destroy them
+
+ // Loop through notices at same window corner destroy them
jQuery.each(jQuery('.jBox-Notice'), function (index, el)
{
el = jQuery(el);
-
+
// Abort if the element is this notice or when it's not at the same position
- if (el.attr('id') == this.id || el.data('jBox-Notice-position') != this.options.attributes.x + '-' + this.options.attributes.y) return;
-
+ if (el.attr('id') == this.id || el.data('jBox-Notice-position') != this.options.attributes.x + '-' + this.options.attributes.y) {
+ return;
+ }
+
// Remove notice when we don't wont to stack them
if (!this.options.stack) {
el.data('jBox').close({ignoreDelay: true});
return;
}
-
- // Get the new margin and add to notices
- var margin = (el.data('jBoxNoticeMargin') ? parseInt(el.data('jBoxNoticeMargin')) : parseInt(el.css('margin-' + this.options.attributes.y))) + this.wrapper.outerHeight() + this.options.stackSpacing;
- el.data('jBoxNoticeMargin', margin);
- el.css('margin-' + this.options.attributes.y, margin);
-
}.bind(this));
},
-
-
- // Remove notice from DOM when closing finishes
-
+
+ // Triggered when resizing window etc.
+
+ _onPosition: function ()
+ {
+ var stacks = {};
+ jQuery.each(jQuery('.jBox-Notice'), function (index, el)
+ {
+ el = jQuery(el);
+ var pos = el.data('jBox-Notice-position');
+ if (!stacks[pos]) {
+ stacks[pos] = [];
+ }
+ stacks[pos].push(el);
+ });
+ for (var pos in stacks) {
+ var position = pos.split('-');
+ var direction = position[1];
+ stacks[pos].reverse();
+ var margin = 0;
+ for (var i in stacks[pos]) {
+ var el = jQuery(stacks[pos][i]);
+ el.css('margin-' + direction, margin);
+ margin += el.outerHeight() + this.options.stackSpacing;
+ }
+ }
+ },
+
+ // Remove notice from DOM and reposition other notices when closing finishes
+
_onCloseComplete: function ()
{
- this.destroy();
+ this.destroy();
+ this.options._onPosition.bind(this).call();
}
-
+
});
-
-});
\ No newline at end of file
+
+};
diff --git a/src/js/umd.js b/src/js/umd.js
new file mode 100755
index 0000000..73216e4
--- /dev/null
+++ b/src/js/umd.js
@@ -0,0 +1,17 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], function (jQuery) {
+ return (root.jBox = factory(jQuery));
+ });
+ } else if (typeof module === 'object' && module.exports) {
+ module.exports = (root.jBox = factory(require('jquery')));
+ } else {
+ root.jBox = factory(root.jQuery);
+ }
+}(this, function (jQuery) {
+ var jBox = jBoxWrapper(jQuery);
+ try { typeof jBoxConfirmWrapper !== 'undefined' && jBoxConfirmWrapper && jBoxConfirmWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ try { typeof jBoxImageWrapper !== 'undefined' && jBoxImageWrapper && jBoxImageWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ try { typeof jBoxNoticeWrapper !== 'undefined' && jBoxNoticeWrapper && jBoxNoticeWrapper(jBox, jQuery); } catch(e) { console.error(e); }
+ return jBox;
+}));
diff --git a/src/scss/jBox.scss b/src/scss/jBox.scss
new file mode 100755
index 0000000..54f335d
--- /dev/null
+++ b/src/scss/jBox.scss
@@ -0,0 +1,670 @@
+// Global
+
+.jBox-wrapper {
+ text-align: left;
+ box-sizing: border-box;
+}
+
+.jBox-title,
+.jBox-content,
+.jBox-container {
+ position: relative;
+ word-break: break-word;
+ box-sizing: border-box;
+}
+
+.jBox-container {
+ background: #fff;
+}
+
+.jBox-content {
+ padding: 8px 12px;
+ overflow-x: hidden;
+ overflow-y: auto;
+ transition: opacity .2s;
+}
+
+.jBox-footer {
+ box-sizing: border-box;
+}
+
+// jBox Tooltip
+
+.jBox-Tooltip,
+.jBox-Mouse {
+ .jBox-container {
+ border-radius: 4px;
+ box-shadow: 0 0 3px rgba(0, 0, 0, .25);
+ }
+
+ .jBox-title {
+ padding: 8px 10px 0;
+ font-weight: bold;
+ }
+
+ &.jBox-hasTitle .jBox-content {
+ padding-top: 5px;
+ }
+}
+
+.jBox-Mouse {
+ pointer-events: none;
+}
+
+// Pointer
+
+.jBox-pointer {
+ position: absolute;
+ overflow: hidden;
+ box-sizing: border-box;
+
+ &:after {
+ content: '';
+ width: 20px;
+ height: 20px;
+ position: absolute;
+ background: #fff;
+ transform: rotate(45deg);
+ box-sizing: border-box;
+ }
+
+ &-top {
+ top: 0;
+
+ &:after {
+ left: 5px;
+ top: 6px;
+ box-shadow: -1px -1px 2px rgba(0, 0, 0, .15);
+ }
+ }
+
+ &-right {
+ right: 0;
+
+ &:after {
+ top: 5px;
+ right: 6px;
+ box-shadow: 1px -1px 2px rgba(0, 0, 0, .15);
+ }
+ }
+
+ &-left {
+ left: 0;
+
+ &:after {
+ top: 5px;
+ left: 6px;
+ box-shadow: -1px 1px 2px rgba(0, 0, 0, .15);
+ }
+ }
+
+ &-bottom {
+ bottom: 0;
+
+ &:after {
+ left: 5px;
+ bottom: 6px;
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, .15);
+ }
+ }
+
+ &-top,
+ &-bottom {
+ width: 30px;
+ height: 12px;
+ }
+
+ &-left,
+ &-right {
+ width: 12px;
+ height: 30px;
+ }
+}
+
+// jBox Modal
+
+.jBox-Modal {
+ .jBox-container {
+ border-radius: 4px;
+ }
+
+ .jBox-container,
+ &.jBox-closeButton-box:before {
+ box-shadow: 0 3px 15px rgba(0, 0, 0, .4), 0 0 5px rgba(0, 0, 0, .4);
+ }
+
+ .jBox-content {
+ padding: 15px 20px;
+ }
+
+ .jBox-title {
+ border-radius: 4px 4px 0 0;
+ padding: 15px 20px;
+ background: #fafafa;
+ border-bottom: 1px solid #eee;
+ }
+
+ &.jBox-closeButton-title {
+ .jBox-title {
+ padding-right: 65px;
+ }
+ }
+
+ .jBox-footer {
+ border-radius: 0 0 4px 4px;
+ }
+}
+
+// Close button
+
+.jBox-closeButton {
+ z-index: 1;
+ cursor: pointer;
+ position: absolute;
+ box-sizing: border-box;
+
+ svg {
+ position: absolute;
+ top: 50%;
+ right: 50%;
+ }
+
+ path {
+ fill: #aaa;
+ transition: fill .2s;
+ }
+
+ &:hover {
+ path {
+ fill: #888;
+ }
+ }
+}
+
+// Close button in overlay
+
+.jBox-overlay {
+ .jBox-closeButton {
+ top: 0;
+ right: 0;
+ width: 40px;
+ height: 40px;
+
+ svg {
+ width: 20px;
+ height: 20px;
+ margin-top: -10px;
+ margin-right: -10px;
+ }
+
+ path {
+ fill: #ddd;
+ }
+
+ &:hover path {
+ fill: #fff;
+ }
+ }
+
+}
+
+// Close button in title
+
+.jBox-closeButton-title {
+ .jBox-closeButton {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ width: 50px;
+ }
+
+ svg {
+ width: 12px;
+ height: 12px;
+ margin-top: -6px;
+ margin-right: -6px;
+ }
+}
+
+// Close button in box
+
+.jBox-closeButton-box {
+ box-sizing: border-box;
+
+ .jBox-closeButton {
+ top: -8px;
+ right: -10px;
+ width: 24px;
+ height: 24px;
+ background: #fff;
+ border-radius: 50%;
+
+ svg {
+ width: 10px;
+ height: 10px;
+ margin-top: -5px;
+ margin-right: -5px;
+ }
+ }
+
+ &:before {
+ content: '';
+ position: absolute;
+ top: -8px;
+ right: -10px;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ }
+
+ &.jBox-pointerPosition-top:before {
+ top: 5px;
+ }
+
+ &.jBox-pointerPosition-right:before {
+ right: 2px;
+ }
+}
+
+
+.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton {
+ background: #fafafa;
+}
+
+// Overlay
+
+.jBox-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, .82);
+}
+
+// Footer
+
+.jBox-footer {
+ background: #fafafa;
+ border-top: 1px solid #eee;
+ padding: 8px 10px;
+ border-radius: 0 0 3px 3px;
+}
+
+// Block scrolling
+
+body[class^="jBox-blockScroll-"],
+body[class*=" jBox-blockScroll-"] {
+ overflow: hidden;
+}
+
+// Draggable
+
+.jBox-draggable {
+ cursor: move;
+}
+
+// Spinner
+
+@keyframes jBoxLoading {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.jBox-loading .jBox-content {
+ opacity: .2;
+}
+
+.jBox-loading-spinner .jBox-content {
+ min-height: 38px !important;
+ min-width: 38px !important;
+ opacity: 0;
+}
+
+.jBox-spinner {
+ box-sizing: border-box;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 24px;
+ height: 24px;
+ margin-top: -12px;
+ margin-left: -12px;
+
+ &:before {
+ display: block;
+ box-sizing: border-box;
+ content: '';
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ border: 2px solid rgba(0, 0, 0, .2);
+ border-top-color: rgba(0, 0, 0, .8);
+ animation: jBoxLoading .6s linear infinite;
+ }
+}
+
+// Countdown
+
+.jBox-countdown {
+ border-radius: 4px 4px 0 0;
+ z-index: 0;
+ background: #000;
+ opacity: .2;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ overflow: hidden;
+
+ &-inner {
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 3px;
+ position: absolute;
+ background: #fff;
+ }
+}
+
+// Animations
+
+[class^="jBox-animated-"],
+[class*=" jBox-animated-"] {
+ animation-fill-mode: both;
+}
+
+// Animation tada
+
+@keyframes jBox-tada {
+ 0% {
+ transform: scale(1);
+ }
+
+ 10%,
+ 20% {
+ transform: scale(0.8) rotate(-4deg);
+ }
+
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: scale(1.2) rotate(4deg);
+ }
+
+ 40%,
+ 60%,
+ 80% {
+ transform: scale(1.2) rotate(-4deg);
+ }
+
+ 100% {
+ transform: scale(1) rotate(0);
+ }
+}
+
+.jBox-animated-tada {
+ animation: jBox-tada 1s;
+}
+
+// Animation tadaSmall
+
+@keyframes jBox-tadaSmall {
+ 0% {
+ transform: scale(1);
+ }
+
+ 10%,
+ 20% {
+ transform: scale(0.9) rotate(-2deg);
+ }
+
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: scale(1.1) rotate(2deg);
+ }
+
+ 40%,
+ 60%,
+ 80% {
+ transform: scale(1.1) rotate(-2deg);
+ }
+
+ 100% {
+ transform: scale(1) rotate(0);
+ }
+}
+
+.jBox-animated-tadaSmall {
+ animation: jBox-tadaSmall 1s;
+}
+
+// Animation flash
+
+@keyframes jBox-flash {
+
+ 0%,
+ 50%,
+ 100% {
+ opacity: 1;
+ }
+
+ 25%,
+ 75% {
+ opacity: 0;
+ }
+}
+
+.jBox-animated-flash {
+ animation: jBox-flash .5s;
+}
+
+// Animation shake
+
+@keyframes jBox-shake {
+
+ 0%,
+ 100% {
+ transform: translateX(0);
+ }
+
+ 20%,
+ 60% {
+ transform: translateX(-6px);
+ }
+
+ 40%,
+ 80% {
+ transform: translateX(6px);
+ }
+}
+
+.jBox-animated-shake {
+ animation: jBox-shake .4s;
+}
+
+// Animation pulseUp
+
+@keyframes jBox-pulseUp {
+ 0% {
+ transform: scale(1);
+ }
+
+ 50% {
+ transform: scale(1.15);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jBox-animated-pulseUp {
+ animation: jBox-pulseUp .25s;
+}
+
+// Animation pulseDown
+
+@keyframes jBox-pulseDown {
+ 0% {
+ transform: scale(1);
+ }
+
+ 50% {
+ transform: scale(0.85);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jBox-animated-pulseDown {
+ animation: jBox-pulseDown .25s;
+}
+
+// Animation popIn
+
+@keyframes jBox-popIn {
+ 0% {
+ transform: scale(0);
+ }
+
+ 50% {
+ transform: scale(1.1);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jBox-animated-popIn {
+ animation: jBox-popIn .25s;
+}
+
+// Animation popOut
+
+@keyframes jBox-popOut {
+ 0% {
+ transform: scale(1);
+ }
+
+ 50% {
+ transform: scale(1.1);
+ }
+
+ 100% {
+ transform: scale(0);
+ }
+}
+
+.jBox-animated-popOut {
+ animation: jBox-popOut .25s;
+}
+
+// Animation fadeIn
+
+@keyframes jBox-fadeIn {
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+.jBox-animated-fadeIn {
+ animation: jBox-fadeIn .2s;
+}
+
+// Animation fadeOut
+
+@keyframes jBox-fadeOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
+
+.jBox-animated-fadeOut {
+ animation: jBox-fadeOut .2s;
+}
+
+// Animation slideUp
+
+@keyframes jBox-slideUp {
+ 0% {
+ transform: translateY(0);
+ }
+
+ 100% {
+ transform: translateY(-300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideUp {
+ animation: jBox-slideUp .4s;
+}
+
+// Animation slideRight
+
+@keyframes jBox-slideRight {
+ 0% {
+ transform: translateX(0);
+ }
+
+ 100% {
+ transform: translateX(300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideRight {
+ animation: jBox-slideRight .4s;
+}
+
+// Animation slideDown
+
+@keyframes jBox-slideDown {
+ 0% {
+ transform: translateY(0);
+ }
+
+ 100% {
+ transform: translateY(300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideDown {
+ animation: jBox-slideDown .4s;
+}
+
+// Animation slideLeft
+
+@keyframes jBox-slideLeft {
+ 0% {
+ transform: translateX(0);
+ }
+
+ 100% {
+ transform: translateX(-300px);
+ opacity: 0;
+ }
+}
+
+.jBox-animated-slideLeft {
+ animation: jBox-slideLeft .4s;
+}
diff --git a/src/scss/plugins/jBox.Confirm.scss b/src/scss/plugins/jBox.Confirm.scss
new file mode 100755
index 0000000..d701171
--- /dev/null
+++ b/src/scss/plugins/jBox.Confirm.scss
@@ -0,0 +1,60 @@
+// jBox plugin: Confirm
+
+.jBox-Confirm {
+ .jBox-content {
+ text-align: center;
+ padding: 46px 35px;
+
+ @media (max-width: 500px) {
+ padding: 32px 20px;
+ }
+ }
+}
+
+.jBox-Confirm-footer {
+ height: 46px;
+}
+
+.jBox-Confirm-button {
+ display: block;
+ float: left;
+ cursor: pointer;
+ text-align: center;
+ width: 50%;
+ line-height: 46px;
+ height: 46px;
+ overflow: hidden;
+ padding: 0 10px;
+ transition: color .2s, background-color .2s;
+ box-sizing: border-box;
+
+ &-cancel {
+ border-bottom-left-radius: 4px;
+ background: #ddd;
+ color: #666;
+
+ &:hover,
+ &:active {
+ background: #ccc;
+ }
+
+ &:active {
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);
+ }
+ }
+
+ &-submit {
+ border-bottom-right-radius: 4px;
+ background: #7d0;
+ color: #fff;
+
+ &:hover,
+ &:active {
+ background: #6c0;
+ }
+
+ &:active {
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);
+ }
+ }
+}
diff --git a/src/scss/plugins/jBox.Image.scss b/src/scss/plugins/jBox.Image.scss
new file mode 100755
index 0000000..f02c3c0
--- /dev/null
+++ b/src/scss/plugins/jBox.Image.scss
@@ -0,0 +1,204 @@
+// jBox plugin: Image
+
+.jBox-Image {
+ .jBox-container {
+ background-color: transparent;
+ }
+
+ .jBox-content {
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ }
+}
+
+.jBox-image-container {
+ background: center center no-repeat;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+}
+
+.jBox-image-label-wrapper {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ height: 40px;
+ z-index: 100;
+ display: flex;
+}
+
+.jBox-image-label-container {
+ position: relative;
+ flex: 1;
+}
+
+.jBox-image-label {
+ box-sizing: border-box;
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ text-align: center;
+ color: #fff;
+ padding: 8px 12px;
+ font-size: 15px;
+ line-height: 24px;
+ transition: opacity .36s;
+ opacity: 0;
+ z-index: 0;
+ pointer-events: none;
+
+ &.expanded {
+ background: #000;
+ }
+
+ &:not(.expanded) {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+
+ &.active {
+ opacity: 1;
+ pointer-events: all;
+ }
+
+ @media (max-width: 600px) {
+ font-size: 13px;
+ }
+}
+
+.jBox-image-pointer-next,
+.jBox-image-pointer-prev {
+ flex-shrink: 0;
+ width: 40px;
+ height: 40px;
+ cursor: pointer;
+ opacity: .8;
+ transition: opacity .2s;
+ background: no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);
+ background-size: 11px auto;
+ user-select: none;
+ z-index: 1;
+
+ &:hover {
+ opacity: 1;
+ }
+}
+
+.jBox-image-pointer-next {
+ transform: scaleX(-1);
+}
+
+.jBox-image-counter-container {
+ flex-shrink: 0;
+ white-space: nowrap;
+ height: 40px;
+ line-height: 40px;
+ font-size: 13px;
+ color: #fff;
+ text-align: right;
+ display: none;
+}
+
+.jBox-image-has-counter .jBox-image-counter-container {
+ display: block;
+}
+
+.jBox-overlay.jBox-overlay-Image {
+ background: #000;
+}
+
+.jBox-image-not-found {
+ background: #000;
+
+ &:before {
+ content: '';
+ box-sizing: border-box;
+ display: block;
+ width: 80px;
+ height: 80px;
+ margin-top: -40px;
+ margin-left: -40px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ border: 5px solid #222;
+ border-radius: 50%;
+ }
+
+ &:after {
+ content: '';
+ display: block;
+ box-sizing: content-box;
+ z-index: auto;
+ width: 6px;
+ height: 74px;
+ margin-top: -37px;
+ margin-left: -3px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ background: #222;
+ transform: rotateZ(45deg);
+ transform-origin: 50% 50% 0;
+ }
+}
+
+// Download button
+
+.jBox-image-download-button-wrapper {
+ position: absolute;
+ top: -40px;
+ right: 35px;
+ height: 40px;
+ display: flex;
+ cursor: pointer;
+ opacity: .8;
+ transition: opacity .2s;
+
+ &:hover {
+ opacity: 1;
+ }
+}
+
+.jBox-image-download-button-icon {
+ width: 40px;
+ height: 40px;
+ background: center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);
+ background-size: 60%;
+}
+
+.jBox-image-download-button-text {
+ white-space: nowrap;
+ line-height: 40px;
+ padding: 0 10px 0 0;
+ color: #fff;
+ font-size: 14px;
+}
+
+// Image spinner
+
+@keyframes jBoxImageLoading {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.jBox-image-loading:before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 32px;
+ height: 32px;
+ margin-top: -16px;
+ margin-left: -16px;
+ border: 4px solid #333;
+ border-bottom-color: #666;
+ animation: jBoxImageLoading 1.2s linear infinite;
+ border-radius: 50%;
+}
diff --git a/src/scss/plugins/jBox.Notice.scss b/src/scss/plugins/jBox.Notice.scss
new file mode 100755
index 0000000..4e67e3c
--- /dev/null
+++ b/src/scss/plugins/jBox.Notice.scss
@@ -0,0 +1,148 @@
+// jBox plugin: Notice
+
+.jBox-Notice {
+ transition: margin .2s;
+
+ .jBox-container {
+ border-radius: 4px;
+ box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, .25), inset -1px -1px 0 0 rgba(0, 0, 0, .1);
+ }
+
+ .jBox-content {
+ border-radius: 4px;
+ padding: 12px 20px;
+
+ @media (max-width: 768px) {
+ padding: 10px 15px;
+ }
+
+ @media (max-width: 500px) {
+ padding: 8px 10px;
+ }
+ }
+
+ &.jBox-hasTitle {
+ .jBox-content {
+ padding-top: 5px;
+
+ @media (max-width: 500px) {
+ padding-top: 0;
+ }
+ }
+
+ .jBox-title {
+ padding: 12px 20px 0;
+ font-weight: bold;
+
+ @media (max-width: 768px) {
+ padding: 10px 15px 0;
+ }
+
+ @media (max-width: 500px) {
+ padding: 8px 10px 0;
+ }
+ }
+ }
+
+ &.jBox-closeButton-title {
+ .jBox-title {
+ padding-right: 55px;
+ }
+
+ &.jBox-hasTitle {
+ .jBox-closeButton {
+ width: 40px;
+ }
+ }
+ }
+
+ &.jBox-Notice-black {
+ .jBox-container {
+ color: #fff;
+ background: #000;
+ }
+
+ &.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+
+ path,
+ &:hover path {
+ fill: #fff;
+ }
+ }
+ }
+
+ &.jBox-Notice-gray {
+ .jBox-container {
+ color: #222;
+ background: #f6f6f6;
+ }
+
+ &.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+
+ path,
+ &:hover path {
+ fill: #222;
+ }
+ }
+ }
+
+ &.jBox-Notice-red {
+ .jBox-container {
+ color: #fff;
+ background: #d00;
+ }
+
+ &.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+
+ path,
+ &:hover path {
+ fill: #fff;
+ }
+ }
+ }
+
+ &.jBox-Notice-green {
+ .jBox-container {
+ color: #fff;
+ background: #5d0;
+ }
+
+ &.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+
+ path,
+ &:hover path {
+ fill: #fff;
+ }
+ }
+ }
+
+ &.jBox-Notice-blue {
+ .jBox-container {
+ color: #fff;
+ background: #49d;
+ }
+
+ &.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+
+ path,
+ &:hover path {
+ fill: #fff;
+ }
+ }
+ }
+
+ &.jBox-Notice-yellow {
+ .jBox-container {
+ color: #000;
+ background: #fd0;
+ }
+
+ &.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
+
+ path,
+ &:hover path {
+ fill: #fff;
+ }
+ }
+ }
+}
diff --git a/src/scss/themes/jBox.NoticeFancy.scss b/src/scss/themes/jBox.NoticeFancy.scss
new file mode 100755
index 0000000..968c1f4
--- /dev/null
+++ b/src/scss/themes/jBox.NoticeFancy.scss
@@ -0,0 +1,52 @@
+// jBox theme: NoticeFancy
+
+.jBox-NoticeFancy {
+
+ .jBox-content,
+ .jBox-title {
+ padding-left: 25px;
+ }
+
+ &.jBox-Notice-color .jBox-container {
+ color: #fff;
+ background: #000;
+
+ &:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 8px;
+ border-radius: 4px 0 0 4px;
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .4) 75%, transparent 75%, transparent);
+ background-size: 14px 14px;
+ }
+ }
+
+ &.jBox-Notice-black .jBox-container:after,
+ &.jBox-Notice-gray .jBox-container:after {
+ background-color: #888;
+ }
+
+ &.jBox-Notice-red .jBox-container:after {
+ background-color: #e00;
+ }
+
+ &.jBox-Notice-green .jBox-container:after {
+ background-color: #6c0;
+ }
+
+ &.jBox-Notice-blue .jBox-container:after {
+ background-color: #49d;
+ }
+
+ &.jBox-Notice-yellow .jBox-container:after {
+ background-color: #fb0;
+ }
+
+ .jBox-countdown {
+ left: 8px;
+ border-radius: 0 4px 0 0;
+ }
+}
diff --git a/src/scss/themes/jBox.TooltipBorder.scss b/src/scss/themes/jBox.TooltipBorder.scss
new file mode 100755
index 0000000..94251ae
--- /dev/null
+++ b/src/scss/themes/jBox.TooltipBorder.scss
@@ -0,0 +1,39 @@
+// jBox theme: TooltipBorder
+
+.jBox-TooltipBorder {
+ .jBox-container,
+ .jBox-pointer:after {
+ border: 2px solid #49d;
+ }
+
+ .jBox-pointer:after {
+ width: 22px;
+ height: 22px;
+ }
+
+ .jBox-pointer-top,
+ .jBox-pointer-bottom {
+ width: 34px;
+ height: 13px;
+
+ &:after {
+ left: 6px;
+ }
+ }
+
+ .jBox-pointer-left,
+ .jBox-pointer-right {
+ width: 13px;
+ height: 34px;
+
+ &:after {
+ top: 6px;
+ }
+ }
+
+ &.jBox-closeButton-box:before {
+ width: 28px;
+ height: 28px;
+ background: #49d;
+ }
+}
diff --git a/src/scss/themes/jBox.TooltipBorderThick.scss b/src/scss/themes/jBox.TooltipBorderThick.scss
new file mode 100755
index 0000000..8cc766d
--- /dev/null
+++ b/src/scss/themes/jBox.TooltipBorderThick.scss
@@ -0,0 +1,34 @@
+// jBox theme: TooltipBorderThick
+
+.jBox-TooltipBorderThick {
+ .jBox-container {
+ box-shadow: none;
+ border-radius: 8px;
+ border: 4px solid #ccc;
+ }
+
+ .jBox-pointer:after {
+ box-shadow: none;
+ border: 4px solid #ccc;
+ width: 24px;
+ height: 24px;
+ }
+
+ .jBox-pointer-top,
+ .jBox-pointer-bottom {
+ width: 38px;
+ height: 13px;
+ }
+
+ .jBox-pointer-left,
+ .jBox-pointer-right {
+ width: 13px;
+ height: 38px;
+ }
+
+ &.jBox-closeButton-box:before {
+ width: 32px;
+ height: 32px;
+ background: #ccc;
+ }
+}
diff --git a/src/scss/themes/jBox.TooltipDark.scss b/src/scss/themes/jBox.TooltipDark.scss
new file mode 100755
index 0000000..ef2146e
--- /dev/null
+++ b/src/scss/themes/jBox.TooltipDark.scss
@@ -0,0 +1,38 @@
+// jBox theme: TooltipDark
+
+.jBox-TooltipDark {
+ .jBox-container {
+ border-radius: 4px;
+ background: #000;
+ color: #fff;
+ box-shadow: 0 0 6px rgba(0, 0, 0, .4);
+ }
+
+ .jBox-pointer:after {
+ background: #000;
+ }
+
+ .jBox-closeButton {
+ background: #000;
+ }
+
+ &.jBox-closeButton-box {
+ &:before {
+ box-shadow: 0 0 6px rgba(0, 0, 0, .4);
+ }
+
+ .jBox-closeButton {
+ path {
+ fill: #ddd;
+ }
+
+ &:hover path {
+ fill: #fff;
+ }
+
+ &:active path {
+ fill: #bbb;
+ }
+ }
+ }
+}
diff --git a/src/scss/themes/jBox.TooltipError.scss b/src/scss/themes/jBox.TooltipError.scss
new file mode 100755
index 0000000..0a64131
--- /dev/null
+++ b/src/scss/themes/jBox.TooltipError.scss
@@ -0,0 +1,58 @@
+// jBox theme: TooltipError
+
+.jBox-TooltipError {
+ pointer-events: none;
+
+ .jBox-container {
+ border-radius: 2px;
+ background: #d00;
+ color: #fff;
+ font-weight: bold;
+ font-size: 13px;
+ }
+
+ .jBox-content {
+ padding: 0 10px;
+ line-height: 28px;
+ }
+
+ .jBox-pointer {
+ &:after {
+ background: #d00;
+ width: 20px;
+ height: 20px;
+ }
+
+ &-top,
+ &-bottom {
+ width: 22px;
+ height: 8px;
+ }
+
+ &-right,
+ &-left {
+ width: 8px;
+ height: 22px;
+ }
+
+ &-top:after {
+ left: 1px;
+ top: 6px;
+ }
+
+ &-right:after {
+ top: 1px;
+ right: 6px;
+ }
+
+ &-bottom:after {
+ left: 1px;
+ bottom: 6px;
+ }
+
+ &-left:after {
+ top: 1px;
+ left: 6px;
+ }
+ }
+}
diff --git a/src/scss/themes/jBox.TooltipSmall.scss b/src/scss/themes/jBox.TooltipSmall.scss
new file mode 100755
index 0000000..921ec42
--- /dev/null
+++ b/src/scss/themes/jBox.TooltipSmall.scss
@@ -0,0 +1,53 @@
+// Box theme: TooltipSmall
+
+.jBox-TooltipSmall {
+ pointer-events: none;
+
+ .jBox-container {
+ border-radius: 2px;
+ }
+
+ .jBox-content {
+ padding: 0 10px;
+ line-height: 28px;
+ }
+
+ .jBox-pointer {
+ &:after {
+ width: 20px;
+ height: 20px;
+ }
+
+ &-top,
+ &-bottom {
+ width: 22px;
+ height: 8px;
+ }
+
+ &-right,
+ &-left {
+ width: 8px;
+ height: 22px;
+ }
+
+ &-top:after {
+ left: 1px;
+ top: 6px;
+ }
+
+ &-right:after {
+ top: 1px;
+ right: 6px;
+ }
+
+ &-bottom:after {
+ left: 1px;
+ bottom: 6px;
+ }
+
+ &-left:after {
+ top: 1px;
+ left: 6px;
+ }
+ }
+}
diff --git a/src/scss/themes/jBox.TooltipSmallGray.scss b/src/scss/themes/jBox.TooltipSmallGray.scss
new file mode 100755
index 0000000..1bda1f6
--- /dev/null
+++ b/src/scss/themes/jBox.TooltipSmallGray.scss
@@ -0,0 +1,57 @@
+// jBox theme: TooltipSmallGray
+
+.jBox-TooltipSmallGray {
+ pointer-events: none;
+
+ .jBox-container {
+ font-size: 13px;
+ line-height: 24px;
+ border-radius: 12px;
+ background-image: linear-gradient(to bottom, #fafafa, #f2f2f2);
+ }
+
+ .jBox-content {
+ padding: 0 10px;
+ }
+
+ .jBox-pointer {
+ &:after {
+ width: 20px;
+ height: 20px;
+ }
+
+ &-top,
+ &-bottom {
+ width: 22px;
+ height: 8px;
+ }
+
+ &-left,
+ &-right {
+ width: 8px;
+ height: 22px;
+ }
+
+ &-top:after {
+ background: #fafafa;
+ left: 1px;
+ top: 6px;
+ }
+
+ &-right:after {
+ top: 1px;
+ right: 6px;
+ }
+
+ &-bottom:after {
+ background: #f2f2f2;
+ left: 1px;
+ bottom: 6px;
+ }
+
+ &-left:after {
+ top: 1px;
+ left: 6px;
+ }
+ }
+}
diff --git a/test/assets.test.js b/test/assets.test.js
new file mode 100644
index 0000000..766214f
--- /dev/null
+++ b/test/assets.test.js
@@ -0,0 +1,59 @@
+var fs = require('fs');
+
+// Check if asset exists
+function checkForAsset(path) {
+ var pathFound = true;
+ try {
+ fs.accessSync(path);
+ } catch (e) {
+ pathFound = false;
+ }
+ return pathFound;
+}
+
+// Plugins
+var plugins = [
+ 'Confirm',
+ 'Image',
+ 'Notice'
+];
+
+// Themes
+var themes = [
+ 'NoticeFancy',
+ 'TooltipBorder',
+ 'TooltipBorderThick',
+ 'TooltipDark',
+ 'TooltipError',
+ 'TooltipSmall',
+ 'TooltipSmallGray'
+];
+
+// Check for default files
+for (let filename of ['jBox', 'jBox.all']) {
+ for (let extension of ['.js', '.min.js', '.css', '.min.css']) {
+ test('Asset ' + filename + extension + ' exists', () => {
+ expect(checkForAsset('./dist/' + filename + extension)).toBe(true);
+ });
+ }
+}
+
+// Check for plugin files
+for (let plugin of plugins) {
+ for (let extension of ['.js', '.min.js', '.css', '.min.css']) {
+ let filename = 'jBox.' + plugin;
+ test('Plugin ' + plugin + ': Asset ' + filename + extension + ' exists', () => {
+ expect(checkForAsset('./dist/plugins/' + filename + extension)).toBe(true);
+ });
+ }
+}
+
+// Check for theme files
+for (let theme of themes) {
+ for (let extension of ['.css', '.min.css']) {
+ let filename = 'jBox.' + theme;
+ test('Theme ' + theme + ': Asset ' + filename + extension + ' exists', () => {
+ expect(checkForAsset('./dist/themes/' + filename + extension)).toBe(true);
+ });
+ }
+}
\ No newline at end of file