--- a/src/iconolab/static/iconolab/js/dist/bundle.js Fri Jul 01 11:15:37 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29277 +0,0 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId])
-/******/ return installedModules[moduleId].exports;
-
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ exports: {},
-/******/ id: moduleId,
-/******/ loaded: false
-/******/ };
-
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
-/******/ // Flag the module as loaded
-/******/ module.loaded = true;
-
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-
-
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "";
-
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
- var cutout = __webpack_require__(1);
-
- /* expose jQuery */
- var test = __webpack_require__(19);
-
- /* expose Vue */
- __webpack_require__(21);
-
- var api = {
- initCutoutComponent: function (config) {
- return cutout.init(config);
- }
- };
-
- module.exports = api;
- iconolab = api;
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
-
- var Snap = __webpack_require__(2);
- ShapeResizer = __webpack_require__(3);
- eventEmitter = __webpack_require__(4)({});
-
- /* custom plugin */
- Snap.plugin(function (Snap, Element, Paper, glob) {
- var elproto = Element.prototype;
-
- elproto.toBack = function () {
- this.prependTo(this.paper);
- };
-
- elproto.toFront = function () {
- this.appendTo(this.paper);
- };
- });
-
- Element.prototype.getTransformedXY = function( x,y ) {
- var m = this.transform().globalMatrix;
- return { x: m.x(x,y), y: m.y(x,y) };
- };
-
- var paper = null;
- var mainImage = null;
- var pointData = [];
- var viewBoxBounds = {X: 100, Y:100};
- var config = null;
- var readOnly = false;
- var startPoint = null;
- var drawing_path = null;
- var canDraw = false;
- var rectZone = null;
- var PATH_COLOR = "#ff00ff";
- var STROKE_COLOR = "red";
- var FILL_COLOR = "orange";
-
- var SELECTED_COLOR = "#ffff00";
- var FIRST_NODE_COLOR = "#FF0000";
- var HANDLE_SIZE = 6;
- var isDragged = false;
- var enablePoint = true;
- var pathIsClosed = false;
- var ENABLE_NEW_NODE = true;
- var RECT_MODE ='RECT';
- var drawingMode = RECT_MODE; //free
- var FREE_MODE = 'FREE';
- var availableModes = [RECT_MODE, FREE_MODE];
- var onChangeCallback = null;
-
- var getId = (function () {
- var cpt = 0;
- var defautPrefix = "item_";
- return function (prefix) {
- prefix = (typeof prefix === 'string') ? prefix : defautPrefix;
- cpt = cpt + 1;
- return prefix + cpt;
- }
- }());
-
- var handleRectPath = function (path) {
- if (readOnly) {
- paper.path(path).attr({ stroke:'red', opacity: 0.6});
- return;
- }
-
- var bbBox = Snap.path.getBBox(path);
- rectZone = paper.rect(bbBox.x, bbBox.y, bbBox.width, bbBox.height);
- rectZone.attr({fill: FILL_COLOR, stroke: STROKE_COLOR, opacity: 0.6});
- drawing_path = rectZone;
- canDraw = false;
- pathIsClosed = true;
- ShapeResizer.apply_resize(paper, drawing_path);
- };
-
-
- var handleFreePath = function (path) {
-
- if (readOnly) {
-
- paper.path(path).attr({
- stroke: 'orange',
- fill: 'orange',
- opacity: 0.5,
- });
-
- return;
- }
-
- var pathInfos = Snap.parsePathString(path);
- pathInfos.map(function (pathData) {
- if(pathData[0] !== 'Z') {
- createPoint(paper, pathData[1], pathData[2], pointData);
- } else {
- pathIsClosed = true;
- updatePath(paper, onClosePath);
- }
- });
-
- /* replay the path here */
-
- };
- //transform point to path
- var updatePath = function (paper, updateCallback) {
- var path = "M";
-
- if (pointData.length <= 1) {
- return;
- }
-
- path += pointData[0].x + ',' + pointData[0].y;
-
- for (var i=0; i < pointData.length; i++) {
- if (i == 0) continue;
-
- var pointInfos = pointData[i];
- lPath = "L" + pointInfos.x + "," + pointInfos.y;
- path += " " + lPath;
- }
-
- path += (pathIsClosed) ? " Z": "";
-
- /* remove prev path */
- if (drawing_path) {
- drawing_path.remove();
- }
-
- drawing_path = paper.path(path);
-
- drawing_path.attr({
- stroke: STROKE_COLOR,
- "stroke-width": 3,
- fill: "white",
- opacity: 0.1
- });
-
- /* bring all handler to front */
- pointData.map(function (point) {
- if (point.handler) {
- point.handler.toFront();
- }
- });
-
- if (typeof updateCallback === 'function' && pathIsClosed) {
- updateCallback();
- }
-
- if (!updateCallback && pathIsClosed) {
- applyClosedStyle();
- }
- };
-
- var applyClosedStyle = function () {
- drawing_path.attr({ fill: FILL_COLOR, strokeWidth: 1, opacity:.6 });
- }
-
- var onClosePath = function () {
- ENABLE_NEW_NODE = false;
- applyClosedStyle();
- };
-
-
- var onClickOnHandler = function (point, p, e) {
- //close path
- if (point.isFirst && pointData.length > 2) {
- pathIsClosed = true;
- }
- };
-
- var updatePointPosition = function (newPoint, x, y) {
- var index = pointData.indexOf(newPoint);
- if (index !== -1) {
- pointData[index].x = x;
- pointData[index].y = y;
- return true;
- } else {
- return false;
- }
- };
-
- var clearPreviousPath = function () {
- drawing_path.remove();
- };
-
- var onMoveHandler = function (dx, dy, posX, posY, e) {
- isDragged = true;
- /* update point then update the view */
- var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy];
- this.attr({ transform: transformValue});
- var boxSize = this.getBBox();
-
- var wasUpdated = updatePointPosition(this.data('point'), boxSize.x + (HANDLE_SIZE / 2) , boxSize.y + (HANDLE_SIZE / 2));
-
- if (wasUpdated) {
- updatePath(this.paper);
- }
- }
-
- var bindHandlerEvent = function (point, p) {
- point.handler.click(onClickOnHandler.bind(this, point, p));
- /* -- handler -- */
- point.handler.hover(function () {
- point.handler.attr({fill: 'yellow'});
- }, function () {
- var fillColor = point.isFirst ? FIRST_NODE_COLOR : "";
- point.handler.attr({fill: fillColor});
- });
-
- point.handler.drag(onMoveHandler, function () {
- this.data('origTransform', this.transform().local );
- }, function () {
- if (!isDragged) { return true; }
- isDragged = false;
- enablePoint = false;
- });
- }
-
- var createPointHandler = function (p, point) {
-
- var handleX = point.x - HANDLE_SIZE/2;
- var handleY = point.y - HANDLE_SIZE/2;
-
- handler = p.rect(handleX, handleY, HANDLE_SIZE, HANDLE_SIZE);
-
- point.handler = handler;
- point.handler.data('point', point);
- if (pointData.length === 0) {
- point.isFirst = true;
- }
-
- bindHandlerEvent(point, p);
- point.handler.attr({
- fill: (pointData.length === 0) ? FIRST_NODE_COLOR : "",
- opacity: 0.9,
- stroke: PATH_COLOR
- });
-
- return point;
- }
-
- //create paper
- var createPoint = function (paper, x, y, pointData) {
-
- var point = {x:x, y:y, id: getId()};
-
- if (pathIsClosed) {
- updatePath(paper, onClosePath);
- return;
- }
-
- if (!enablePoint) {
- enablePoint = true;
- return false;
- }
-
- point = createPointHandler(paper, point);
- pointData.push(point);
- updatePath(paper);
- };
-
- var attachRectEvents = function (paper) {
- if (readOnly) { return false; }
-
- var startPosition = {};
- var currentPosition = {};
- /* add resizer */
-
- paper.mousedown(function (e) {
-
- if (drawingMode === FREE_MODE || pathIsClosed) { return; }
- startPosition.x = e.offsetX;
- startPosition.y = e.offsetY;
- canDraw = true;
- });
-
- paper.mousemove(function (e) {
- if (drawingMode === FREE_MODE) { return; }
- if (!canDraw) { return; }
- var x, y;
- currentPosition.x = e.offsetX;
- currentPosition.y = e.offsetY;
-
- if (rectZone) {
- rectZone.remove();
- }
-
- /* bas -> droite */
- var width = Math.abs(currentPosition.x - startPosition.x);
- var height = Math.abs(startPosition.y - currentPosition.y);
-
- if (currentPosition.y > startPosition.y && currentPosition.x > startPosition.x) {
- x = startPosition.x;
- y = startPosition.y;
- }
-
- /* haut -> droite */
- if (currentPosition.y < startPosition.y && currentPosition.x > startPosition.x) {
- x = currentPosition.x - width;
- y = currentPosition.y;
- }
-
- /* haut -> gauche */
- if (currentPosition.y < startPosition.y && currentPosition.x < startPosition.x) {
- x = currentPosition.x;
- y = currentPosition.y;
- }
-
- /* bas -> gauche */
- if (currentPosition.y > startPosition.y && currentPosition.x < startPosition.x) {
- x = currentPosition.x
- y = currentPosition.y - height;
- }
- if(!x || !y) { return; }
-
- rectZone = paper.rect(x, y, width, height);
- rectZone.attr({fill: FILL_COLOR, stroke: STROKE_COLOR, opacity: 0.6});
- });
-
-
- paper.mouseup(function () {
- if ((drawingMode === FREE_MODE) || pathIsClosed || !rectZone) { return false; }
- drawing_path = rectZone;
- ShapeResizer.apply_resize(paper, rectZone);
- canDraw = false;
- pathIsClosed = true;
- });
- };
- var attachPointEvents = function (paper) {
- if (readOnly) { return; }
- paper.click( function(e) {
- if (drawingMode === RECT_MODE) {
- return true;
- }
-
- if (!ENABLE_NEW_NODE) { return true; }
- createPoint(paper, e.offsetX, e.offsetY, pointData);
- });
- };
-
- var API = {
-
- setPath: function (pathString) {
- /* redraw the path */
- var pathInfos = pathString.split(';');
- if( availableModes.indexOf(pathInfos[1]) === -1) {
- /* We assume then it is a free path */
- pathInfos[1] = "FREE";
- }
-
- this.setDrawingMode(pathInfos[1]);
- var pathData = pathInfos[0];
-
- if(!pathData.length) {
- return;
- }
- /* deal with path nomalization x = ImageWith/MaxXBound*/
- var xRatio = mainImage.width() / viewBoxBounds.X;
- var yRatio = mainImage.height() / viewBoxBounds.Y;
-
- if(isNaN(xRatio) || isNaN(yRatio)) {
- new Error('Ratio should be a number.');
- }
-
- var transformMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
- path = Snap.path.map(pathData, transformMatrix).toString();
-
- /* always close path */
- if (path.search(/[z|Z]/gi) === -1 ) {
- path += "Z";
- }
- if (pathInfos.length >= 2) {
- if (pathInfos[1] === RECT_MODE) {
- handleRectPath(path);
- }
-
- if (pathInfos[1] === FREE_MODE) {
- handleFreePath(path);
- }
- }
- },
-
- setDrawingMode: function (mode) {
-
- if (availableModes.indexOf(mode) !== -1) {
- drawingMode = mode;
- }
- if (typeof onChangeCallback === "function") {
- onChangeCallback(drawingMode);
- }
-
- this.clear();
- },
-
- clear: function () {
- /* clear previous path, point, handler */
- pointData.map(function (point) {
- if (point.handler) {
- point.handler.remove();
- }
- });
-
- /*clear path is exists*/
- if (drawing_path) {
- drawing_path.remove();
- }
- eventEmitter.emit("cutout:clear");
- pointData = [];
- startPoint = null;
- drawing_path = null;
- isDragged = false;
- enablePoint = true;
- pathIsClosed = false;
- ENABLE_NEW_NODE = true;
- },
-
- getPath: function () {
- /* retourne le chemin */
- /* send path and BBox | implement edit and load path */
- var path = "";
- if (drawing_path) {
- if (drawingMode === RECT_MODE) {
- var bBox = drawing_path.getBBox();
- var transform = drawing_path.transform();
-
- if (!transform.global.length) {
- var shapePath = drawing_path.getBBox().path;
- }
-
- else {
-
- var shapeX = drawing_path.node.getAttribute('x');
- var shapeY = drawing_path.node.getAttribute('y');
-
- var transformMatrix = transform.globalMatrix;
- var fakeShape = paper.rect(transformMatrix.x(shapeX, shapeY),transformMatrix.y(shapeX, shapeY), bBox.width, bBox.height);
- shapePath = fakeShape.getBBox().path;
- fakeShape.remove();
- }
-
- path = Snap.path.toAbsolute(shapePath).toString();
-
- }
- else {
- path = drawing_path.attr('d');
- }
- }
-
- var xRatio = viewBoxBounds.X / mainImage.width();
- var yRatio = viewBoxBounds.Y / mainImage.height();
- if(isNaN(xRatio) || isNaN(yRatio)) {
- new Error('ratio should be a number.');
- }
-
- if (!path.length) {
- path = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
- return path;
- }
-
- var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
- path = Snap.path.map(path, normalizeMatrix).toString();
-
- /* save the type */
- var type = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
- if (path.search(/[z|Z]/gi) === -1) {
- path += " Z";
- }
-
- path += type;
-
- return path;
- }
- };
-
- /* change to a component */
- module.exports = {
-
- init: function(config) {
-
- mainImage = jQuery(config.wrapperId).find('img').eq(0);
- var cutCanvas = jQuery(config.wrapperId).find('.cut-canvas').eq(0);
- var path = jQuery(config.wrapperId).find('.image-path').eq(0);
-
- if (typeof config.onDrawingModeChange === 'function') {
- onChangeCallback = config.onDrawingModeChange;
- }
-
- if (!cutCanvas.length) {
- var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
- jQuery(config.wrapperId).append(cutCanvas);
- }
-
- if (!mainImage) {
- new Error(config.wrapperId + "Can't be found ...");
- }
-
- cutCanvas.css({
- position: 'absolute',
- top: '0px',
- left: '15px',
- marginLeft: 'auto',
- marginRight: 'auto',
- width: mainImage.width(),
- height: mainImage.height(),
- viewBox: '0 0 100 100'
- });
-
- if (typeof config.readOnly === 'boolean' && config.readOnly === true) {
- readOnly = true;
- }
-
- paper = new Snap(cutCanvas.get(0));
-
- if (path.length) {
- jQuery(cutCanvas).append(path);
- API.setPath(path.attr("d"));
- }
-
- attachPointEvents(paper);
- attachRectEvents(paper);
-
- return API;
- },
- };
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_0__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*** IMPORTS FROM imports-loader ***/
- (function() {
- var fix = module.exports=0;
-
- // Snap.svg 0.4.0
- //
- // Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- // build: 2015-04-07
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // ┌────────────────────────────────────────────────────────────┐ \\
- // │ Eve 0.4.2 - JavaScript Events Library │ \\
- // ├────────────────────────────────────────────────────────────┤ \\
- // │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
- // └────────────────────────────────────────────────────────────┘ \\
-
- (function (glob) {
- var version = "0.4.2",
- has = "hasOwnProperty",
- separator = /[\.\/]/,
- comaseparator = /\s*,\s*/,
- wildcard = "*",
- fun = function () {},
- numsort = function (a, b) {
- return a - b;
- },
- current_event,
- stop,
- events = {n: {}},
- firstDefined = function () {
- for (var i = 0, ii = this.length; i < ii; i++) {
- if (typeof this[i] != "undefined") {
- return this[i];
- }
- }
- },
- lastDefined = function () {
- var i = this.length;
- while (--i) {
- if (typeof this[i] != "undefined") {
- return this[i];
- }
- }
- },
- /*\
- * eve
- [ method ]
-
- * Fires event with given `name`, given scope and other parameters.
-
- > Arguments
-
- - name (string) name of the *event*, dot (`.`) or slash (`/`) separated
- - scope (object) context for the event handlers
- - varargs (...) the rest of arguments will be sent to event handlers
-
- = (object) array of returned values from the listeners. Array has two methods `.firstDefined()` and `.lastDefined()` to get first or last not `undefined` value.
- \*/
- eve = function (name, scope) {
- name = String(name);
- var e = events,
- oldstop = stop,
- args = Array.prototype.slice.call(arguments, 2),
- listeners = eve.listeners(name),
- z = 0,
- f = false,
- l,
- indexed = [],
- queue = {},
- out = [],
- ce = current_event,
- errors = [];
- out.firstDefined = firstDefined;
- out.lastDefined = lastDefined;
- current_event = name;
- stop = 0;
- for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) {
- indexed.push(listeners[i].zIndex);
- if (listeners[i].zIndex < 0) {
- queue[listeners[i].zIndex] = listeners[i];
- }
- }
- indexed.sort(numsort);
- while (indexed[z] < 0) {
- l = queue[indexed[z++]];
- out.push(l.apply(scope, args));
- if (stop) {
- stop = oldstop;
- return out;
- }
- }
- for (i = 0; i < ii; i++) {
- l = listeners[i];
- if ("zIndex" in l) {
- if (l.zIndex == indexed[z]) {
- out.push(l.apply(scope, args));
- if (stop) {
- break;
- }
- do {
- z++;
- l = queue[indexed[z]];
- l && out.push(l.apply(scope, args));
- if (stop) {
- break;
- }
- } while (l)
- } else {
- queue[l.zIndex] = l;
- }
- } else {
- out.push(l.apply(scope, args));
- if (stop) {
- break;
- }
- }
- }
- stop = oldstop;
- current_event = ce;
- return out;
- };
- // Undocumented. Debug only.
- eve._events = events;
- /*\
- * eve.listeners
- [ method ]
-
- * Internal method which gives you array of all event handlers that will be triggered by the given `name`.
-
- > Arguments
-
- - name (string) name of the event, dot (`.`) or slash (`/`) separated
-
- = (array) array of event handlers
- \*/
- eve.listeners = function (name) {
- var names = name.split(separator),
- e = events,
- item,
- items,
- k,
- i,
- ii,
- j,
- jj,
- nes,
- es = [e],
- out = [];
- for (i = 0, ii = names.length; i < ii; i++) {
- nes = [];
- for (j = 0, jj = es.length; j < jj; j++) {
- e = es[j].n;
- items = [e[names[i]], e[wildcard]];
- k = 2;
- while (k--) {
- item = items[k];
- if (item) {
- nes.push(item);
- out = out.concat(item.f || []);
- }
- }
- }
- es = nes;
- }
- return out;
- };
-
- /*\
- * eve.on
- [ method ]
- **
- * Binds given event handler with a given name. You can use wildcards “`*`” for the names:
- | eve.on("*.under.*", f);
- | eve("mouse.under.floor"); // triggers f
- * Use @eve to trigger the listener.
- **
- > Arguments
- **
- - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
- - f (function) event handler function
- **
- = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment.
- > Example:
- | eve.on("mouse", eatIt)(2);
- | eve.on("mouse", scream);
- | eve.on("mouse", catchIt)(1);
- * This will ensure that `catchIt` function will be called before `eatIt`.
- *
- * If you want to put your handler before non-indexed handlers, specify a negative value.
- * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.
- \*/
- eve.on = function (name, f) {
- name = String(name);
- if (typeof f != "function") {
- return function () {};
- }
- var names = name.split(comaseparator);
- for (var i = 0, ii = names.length; i < ii; i++) {
- (function (name) {
- var names = name.split(separator),
- e = events,
- exist;
- for (var i = 0, ii = names.length; i < ii; i++) {
- e = e.n;
- e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});
- }
- e.f = e.f || [];
- for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {
- exist = true;
- break;
- }
- !exist && e.f.push(f);
- }(names[i]));
- }
- return function (zIndex) {
- if (+zIndex == +zIndex) {
- f.zIndex = +zIndex;
- }
- };
- };
- /*\
- * eve.f
- [ method ]
- **
- * Returns function that will fire given event with optional arguments.
- * Arguments that will be passed to the result function will be also
- * concated to the list of final arguments.
- | el.onclick = eve.f("click", 1, 2);
- | eve.on("click", function (a, b, c) {
- | console.log(a, b, c); // 1, 2, [event object]
- | });
- > Arguments
- - event (string) event name
- - varargs (…) and any other arguments
- = (function) possible event handler function
- \*/
- eve.f = function (event) {
- var attrs = [].slice.call(arguments, 1);
- return function () {
- eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));
- };
- };
- /*\
- * eve.stop
- [ method ]
- **
- * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.
- \*/
- eve.stop = function () {
- stop = 1;
- };
- /*\
- * eve.nt
- [ method ]
- **
- * Could be used inside event handler to figure out actual name of the event.
- **
- > Arguments
- **
- - subname (string) #optional subname of the event
- **
- = (string) name of the event, if `subname` is not specified
- * or
- = (boolean) `true`, if current event’s name contains `subname`
- \*/
- eve.nt = function (subname) {
- if (subname) {
- return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
- }
- return current_event;
- };
- /*\
- * eve.nts
- [ method ]
- **
- * Could be used inside event handler to figure out actual name of the event.
- **
- **
- = (array) names of the event
- \*/
- eve.nts = function () {
- return current_event.split(separator);
- };
- /*\
- * eve.off
- [ method ]
- **
- * Removes given function from the list of event listeners assigned to given name.
- * If no arguments specified all the events will be cleared.
- **
- > Arguments
- **
- - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
- - f (function) event handler function
- \*/
- /*\
- * eve.unbind
- [ method ]
- **
- * See @eve.off
- \*/
- eve.off = eve.unbind = function (name, f) {
- if (!name) {
- eve._events = events = {n: {}};
- return;
- }
- var names = name.split(comaseparator);
- if (names.length > 1) {
- for (var i = 0, ii = names.length; i < ii; i++) {
- eve.off(names[i], f);
- }
- return;
- }
- names = name.split(separator);
- var e,
- key,
- splice,
- i, ii, j, jj,
- cur = [events];
- for (i = 0, ii = names.length; i < ii; i++) {
- for (j = 0; j < cur.length; j += splice.length - 2) {
- splice = [j, 1];
- e = cur[j].n;
- if (names[i] != wildcard) {
- if (e[names[i]]) {
- splice.push(e[names[i]]);
- }
- } else {
- for (key in e) if (e[has](key)) {
- splice.push(e[key]);
- }
- }
- cur.splice.apply(cur, splice);
- }
- }
- for (i = 0, ii = cur.length; i < ii; i++) {
- e = cur[i];
- while (e.n) {
- if (f) {
- if (e.f) {
- for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {
- e.f.splice(j, 1);
- break;
- }
- !e.f.length && delete e.f;
- }
- for (key in e.n) if (e.n[has](key) && e.n[key].f) {
- var funcs = e.n[key].f;
- for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {
- funcs.splice(j, 1);
- break;
- }
- !funcs.length && delete e.n[key].f;
- }
- } else {
- delete e.f;
- for (key in e.n) if (e.n[has](key) && e.n[key].f) {
- delete e.n[key].f;
- }
- }
- e = e.n;
- }
- }
- };
- /*\
- * eve.once
- [ method ]
- **
- * Binds given event handler with a given name to only run once then unbind itself.
- | eve.once("login", f);
- | eve("login"); // triggers f
- | eve("login"); // no listeners
- * Use @eve to trigger the listener.
- **
- > Arguments
- **
- - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
- - f (function) event handler function
- **
- = (function) same return function as @eve.on
- \*/
- eve.once = function (name, f) {
- var f2 = function () {
- eve.unbind(name, f2);
- return f.apply(this, arguments);
- };
- return eve.on(name, f2);
- };
- /*\
- * eve.version
- [ property (string) ]
- **
- * Current version of the library.
- \*/
- eve.version = version;
- eve.toString = function () {
- return "You are running Eve " + version;
- };
- (typeof module != "undefined" && module.exports) ? (module.exports = eve) : ( true ? (!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_LOCAL_MODULE_0__ = (function() { return eve; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)))) : (glob.eve = eve));
- })(this);
-
- (function (glob, factory) {
- // AMD support
- if (true) {
- // Define as an anonymous module
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_0__], __WEBPACK_AMD_DEFINE_RESULT__ = function (eve) {
- return factory(glob, eve);
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- } else if (typeof exports != 'undefined') {
- // Next for Node.js or CommonJS
- var eve = require('eve');
- module.exports = factory(glob, eve);
- } else {
- // Browser globals (glob is window)
- // Snap adds itself to window
- factory(glob, glob.eve);
- }
- }(window || this, function (window, eve) {
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- var mina = (function (eve) {
- var animations = {},
- requestAnimFrame = window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function (callback) {
- setTimeout(callback, 16);
- },
- isArray = Array.isArray || function (a) {
- return a instanceof Array ||
- Object.prototype.toString.call(a) == "[object Array]";
- },
- idgen = 0,
- idprefix = "M" + (+new Date).toString(36),
- ID = function () {
- return idprefix + (idgen++).toString(36);
- },
- diff = function (a, b, A, B) {
- if (isArray(a)) {
- res = [];
- for (var i = 0, ii = a.length; i < ii; i++) {
- res[i] = diff(a[i], b, A[i], B);
- }
- return res;
- }
- var dif = (A - a) / (B - b);
- return function (bb) {
- return a + dif * (bb - b);
- };
- },
- timer = Date.now || function () {
- return +new Date;
- },
- sta = function (val) {
- var a = this;
- if (val == null) {
- return a.s;
- }
- var ds = a.s - val;
- a.b += a.dur * ds;
- a.B += a.dur * ds;
- a.s = val;
- },
- speed = function (val) {
- var a = this;
- if (val == null) {
- return a.spd;
- }
- a.spd = val;
- },
- duration = function (val) {
- var a = this;
- if (val == null) {
- return a.dur;
- }
- a.s = a.s * val / a.dur;
- a.dur = val;
- },
- stopit = function () {
- var a = this;
- delete animations[a.id];
- a.update();
- eve("mina.stop." + a.id, a);
- },
- pause = function () {
- var a = this;
- if (a.pdif) {
- return;
- }
- delete animations[a.id];
- a.update();
- a.pdif = a.get() - a.b;
- },
- resume = function () {
- var a = this;
- if (!a.pdif) {
- return;
- }
- a.b = a.get() - a.pdif;
- delete a.pdif;
- animations[a.id] = a;
- },
- update = function () {
- var a = this,
- res;
- if (isArray(a.start)) {
- res = [];
- for (var j = 0, jj = a.start.length; j < jj; j++) {
- res[j] = +a.start[j] +
- (a.end[j] - a.start[j]) * a.easing(a.s);
- }
- } else {
- res = +a.start + (a.end - a.start) * a.easing(a.s);
- }
- a.set(res);
- },
- frame = function () {
- var len = 0;
- for (var i in animations) if (animations.hasOwnProperty(i)) {
- var a = animations[i],
- b = a.get(),
- res;
- len++;
- a.s = (b - a.b) / (a.dur / a.spd);
- if (a.s >= 1) {
- delete animations[i];
- a.s = 1;
- len--;
- (function (a) {
- setTimeout(function () {
- eve("mina.finish." + a.id, a);
- });
- }(a));
- }
- a.update();
- }
- len && requestAnimFrame(frame);
- },
- /*\
- * mina
- [ method ]
- **
- * Generic animation of numbers
- **
- - a (number) start _slave_ number
- - A (number) end _slave_ number
- - b (number) start _master_ number (start time in general case)
- - B (number) end _master_ number (end time in gereal case)
- - get (function) getter of _master_ number (see @mina.time)
- - set (function) setter of _slave_ number
- - easing (function) #optional easing function, default is @mina.linear
- = (object) animation descriptor
- o {
- o id (string) animation id,
- o start (number) start _slave_ number,
- o end (number) end _slave_ number,
- o b (number) start _master_ number,
- o s (number) animation status (0..1),
- o dur (number) animation duration,
- o spd (number) animation speed,
- o get (function) getter of _master_ number (see @mina.time),
- o set (function) setter of _slave_ number,
- o easing (function) easing function, default is @mina.linear,
- o status (function) status getter/setter,
- o speed (function) speed getter/setter,
- o duration (function) duration getter/setter,
- o stop (function) animation stopper
- o pause (function) pauses the animation
- o resume (function) resumes the animation
- o update (function) calles setter with the right value of the animation
- o }
- \*/
- mina = function (a, A, b, B, get, set, easing) {
- var anim = {
- id: ID(),
- start: a,
- end: A,
- b: b,
- s: 0,
- dur: B - b,
- spd: 1,
- get: get,
- set: set,
- easing: easing || mina.linear,
- status: sta,
- speed: speed,
- duration: duration,
- stop: stopit,
- pause: pause,
- resume: resume,
- update: update
- };
- animations[anim.id] = anim;
- var len = 0, i;
- for (i in animations) if (animations.hasOwnProperty(i)) {
- len++;
- if (len == 2) {
- break;
- }
- }
- len == 1 && requestAnimFrame(frame);
- return anim;
- };
- /*\
- * mina.time
- [ method ]
- **
- * Returns the current time. Equivalent to:
- | function () {
- | return (new Date).getTime();
- | }
- \*/
- mina.time = timer;
- /*\
- * mina.getById
- [ method ]
- **
- * Returns an animation by its id
- - id (string) animation's id
- = (object) See @mina
- \*/
- mina.getById = function (id) {
- return animations[id] || null;
- };
-
- /*\
- * mina.linear
- [ method ]
- **
- * Default linear easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.linear = function (n) {
- return n;
- };
- /*\
- * mina.easeout
- [ method ]
- **
- * Easeout easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.easeout = function (n) {
- return Math.pow(n, 1.7);
- };
- /*\
- * mina.easein
- [ method ]
- **
- * Easein easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.easein = function (n) {
- return Math.pow(n, .48);
- };
- /*\
- * mina.easeinout
- [ method ]
- **
- * Easeinout easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.easeinout = function (n) {
- if (n == 1) {
- return 1;
- }
- if (n == 0) {
- return 0;
- }
- var q = .48 - n / 1.04,
- Q = Math.sqrt(.1734 + q * q),
- x = Q - q,
- X = Math.pow(Math.abs(x), 1 / 3) * (x < 0 ? -1 : 1),
- y = -Q - q,
- Y = Math.pow(Math.abs(y), 1 / 3) * (y < 0 ? -1 : 1),
- t = X + Y + .5;
- return (1 - t) * 3 * t * t + t * t * t;
- };
- /*\
- * mina.backin
- [ method ]
- **
- * Backin easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.backin = function (n) {
- if (n == 1) {
- return 1;
- }
- var s = 1.70158;
- return n * n * ((s + 1) * n - s);
- };
- /*\
- * mina.backout
- [ method ]
- **
- * Backout easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.backout = function (n) {
- if (n == 0) {
- return 0;
- }
- n = n - 1;
- var s = 1.70158;
- return n * n * ((s + 1) * n + s) + 1;
- };
- /*\
- * mina.elastic
- [ method ]
- **
- * Elastic easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.elastic = function (n) {
- if (n == !!n) {
- return n;
- }
- return Math.pow(2, -10 * n) * Math.sin((n - .075) *
- (2 * Math.PI) / .3) + 1;
- };
- /*\
- * mina.bounce
- [ method ]
- **
- * Bounce easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.bounce = function (n) {
- var s = 7.5625,
- p = 2.75,
- l;
- if (n < (1 / p)) {
- l = s * n * n;
- } else {
- if (n < (2 / p)) {
- n -= (1.5 / p);
- l = s * n * n + .75;
- } else {
- if (n < (2.5 / p)) {
- n -= (2.25 / p);
- l = s * n * n + .9375;
- } else {
- n -= (2.625 / p);
- l = s * n * n + .984375;
- }
- }
- }
- return l;
- };
- window.mina = mina;
- return mina;
- })(typeof eve == "undefined" ? function () {} : eve);
- // Copyright (c) 2013 - 2015 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- var Snap = (function(root) {
- Snap.version = "0.4.0";
- /*\
- * Snap
- [ method ]
- **
- * Creates a drawing surface or wraps existing SVG element.
- **
- - width (number|string) width of surface
- - height (number|string) height of surface
- * or
- - DOM (SVGElement) element to be wrapped into Snap structure
- * or
- - array (array) array of elements (will return set of elements)
- * or
- - query (string) CSS query selector
- = (object) @Element
- \*/
- function Snap(w, h) {
- if (w) {
- if (w.nodeType) {
- return wrap(w);
- }
- if (is(w, "array") && Snap.set) {
- return Snap.set.apply(Snap, w);
- }
- if (w instanceof Element) {
- return w;
- }
- if (h == null) {
- w = glob.doc.querySelector(String(w));
- return wrap(w);
- }
- }
- w = w == null ? "100%" : w;
- h = h == null ? "100%" : h;
- return new Paper(w, h);
- }
- Snap.toString = function () {
- return "Snap v" + this.version;
- };
- Snap._ = {};
- var glob = {
- win: root.window,
- doc: root.window.document
- };
- Snap._.glob = glob;
- var has = "hasOwnProperty",
- Str = String,
- toFloat = parseFloat,
- toInt = parseInt,
- math = Math,
- mmax = math.max,
- mmin = math.min,
- abs = math.abs,
- pow = math.pow,
- PI = math.PI,
- round = math.round,
- E = "",
- S = " ",
- objectToString = Object.prototype.toString,
- ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
- colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,
- bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
- reURLValue = /^url\(#?([^)]+)\)$/,
- separator = Snap._.separator = /[,\s]+/,
- whitespace = /[\s]/g,
- commaSpaces = /[\s]*,[\s]*/,
- hsrg = {hs: 1, rg: 1},
- pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
- tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
- pathValues = /(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/ig,
- idgen = 0,
- idprefix = "S" + (+new Date).toString(36),
- ID = function (el) {
- return (el && el.type ? el.type : E) + idprefix + (idgen++).toString(36);
- },
- xlink = "http://www.w3.org/1999/xlink",
- xmlns = "http://www.w3.org/2000/svg",
- hub = {},
- URL = Snap.url = function (url) {
- return "url('#" + url + "')";
- };
-
- function $(el, attr) {
- if (attr) {
- if (el == "#text") {
- el = glob.doc.createTextNode(attr.text || attr["#text"] || "");
- }
- if (el == "#comment") {
- el = glob.doc.createComment(attr.text || attr["#text"] || "");
- }
- if (typeof el == "string") {
- el = $(el);
- }
- if (typeof attr == "string") {
- if (el.nodeType == 1) {
- if (attr.substring(0, 6) == "xlink:") {
- return el.getAttributeNS(xlink, attr.substring(6));
- }
- if (attr.substring(0, 4) == "xml:") {
- return el.getAttributeNS(xmlns, attr.substring(4));
- }
- return el.getAttribute(attr);
- } else if (attr == "text") {
- return el.nodeValue;
- } else {
- return null;
- }
- }
- if (el.nodeType == 1) {
- for (var key in attr) if (attr[has](key)) {
- var val = Str(attr[key]);
- if (val) {
- if (key.substring(0, 6) == "xlink:") {
- el.setAttributeNS(xlink, key.substring(6), val);
- } else if (key.substring(0, 4) == "xml:") {
- el.setAttributeNS(xmlns, key.substring(4), val);
- } else {
- el.setAttribute(key, val);
- }
- } else {
- el.removeAttribute(key);
- }
- }
- } else if ("text" in attr) {
- el.nodeValue = attr.text;
- }
- } else {
- el = glob.doc.createElementNS(xmlns, el);
- }
- return el;
- }
- Snap._.$ = $;
- Snap._.id = ID;
- function getAttrs(el) {
- var attrs = el.attributes,
- name,
- out = {};
- for (var i = 0; i < attrs.length; i++) {
- if (attrs[i].namespaceURI == xlink) {
- name = "xlink:";
- } else {
- name = "";
- }
- name += attrs[i].name;
- out[name] = attrs[i].textContent;
- }
- return out;
- }
- function is(o, type) {
- type = Str.prototype.toLowerCase.call(type);
- if (type == "finite") {
- return isFinite(o);
- }
- if (type == "array" &&
- (o instanceof Array || Array.isArray && Array.isArray(o))) {
- return true;
- }
- return (type == "null" && o === null) ||
- (type == typeof o && o !== null) ||
- (type == "object" && o === Object(o)) ||
- objectToString.call(o).slice(8, -1).toLowerCase() == type;
- }
- /*\
- * Snap.format
- [ method ]
- **
- * Replaces construction of type `{<name>}` to the corresponding argument
- **
- - token (string) string to format
- - json (object) object which properties are used as a replacement
- = (string) formatted string
- > Usage
- | // this draws a rectangular shape equivalent to "M10,20h40v50h-40z"
- | paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", {
- | x: 10,
- | y: 20,
- | dim: {
- | width: 40,
- | height: 50,
- | "negative width": -40
- | }
- | }));
- \*/
- Snap.format = (function () {
- var tokenRegex = /\{([^\}]+)\}/g,
- objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties
- replacer = function (all, key, obj) {
- var res = obj;
- key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
- name = name || quotedName;
- if (res) {
- if (name in res) {
- res = res[name];
- }
- typeof res == "function" && isFunc && (res = res());
- }
- });
- res = (res == null || res == obj ? all : res) + "";
- return res;
- };
- return function (str, obj) {
- return Str(str).replace(tokenRegex, function (all, key) {
- return replacer(all, key, obj);
- });
- };
- })();
- function clone(obj) {
- if (typeof obj == "function" || Object(obj) !== obj) {
- return obj;
- }
- var res = new obj.constructor;
- for (var key in obj) if (obj[has](key)) {
- res[key] = clone(obj[key]);
- }
- return res;
- }
- Snap._.clone = clone;
- function repush(array, item) {
- for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
- return array.push(array.splice(i, 1)[0]);
- }
- }
- function cacher(f, scope, postprocessor) {
- function newf() {
- var arg = Array.prototype.slice.call(arguments, 0),
- args = arg.join("\u2400"),
- cache = newf.cache = newf.cache || {},
- count = newf.count = newf.count || [];
- if (cache[has](args)) {
- repush(count, args);
- return postprocessor ? postprocessor(cache[args]) : cache[args];
- }
- count.length >= 1e3 && delete cache[count.shift()];
- count.push(args);
- cache[args] = f.apply(scope, arg);
- return postprocessor ? postprocessor(cache[args]) : cache[args];
- }
- return newf;
- }
- Snap._.cacher = cacher;
- function angle(x1, y1, x2, y2, x3, y3) {
- if (x3 == null) {
- var x = x1 - x2,
- y = y1 - y2;
- if (!x && !y) {
- return 0;
- }
- return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;
- } else {
- return angle(x1, y1, x3, y3) - angle(x2, y2, x3, y3);
- }
- }
- function rad(deg) {
- return deg % 360 * PI / 180;
- }
- function deg(rad) {
- return rad * 180 / PI % 360;
- }
- function x_y() {
- return this.x + S + this.y;
- }
- function x_y_w_h() {
- return this.x + S + this.y + S + this.width + " \xd7 " + this.height;
- }
-
- /*\
- * Snap.rad
- [ method ]
- **
- * Transform angle to radians
- - deg (number) angle in degrees
- = (number) angle in radians
- \*/
- Snap.rad = rad;
- /*\
- * Snap.deg
- [ method ]
- **
- * Transform angle to degrees
- - rad (number) angle in radians
- = (number) angle in degrees
- \*/
- Snap.deg = deg;
- /*\
- * Snap.sin
- [ method ]
- **
- * Equivalent to `Math.sin()` only works with degrees, not radians.
- - angle (number) angle in degrees
- = (number) sin
- \*/
- Snap.sin = function (angle) {
- return math.sin(Snap.rad(angle));
- };
- /*\
- * Snap.tan
- [ method ]
- **
- * Equivalent to `Math.tan()` only works with degrees, not radians.
- - angle (number) angle in degrees
- = (number) tan
- \*/
- Snap.tan = function (angle) {
- return math.tan(Snap.rad(angle));
- };
- /*\
- * Snap.cos
- [ method ]
- **
- * Equivalent to `Math.cos()` only works with degrees, not radians.
- - angle (number) angle in degrees
- = (number) cos
- \*/
- Snap.cos = function (angle) {
- return math.cos(Snap.rad(angle));
- };
- /*\
- * Snap.asin
- [ method ]
- **
- * Equivalent to `Math.asin()` only works with degrees, not radians.
- - num (number) value
- = (number) asin in degrees
- \*/
- Snap.asin = function (num) {
- return Snap.deg(math.asin(num));
- };
- /*\
- * Snap.acos
- [ method ]
- **
- * Equivalent to `Math.acos()` only works with degrees, not radians.
- - num (number) value
- = (number) acos in degrees
- \*/
- Snap.acos = function (num) {
- return Snap.deg(math.acos(num));
- };
- /*\
- * Snap.atan
- [ method ]
- **
- * Equivalent to `Math.atan()` only works with degrees, not radians.
- - num (number) value
- = (number) atan in degrees
- \*/
- Snap.atan = function (num) {
- return Snap.deg(math.atan(num));
- };
- /*\
- * Snap.atan2
- [ method ]
- **
- * Equivalent to `Math.atan2()` only works with degrees, not radians.
- - num (number) value
- = (number) atan2 in degrees
- \*/
- Snap.atan2 = function (num) {
- return Snap.deg(math.atan2(num));
- };
- /*\
- * Snap.angle
- [ method ]
- **
- * Returns an angle between two or three points
- > Parameters
- - x1 (number) x coord of first point
- - y1 (number) y coord of first point
- - x2 (number) x coord of second point
- - y2 (number) y coord of second point
- - x3 (number) #optional x coord of third point
- - y3 (number) #optional y coord of third point
- = (number) angle in degrees
- \*/
- Snap.angle = angle;
- /*\
- * Snap.len
- [ method ]
- **
- * Returns distance between two points
- > Parameters
- - x1 (number) x coord of first point
- - y1 (number) y coord of first point
- - x2 (number) x coord of second point
- - y2 (number) y coord of second point
- = (number) distance
- \*/
- Snap.len = function (x1, y1, x2, y2) {
- return Math.sqrt(Snap.len2(x1, y1, x2, y2));
- };
- /*\
- * Snap.len2
- [ method ]
- **
- * Returns squared distance between two points
- > Parameters
- - x1 (number) x coord of first point
- - y1 (number) y coord of first point
- - x2 (number) x coord of second point
- - y2 (number) y coord of second point
- = (number) distance
- \*/
- Snap.len2 = function (x1, y1, x2, y2) {
- return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
- };
- /*\
- * Snap.closestPoint
- [ method ]
- **
- * Returns closest point to a given one on a given path.
- > Parameters
- - path (Element) path element
- - x (number) x coord of a point
- - y (number) y coord of a point
- = (object) in format
- {
- x (number) x coord of the point on the path
- y (number) y coord of the point on the path
- length (number) length of the path to the point
- distance (number) distance from the given point to the path
- }
- \*/
- // Copied from http://bl.ocks.org/mbostock/8027637
- Snap.closestPoint = function (path, x, y) {
- function distance2(p) {
- var dx = p.x - x,
- dy = p.y - y;
- return dx * dx + dy * dy;
- }
- var pathNode = path.node,
- pathLength = pathNode.getTotalLength(),
- precision = pathLength / pathNode.pathSegList.numberOfItems * .125,
- best,
- bestLength,
- bestDistance = Infinity;
-
- // linear scan for coarse approximation
- for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) {
- if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) {
- best = scan, bestLength = scanLength, bestDistance = scanDistance;
- }
- }
-
- // binary search for precise estimate
- precision *= .5;
- while (precision > .5) {
- var before,
- after,
- beforeLength,
- afterLength,
- beforeDistance,
- afterDistance;
- if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) {
- best = before, bestLength = beforeLength, bestDistance = beforeDistance;
- } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) {
- best = after, bestLength = afterLength, bestDistance = afterDistance;
- } else {
- precision *= .5;
- }
- }
-
- best = {
- x: best.x,
- y: best.y,
- length: bestLength,
- distance: Math.sqrt(bestDistance)
- };
- return best;
- }
- /*\
- * Snap.is
- [ method ]
- **
- * Handy replacement for the `typeof` operator
- - o (…) any object or primitive
- - type (string) name of the type, e.g., `string`, `function`, `number`, etc.
- = (boolean) `true` if given value is of given type
- \*/
- Snap.is = is;
- /*\
- * Snap.snapTo
- [ method ]
- **
- * Snaps given value to given grid
- - values (array|number) given array of values or step of the grid
- - value (number) value to adjust
- - tolerance (number) #optional maximum distance to the target value that would trigger the snap. Default is `10`.
- = (number) adjusted value
- \*/
- Snap.snapTo = function (values, value, tolerance) {
- tolerance = is(tolerance, "finite") ? tolerance : 10;
- if (is(values, "array")) {
- var i = values.length;
- while (i--) if (abs(values[i] - value) <= tolerance) {
- return values[i];
- }
- } else {
- values = +values;
- var rem = value % values;
- if (rem < tolerance) {
- return value - rem;
- }
- if (rem > values - tolerance) {
- return value - rem + values;
- }
- }
- return value;
- };
- // Colour
- /*\
- * Snap.getRGB
- [ method ]
- **
- * Parses color string as RGB object
- - color (string) color string in one of the following formats:
- # <ul>
- # <li>Color name (<code>red</code>, <code>green</code>, <code>cornflowerblue</code>, etc)</li>
- # <li>#••• — shortened HTML color: (<code>#000</code>, <code>#fc0</code>, etc.)</li>
- # <li>#•••••• — full length HTML color: (<code>#000000</code>, <code>#bd2300</code>)</li>
- # <li>rgb(•••, •••, •••) — red, green and blue channels values: (<code>rgb(200, 100, 0)</code>)</li>
- # <li>rgba(•••, •••, •••, •••) — also with opacity</li>
- # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (<code>rgb(100%, 175%, 0%)</code>)</li>
- # <li>rgba(•••%, •••%, •••%, •••%) — also with opacity</li>
- # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (<code>hsb(0.5, 0.25, 1)</code>)</li>
- # <li>hsba(•••, •••, •••, •••) — also with opacity</li>
- # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
- # <li>hsba(•••%, •••%, •••%, •••%) — also with opacity</li>
- # <li>hsl(•••, •••, •••) — hue, saturation and luminosity values: (<code>hsb(0.5, 0.25, 0.5)</code>)</li>
- # <li>hsla(•••, •••, •••, •••) — also with opacity</li>
- # <li>hsl(•••%, •••%, •••%) — same as above, but in %</li>
- # <li>hsla(•••%, •••%, •••%, •••%) — also with opacity</li>
- # </ul>
- * Note that `%` can be used any time: `rgb(20%, 255, 50%)`.
- = (object) RGB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••,
- o error (boolean) true if string can't be parsed
- o }
- \*/
- Snap.getRGB = cacher(function (colour) {
- if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
- return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString};
- }
- if (colour == "none") {
- return {r: -1, g: -1, b: -1, hex: "none", toString: rgbtoString};
- }
- !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
- if (!colour) {
- return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString};
- }
- var res,
- red,
- green,
- blue,
- opacity,
- t,
- values,
- rgb = colour.match(colourRegExp);
- if (rgb) {
- if (rgb[2]) {
- blue = toInt(rgb[2].substring(5), 16);
- green = toInt(rgb[2].substring(3, 5), 16);
- red = toInt(rgb[2].substring(1, 3), 16);
- }
- if (rgb[3]) {
- blue = toInt((t = rgb[3].charAt(3)) + t, 16);
- green = toInt((t = rgb[3].charAt(2)) + t, 16);
- red = toInt((t = rgb[3].charAt(1)) + t, 16);
- }
- if (rgb[4]) {
- values = rgb[4].split(commaSpaces);
- red = toFloat(values[0]);
- values[0].slice(-1) == "%" && (red *= 2.55);
- green = toFloat(values[1]);
- values[1].slice(-1) == "%" && (green *= 2.55);
- blue = toFloat(values[2]);
- values[2].slice(-1) == "%" && (blue *= 2.55);
- rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));
- values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
- }
- if (rgb[5]) {
- values = rgb[5].split(commaSpaces);
- red = toFloat(values[0]);
- values[0].slice(-1) == "%" && (red /= 100);
- green = toFloat(values[1]);
- values[1].slice(-1) == "%" && (green /= 100);
- blue = toFloat(values[2]);
- values[2].slice(-1) == "%" && (blue /= 100);
- (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
- rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));
- values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
- return Snap.hsb2rgb(red, green, blue, opacity);
- }
- if (rgb[6]) {
- values = rgb[6].split(commaSpaces);
- red = toFloat(values[0]);
- values[0].slice(-1) == "%" && (red /= 100);
- green = toFloat(values[1]);
- values[1].slice(-1) == "%" && (green /= 100);
- blue = toFloat(values[2]);
- values[2].slice(-1) == "%" && (blue /= 100);
- (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
- rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));
- values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
- return Snap.hsl2rgb(red, green, blue, opacity);
- }
- red = mmin(math.round(red), 255);
- green = mmin(math.round(green), 255);
- blue = mmin(math.round(blue), 255);
- opacity = mmin(mmax(opacity, 0), 1);
- rgb = {r: red, g: green, b: blue, toString: rgbtoString};
- rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
- rgb.opacity = is(opacity, "finite") ? opacity : 1;
- return rgb;
- }
- return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString};
- }, Snap);
- /*\
- * Snap.hsb
- [ method ]
- **
- * Converts HSB values to a hex representation of the color
- - h (number) hue
- - s (number) saturation
- - b (number) value or brightness
- = (string) hex representation of the color
- \*/
- Snap.hsb = cacher(function (h, s, b) {
- return Snap.hsb2rgb(h, s, b).hex;
- });
- /*\
- * Snap.hsl
- [ method ]
- **
- * Converts HSL values to a hex representation of the color
- - h (number) hue
- - s (number) saturation
- - l (number) luminosity
- = (string) hex representation of the color
- \*/
- Snap.hsl = cacher(function (h, s, l) {
- return Snap.hsl2rgb(h, s, l).hex;
- });
- /*\
- * Snap.rgb
- [ method ]
- **
- * Converts RGB values to a hex representation of the color
- - r (number) red
- - g (number) green
- - b (number) blue
- = (string) hex representation of the color
- \*/
- Snap.rgb = cacher(function (r, g, b, o) {
- if (is(o, "finite")) {
- var round = math.round;
- return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")";
- }
- return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
- });
- var toHex = function (color) {
- var i = glob.doc.getElementsByTagName("head")[0] || glob.doc.getElementsByTagName("svg")[0],
- red = "rgb(255, 0, 0)";
- toHex = cacher(function (color) {
- if (color.toLowerCase() == "red") {
- return red;
- }
- i.style.color = red;
- i.style.color = color;
- var out = glob.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
- return out == red ? null : out;
- });
- return toHex(color);
- },
- hsbtoString = function () {
- return "hsb(" + [this.h, this.s, this.b] + ")";
- },
- hsltoString = function () {
- return "hsl(" + [this.h, this.s, this.l] + ")";
- },
- rgbtoString = function () {
- return this.opacity == 1 || this.opacity == null ?
- this.hex :
- "rgba(" + [this.r, this.g, this.b, this.opacity] + ")";
- },
- prepareRGB = function (r, g, b) {
- if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) {
- b = r.b;
- g = r.g;
- r = r.r;
- }
- if (g == null && is(r, string)) {
- var clr = Snap.getRGB(r);
- r = clr.r;
- g = clr.g;
- b = clr.b;
- }
- if (r > 1 || g > 1 || b > 1) {
- r /= 255;
- g /= 255;
- b /= 255;
- }
-
- return [r, g, b];
- },
- packageRGB = function (r, g, b, o) {
- r = math.round(r * 255);
- g = math.round(g * 255);
- b = math.round(b * 255);
- var rgb = {
- r: r,
- g: g,
- b: b,
- opacity: is(o, "finite") ? o : 1,
- hex: Snap.rgb(r, g, b),
- toString: rgbtoString
- };
- is(o, "finite") && (rgb.opacity = o);
- return rgb;
- };
- /*\
- * Snap.color
- [ method ]
- **
- * Parses the color string and returns an object featuring the color's component values
- - clr (string) color string in one of the supported formats (see @Snap.getRGB)
- = (object) Combined RGB/HSB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••,
- o error (boolean) `true` if string can't be parsed,
- o h (number) hue,
- o s (number) saturation,
- o v (number) value (brightness),
- o l (number) lightness
- o }
- \*/
- Snap.color = function (clr) {
- var rgb;
- if (is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
- rgb = Snap.hsb2rgb(clr);
- clr.r = rgb.r;
- clr.g = rgb.g;
- clr.b = rgb.b;
- clr.opacity = 1;
- clr.hex = rgb.hex;
- } else if (is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) {
- rgb = Snap.hsl2rgb(clr);
- clr.r = rgb.r;
- clr.g = rgb.g;
- clr.b = rgb.b;
- clr.opacity = 1;
- clr.hex = rgb.hex;
- } else {
- if (is(clr, "string")) {
- clr = Snap.getRGB(clr);
- }
- if (is(clr, "object") && "r" in clr && "g" in clr && "b" in clr && !("error" in clr)) {
- rgb = Snap.rgb2hsl(clr);
- clr.h = rgb.h;
- clr.s = rgb.s;
- clr.l = rgb.l;
- rgb = Snap.rgb2hsb(clr);
- clr.v = rgb.b;
- } else {
- clr = {hex: "none"};
- clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;
- clr.error = 1;
- }
- }
- clr.toString = rgbtoString;
- return clr;
- };
- /*\
- * Snap.hsb2rgb
- [ method ]
- **
- * Converts HSB values to an RGB object
- - h (number) hue
- - s (number) saturation
- - v (number) value or brightness
- = (object) RGB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••
- o }
- \*/
- Snap.hsb2rgb = function (h, s, v, o) {
- if (is(h, "object") && "h" in h && "s" in h && "b" in h) {
- v = h.b;
- s = h.s;
- o = h.o;
- h = h.h;
- }
- h *= 360;
- var R, G, B, X, C;
- h = (h % 360) / 60;
- C = v * s;
- X = C * (1 - abs(h % 2 - 1));
- R = G = B = v - C;
-
- h = ~~h;
- R += [C, X, 0, 0, X, C][h];
- G += [X, C, C, X, 0, 0][h];
- B += [0, 0, X, C, C, X][h];
- return packageRGB(R, G, B, o);
- };
- /*\
- * Snap.hsl2rgb
- [ method ]
- **
- * Converts HSL values to an RGB object
- - h (number) hue
- - s (number) saturation
- - l (number) luminosity
- = (object) RGB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••
- o }
- \*/
- Snap.hsl2rgb = function (h, s, l, o) {
- if (is(h, "object") && "h" in h && "s" in h && "l" in h) {
- l = h.l;
- s = h.s;
- h = h.h;
- }
- if (h > 1 || s > 1 || l > 1) {
- h /= 360;
- s /= 100;
- l /= 100;
- }
- h *= 360;
- var R, G, B, X, C;
- h = (h % 360) / 60;
- C = 2 * s * (l < .5 ? l : 1 - l);
- X = C * (1 - abs(h % 2 - 1));
- R = G = B = l - C / 2;
-
- h = ~~h;
- R += [C, X, 0, 0, X, C][h];
- G += [X, C, C, X, 0, 0][h];
- B += [0, 0, X, C, C, X][h];
- return packageRGB(R, G, B, o);
- };
- /*\
- * Snap.rgb2hsb
- [ method ]
- **
- * Converts RGB values to an HSB object
- - r (number) red
- - g (number) green
- - b (number) blue
- = (object) HSB object in the following format:
- o {
- o h (number) hue,
- o s (number) saturation,
- o b (number) brightness
- o }
- \*/
- Snap.rgb2hsb = function (r, g, b) {
- b = prepareRGB(r, g, b);
- r = b[0];
- g = b[1];
- b = b[2];
-
- var H, S, V, C;
- V = mmax(r, g, b);
- C = V - mmin(r, g, b);
- H = (C == 0 ? null :
- V == r ? (g - b) / C :
- V == g ? (b - r) / C + 2 :
- (r - g) / C + 4
- );
- H = ((H + 360) % 6) * 60 / 360;
- S = C == 0 ? 0 : C / V;
- return {h: H, s: S, b: V, toString: hsbtoString};
- };
- /*\
- * Snap.rgb2hsl
- [ method ]
- **
- * Converts RGB values to an HSL object
- - r (number) red
- - g (number) green
- - b (number) blue
- = (object) HSL object in the following format:
- o {
- o h (number) hue,
- o s (number) saturation,
- o l (number) luminosity
- o }
- \*/
- Snap.rgb2hsl = function (r, g, b) {
- b = prepareRGB(r, g, b);
- r = b[0];
- g = b[1];
- b = b[2];
-
- var H, S, L, M, m, C;
- M = mmax(r, g, b);
- m = mmin(r, g, b);
- C = M - m;
- H = (C == 0 ? null :
- M == r ? (g - b) / C :
- M == g ? (b - r) / C + 2 :
- (r - g) / C + 4);
- H = ((H + 360) % 6) * 60 / 360;
- L = (M + m) / 2;
- S = (C == 0 ? 0 :
- L < .5 ? C / (2 * L) :
- C / (2 - 2 * L));
- return {h: H, s: S, l: L, toString: hsltoString};
- };
-
- // Transformations
- /*\
- * Snap.parsePathString
- [ method ]
- **
- * Utility method
- **
- * Parses given path string into an array of arrays of path segments
- - pathString (string|array) path string or array of segments (in the last case it is returned straight away)
- = (array) array of segments
- \*/
- Snap.parsePathString = function (pathString) {
- if (!pathString) {
- return null;
- }
- var pth = Snap.path(pathString);
- if (pth.arr) {
- return Snap.path.clone(pth.arr);
- }
-
- var paramCounts = {a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0},
- data = [];
- if (is(pathString, "array") && is(pathString[0], "array")) { // rough assumption
- data = Snap.path.clone(pathString);
- }
- if (!data.length) {
- Str(pathString).replace(pathCommand, function (a, b, c) {
- var params = [],
- name = b.toLowerCase();
- c.replace(pathValues, function (a, b) {
- b && params.push(+b);
- });
- if (name == "m" && params.length > 2) {
- data.push([b].concat(params.splice(0, 2)));
- name = "l";
- b = b == "m" ? "l" : "L";
- }
- if (name == "o" && params.length == 1) {
- data.push([b, params[0]]);
- }
- if (name == "r") {
- data.push([b].concat(params));
- } else while (params.length >= paramCounts[name]) {
- data.push([b].concat(params.splice(0, paramCounts[name])));
- if (!paramCounts[name]) {
- break;
- }
- }
- });
- }
- data.toString = Snap.path.toString;
- pth.arr = Snap.path.clone(data);
- return data;
- };
- /*\
- * Snap.parseTransformString
- [ method ]
- **
- * Utility method
- **
- * Parses given transform string into an array of transformations
- - TString (string|array) transform string or array of transformations (in the last case it is returned straight away)
- = (array) array of transformations
- \*/
- var parseTransformString = Snap.parseTransformString = function (TString) {
- if (!TString) {
- return null;
- }
- var paramCounts = {r: 3, s: 4, t: 2, m: 6},
- data = [];
- if (is(TString, "array") && is(TString[0], "array")) { // rough assumption
- data = Snap.path.clone(TString);
- }
- if (!data.length) {
- Str(TString).replace(tCommand, function (a, b, c) {
- var params = [],
- name = b.toLowerCase();
- c.replace(pathValues, function (a, b) {
- b && params.push(+b);
- });
- data.push([b].concat(params));
- });
- }
- data.toString = Snap.path.toString;
- return data;
- };
- function svgTransform2string(tstr) {
- var res = [];
- tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function (all, name, params) {
- params = params.split(/\s*,\s*|\s+/);
- if (name == "rotate" && params.length == 1) {
- params.push(0, 0);
- }
- if (name == "scale") {
- if (params.length > 2) {
- params = params.slice(0, 2);
- } else if (params.length == 2) {
- params.push(0, 0);
- }
- if (params.length == 1) {
- params.push(params[0], 0, 0);
- }
- }
- if (name == "skewX") {
- res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]);
- } else if (name == "skewY") {
- res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]);
- } else {
- res.push([name.charAt(0)].concat(params));
- }
- return all;
- });
- return res;
- }
- Snap._.svgTransform2string = svgTransform2string;
- Snap._.rgTransform = /^[a-z][\s]*-?\.?\d/i;
- function transform2matrix(tstr, bbox) {
- var tdata = parseTransformString(tstr),
- m = new Snap.Matrix;
- if (tdata) {
- for (var i = 0, ii = tdata.length; i < ii; i++) {
- var t = tdata[i],
- tlen = t.length,
- command = Str(t[0]).toLowerCase(),
- absolute = t[0] != command,
- inver = absolute ? m.invert() : 0,
- x1,
- y1,
- x2,
- y2,
- bb;
- if (command == "t" && tlen == 2){
- m.translate(t[1], 0);
- } else if (command == "t" && tlen == 3) {
- if (absolute) {
- x1 = inver.x(0, 0);
- y1 = inver.y(0, 0);
- x2 = inver.x(t[1], t[2]);
- y2 = inver.y(t[1], t[2]);
- m.translate(x2 - x1, y2 - y1);
- } else {
- m.translate(t[1], t[2]);
- }
- } else if (command == "r") {
- if (tlen == 2) {
- bb = bb || bbox;
- m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);
- } else if (tlen == 4) {
- if (absolute) {
- x2 = inver.x(t[2], t[3]);
- y2 = inver.y(t[2], t[3]);
- m.rotate(t[1], x2, y2);
- } else {
- m.rotate(t[1], t[2], t[3]);
- }
- }
- } else if (command == "s") {
- if (tlen == 2 || tlen == 3) {
- bb = bb || bbox;
- m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);
- } else if (tlen == 4) {
- if (absolute) {
- x2 = inver.x(t[2], t[3]);
- y2 = inver.y(t[2], t[3]);
- m.scale(t[1], t[1], x2, y2);
- } else {
- m.scale(t[1], t[1], t[2], t[3]);
- }
- } else if (tlen == 5) {
- if (absolute) {
- x2 = inver.x(t[3], t[4]);
- y2 = inver.y(t[3], t[4]);
- m.scale(t[1], t[2], x2, y2);
- } else {
- m.scale(t[1], t[2], t[3], t[4]);
- }
- }
- } else if (command == "m" && tlen == 7) {
- m.add(t[1], t[2], t[3], t[4], t[5], t[6]);
- }
- }
- }
- return m;
- }
- Snap._.transform2matrix = transform2matrix;
- Snap._unit2px = unit2px;
- var contains = glob.doc.contains || glob.doc.compareDocumentPosition ?
- function (a, b) {
- var adown = a.nodeType == 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a == bup || !!(bup && bup.nodeType == 1 && (
- adown.contains ?
- adown.contains(bup) :
- a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
- ));
- } :
- function (a, b) {
- if (b) {
- while (b) {
- b = b.parentNode;
- if (b == a) {
- return true;
- }
- }
- }
- return false;
- };
- function getSomeDefs(el) {
- var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) ||
- (el.node.parentNode && wrap(el.node.parentNode)) ||
- Snap.select("svg") ||
- Snap(0, 0),
- pdefs = p.select("defs"),
- defs = pdefs == null ? false : pdefs.node;
- if (!defs) {
- defs = make("defs", p.node).node;
- }
- return defs;
- }
- function getSomeSVG(el) {
- return el.node.ownerSVGElement && wrap(el.node.ownerSVGElement) || Snap.select("svg");
- }
- Snap._.getSomeDefs = getSomeDefs;
- Snap._.getSomeSVG = getSomeSVG;
- function unit2px(el, name, value) {
- var svg = getSomeSVG(el).node,
- out = {},
- mgr = svg.querySelector(".svg---mgr");
- if (!mgr) {
- mgr = $("rect");
- $(mgr, {x: -9e9, y: -9e9, width: 10, height: 10, "class": "svg---mgr", fill: "none"});
- svg.appendChild(mgr);
- }
- function getW(val) {
- if (val == null) {
- return E;
- }
- if (val == +val) {
- return val;
- }
- $(mgr, {width: val});
- try {
- return mgr.getBBox().width;
- } catch (e) {
- return 0;
- }
- }
- function getH(val) {
- if (val == null) {
- return E;
- }
- if (val == +val) {
- return val;
- }
- $(mgr, {height: val});
- try {
- return mgr.getBBox().height;
- } catch (e) {
- return 0;
- }
- }
- function set(nam, f) {
- if (name == null) {
- out[nam] = f(el.attr(nam) || 0);
- } else if (nam == name) {
- out = f(value == null ? el.attr(nam) || 0 : value);
- }
- }
- switch (el.type) {
- case "rect":
- set("rx", getW);
- set("ry", getH);
- case "image":
- set("width", getW);
- set("height", getH);
- case "text":
- set("x", getW);
- set("y", getH);
- break;
- case "circle":
- set("cx", getW);
- set("cy", getH);
- set("r", getW);
- break;
- case "ellipse":
- set("cx", getW);
- set("cy", getH);
- set("rx", getW);
- set("ry", getH);
- break;
- case "line":
- set("x1", getW);
- set("x2", getW);
- set("y1", getH);
- set("y2", getH);
- break;
- case "marker":
- set("refX", getW);
- set("markerWidth", getW);
- set("refY", getH);
- set("markerHeight", getH);
- break;
- case "radialGradient":
- set("fx", getW);
- set("fy", getH);
- break;
- case "tspan":
- set("dx", getW);
- set("dy", getH);
- break;
- default:
- set(name, getW);
- }
- svg.removeChild(mgr);
- return out;
- }
- /*\
- * Snap.select
- [ method ]
- **
- * Wraps a DOM element specified by CSS selector as @Element
- - query (string) CSS selector of the element
- = (Element) the current element
- \*/
- Snap.select = function (query) {
- query = Str(query).replace(/([^\\]):/g, "$1\\:");
- return wrap(glob.doc.querySelector(query));
- };
- /*\
- * Snap.selectAll
- [ method ]
- **
- * Wraps DOM elements specified by CSS selector as set or array of @Element
- - query (string) CSS selector of the element
- = (Element) the current element
- \*/
- Snap.selectAll = function (query) {
- var nodelist = glob.doc.querySelectorAll(query),
- set = (Snap.set || Array)();
- for (var i = 0; i < nodelist.length; i++) {
- set.push(wrap(nodelist[i]));
- }
- return set;
- };
-
- function add2group(list) {
- if (!is(list, "array")) {
- list = Array.prototype.slice.call(arguments, 0);
- }
- var i = 0,
- j = 0,
- node = this.node;
- while (this[i]) delete this[i++];
- for (i = 0; i < list.length; i++) {
- if (list[i].type == "set") {
- list[i].forEach(function (el) {
- node.appendChild(el.node);
- });
- } else {
- node.appendChild(list[i].node);
- }
- }
- var children = node.childNodes;
- for (i = 0; i < children.length; i++) {
- this[j++] = wrap(children[i]);
- }
- return this;
- }
- // Hub garbage collector every 10s
- setInterval(function () {
- for (var key in hub) if (hub[has](key)) {
- var el = hub[key],
- node = el.node;
- if (el.type != "svg" && !node.ownerSVGElement || el.type == "svg" && (!node.parentNode || "ownerSVGElement" in node.parentNode && !node.ownerSVGElement)) {
- delete hub[key];
- }
- }
- }, 1e4);
- function Element(el) {
- if (el.snap in hub) {
- return hub[el.snap];
- }
- var svg;
- try {
- svg = el.ownerSVGElement;
- } catch(e) {}
- /*\
- * Element.node
- [ property (object) ]
- **
- * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.
- > Usage
- | // draw a circle at coordinate 10,10 with radius of 10
- | var c = paper.circle(10, 10, 10);
- | c.node.onclick = function () {
- | c.attr("fill", "red");
- | };
- \*/
- this.node = el;
- if (svg) {
- this.paper = new Paper(svg);
- }
- /*\
- * Element.type
- [ property (string) ]
- **
- * SVG tag name of the given element.
- \*/
- this.type = el.tagName || el.nodeName;
- var id = this.id = ID(this);
- this.anims = {};
- this._ = {
- transform: []
- };
- el.snap = id;
- hub[id] = this;
- if (this.type == "g") {
- this.add = add2group;
- }
- if (this.type in {g: 1, mask: 1, pattern: 1, symbol: 1}) {
- for (var method in Paper.prototype) if (Paper.prototype[has](method)) {
- this[method] = Paper.prototype[method];
- }
- }
- }
- /*\
- * Element.attr
- [ method ]
- **
- * Gets or sets given attributes of the element.
- **
- - params (object) contains key-value pairs of attributes you want to set
- * or
- - param (string) name of the attribute
- = (Element) the current element
- * or
- = (string) value of attribute
- > Usage
- | el.attr({
- | fill: "#fc0",
- | stroke: "#000",
- | strokeWidth: 2, // CamelCase...
- | "fill-opacity": 0.5, // or dash-separated names
- | width: "*=2" // prefixed values
- | });
- | console.log(el.attr("fill")); // #fc0
- * Prefixed values in format `"+=10"` supported. All four operations
- * (`+`, `-`, `*` and `/`) could be used. Optionally you can use units for `+`
- * and `-`: `"+=2em"`.
- \*/
- Element.prototype.attr = function (params, value) {
- var el = this,
- node = el.node;
- if (!params) {
- if (node.nodeType != 1) {
- return {
- text: node.nodeValue
- };
- }
- var attr = node.attributes,
- out = {};
- for (var i = 0, ii = attr.length; i < ii; i++) {
- out[attr[i].nodeName] = attr[i].nodeValue;
- }
- return out;
- }
- if (is(params, "string")) {
- if (arguments.length > 1) {
- var json = {};
- json[params] = value;
- params = json;
- } else {
- return eve("snap.util.getattr." + params, el).firstDefined();
- }
- }
- for (var att in params) {
- if (params[has](att)) {
- eve("snap.util.attr." + att, el, params[att]);
- }
- }
- return el;
- };
- /*\
- * Snap.parse
- [ method ]
- **
- * Parses SVG fragment and converts it into a @Fragment
- **
- - svg (string) SVG string
- = (Fragment) the @Fragment
- \*/
- Snap.parse = function (svg) {
- var f = glob.doc.createDocumentFragment(),
- full = true,
- div = glob.doc.createElement("div");
- svg = Str(svg);
- if (!svg.match(/^\s*<\s*svg(?:\s|>)/)) {
- svg = "<svg>" + svg + "</svg>";
- full = false;
- }
- div.innerHTML = svg;
- svg = div.getElementsByTagName("svg")[0];
- if (svg) {
- if (full) {
- f = svg;
- } else {
- while (svg.firstChild) {
- f.appendChild(svg.firstChild);
- }
- }
- }
- return new Fragment(f);
- };
- function Fragment(frag) {
- this.node = frag;
- }
- /*\
- * Snap.fragment
- [ method ]
- **
- * Creates a DOM fragment from a given list of elements or strings
- **
- - varargs (…) SVG string
- = (Fragment) the @Fragment
- \*/
- Snap.fragment = function () {
- var args = Array.prototype.slice.call(arguments, 0),
- f = glob.doc.createDocumentFragment();
- for (var i = 0, ii = args.length; i < ii; i++) {
- var item = args[i];
- if (item.node && item.node.nodeType) {
- f.appendChild(item.node);
- }
- if (item.nodeType) {
- f.appendChild(item);
- }
- if (typeof item == "string") {
- f.appendChild(Snap.parse(item).node);
- }
- }
- return new Fragment(f);
- };
-
- function make(name, parent) {
- var res = $(name);
- parent.appendChild(res);
- var el = wrap(res);
- return el;
- }
- function Paper(w, h) {
- var res,
- desc,
- defs,
- proto = Paper.prototype;
- if (w && w.tagName == "svg") {
- if (w.snap in hub) {
- return hub[w.snap];
- }
- var doc = w.ownerDocument;
- res = new Element(w);
- desc = w.getElementsByTagName("desc")[0];
- defs = w.getElementsByTagName("defs")[0];
- if (!desc) {
- desc = $("desc");
- desc.appendChild(doc.createTextNode("Created with Snap"));
- res.node.appendChild(desc);
- }
- if (!defs) {
- defs = $("defs");
- res.node.appendChild(defs);
- }
- res.defs = defs;
- for (var key in proto) if (proto[has](key)) {
- res[key] = proto[key];
- }
- res.paper = res.root = res;
- } else {
- res = make("svg", glob.doc.body);
- $(res.node, {
- height: h,
- version: 1.1,
- width: w,
- xmlns: xmlns
- });
- }
- return res;
- }
- function wrap(dom) {
- if (!dom) {
- return dom;
- }
- if (dom instanceof Element || dom instanceof Fragment) {
- return dom;
- }
- if (dom.tagName && dom.tagName.toLowerCase() == "svg") {
- return new Paper(dom);
- }
- if (dom.tagName && dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") {
- return new Paper(dom.contentDocument.getElementsByTagName("svg")[0]);
- }
- return new Element(dom);
- }
-
- Snap._.make = make;
- Snap._.wrap = wrap;
- /*\
- * Paper.el
- [ method ]
- **
- * Creates an element on paper with a given name and no attributes
- **
- - name (string) tag name
- - attr (object) attributes
- = (Element) the current element
- > Usage
- | var c = paper.circle(10, 10, 10); // is the same as...
- | var c = paper.el("circle").attr({
- | cx: 10,
- | cy: 10,
- | r: 10
- | });
- | // and the same as
- | var c = paper.el("circle", {
- | cx: 10,
- | cy: 10,
- | r: 10
- | });
- \*/
- Paper.prototype.el = function (name, attr) {
- var el = make(name, this.node);
- attr && el.attr(attr);
- return el;
- };
- /*\
- * Element.children
- [ method ]
- **
- * Returns array of all the children of the element.
- = (array) array of Elements
- \*/
- Element.prototype.children = function () {
- var out = [],
- ch = this.node.childNodes;
- for (var i = 0, ii = ch.length; i < ii; i++) {
- out[i] = Snap(ch[i]);
- }
- return out;
- };
- function jsonFiller(root, o) {
- for (var i = 0, ii = root.length; i < ii; i++) {
- var item = {
- type: root[i].type,
- attr: root[i].attr()
- },
- children = root[i].children();
- o.push(item);
- if (children.length) {
- jsonFiller(children, item.childNodes = []);
- }
- }
- }
- /*\
- * Element.toJSON
- [ method ]
- **
- * Returns object representation of the given element and all its children.
- = (object) in format
- o {
- o type (string) this.type,
- o attr (object) attributes map,
- o childNodes (array) optional array of children in the same format
- o }
- \*/
- Element.prototype.toJSON = function () {
- var out = [];
- jsonFiller([this], out);
- return out[0];
- };
- // default
- eve.on("snap.util.getattr", function () {
- var att = eve.nt();
- att = att.substring(att.lastIndexOf(".") + 1);
- var css = att.replace(/[A-Z]/g, function (letter) {
- return "-" + letter.toLowerCase();
- });
- if (cssAttr[has](css)) {
- return this.node.ownerDocument.defaultView.getComputedStyle(this.node, null).getPropertyValue(css);
- } else {
- return $(this.node, att);
- }
- });
- var cssAttr = {
- "alignment-baseline": 0,
- "baseline-shift": 0,
- "clip": 0,
- "clip-path": 0,
- "clip-rule": 0,
- "color": 0,
- "color-interpolation": 0,
- "color-interpolation-filters": 0,
- "color-profile": 0,
- "color-rendering": 0,
- "cursor": 0,
- "direction": 0,
- "display": 0,
- "dominant-baseline": 0,
- "enable-background": 0,
- "fill": 0,
- "fill-opacity": 0,
- "fill-rule": 0,
- "filter": 0,
- "flood-color": 0,
- "flood-opacity": 0,
- "font": 0,
- "font-family": 0,
- "font-size": 0,
- "font-size-adjust": 0,
- "font-stretch": 0,
- "font-style": 0,
- "font-variant": 0,
- "font-weight": 0,
- "glyph-orientation-horizontal": 0,
- "glyph-orientation-vertical": 0,
- "image-rendering": 0,
- "kerning": 0,
- "letter-spacing": 0,
- "lighting-color": 0,
- "marker": 0,
- "marker-end": 0,
- "marker-mid": 0,
- "marker-start": 0,
- "mask": 0,
- "opacity": 0,
- "overflow": 0,
- "pointer-events": 0,
- "shape-rendering": 0,
- "stop-color": 0,
- "stop-opacity": 0,
- "stroke": 0,
- "stroke-dasharray": 0,
- "stroke-dashoffset": 0,
- "stroke-linecap": 0,
- "stroke-linejoin": 0,
- "stroke-miterlimit": 0,
- "stroke-opacity": 0,
- "stroke-width": 0,
- "text-anchor": 0,
- "text-decoration": 0,
- "text-rendering": 0,
- "unicode-bidi": 0,
- "visibility": 0,
- "word-spacing": 0,
- "writing-mode": 0
- };
-
- eve.on("snap.util.attr", function (value) {
- var att = eve.nt(),
- attr = {};
- att = att.substring(att.lastIndexOf(".") + 1);
- attr[att] = value;
- var style = att.replace(/-(\w)/gi, function (all, letter) {
- return letter.toUpperCase();
- }),
- css = att.replace(/[A-Z]/g, function (letter) {
- return "-" + letter.toLowerCase();
- });
- if (cssAttr[has](css)) {
- this.node.style[style] = value == null ? E : value;
- } else {
- $(this.node, attr);
- }
- });
- (function (proto) {}(Paper.prototype));
-
- // simple ajax
- /*\
- * Snap.ajax
- [ method ]
- **
- * Simple implementation of Ajax
- **
- - url (string) URL
- - postData (object|string) data for post request
- - callback (function) callback
- - scope (object) #optional scope of callback
- * or
- - url (string) URL
- - callback (function) callback
- - scope (object) #optional scope of callback
- = (XMLHttpRequest) the XMLHttpRequest object, just in case
- \*/
- Snap.ajax = function (url, postData, callback, scope){
- var req = new XMLHttpRequest,
- id = ID();
- if (req) {
- if (is(postData, "function")) {
- scope = callback;
- callback = postData;
- postData = null;
- } else if (is(postData, "object")) {
- var pd = [];
- for (var key in postData) if (postData.hasOwnProperty(key)) {
- pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key]));
- }
- postData = pd.join("&");
- }
- req.open((postData ? "POST" : "GET"), url, true);
- if (postData) {
- req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- }
- if (callback) {
- eve.once("snap.ajax." + id + ".0", callback);
- eve.once("snap.ajax." + id + ".200", callback);
- eve.once("snap.ajax." + id + ".304", callback);
- }
- req.onreadystatechange = function() {
- if (req.readyState != 4) return;
- eve("snap.ajax." + id + "." + req.status, scope, req);
- };
- if (req.readyState == 4) {
- return req;
- }
- req.send(postData);
- return req;
- }
- };
- /*\
- * Snap.load
- [ method ]
- **
- * Loads external SVG file as a @Fragment (see @Snap.ajax for more advanced AJAX)
- **
- - url (string) URL
- - callback (function) callback
- - scope (object) #optional scope of callback
- \*/
- Snap.load = function (url, callback, scope) {
- Snap.ajax(url, function (req) {
- var f = Snap.parse(req.responseText);
- scope ? callback.call(scope, f) : callback(f);
- });
- };
- var getOffset = function (elem) {
- var box = elem.getBoundingClientRect(),
- doc = elem.ownerDocument,
- body = doc.body,
- docElem = doc.documentElement,
- clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
- top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,
- left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;
- return {
- y: top,
- x: left
- };
- };
- /*\
- * Snap.getElementByPoint
- [ method ]
- **
- * Returns you topmost element under given point.
- **
- = (object) Snap element object
- - x (number) x coordinate from the top left corner of the window
- - y (number) y coordinate from the top left corner of the window
- > Usage
- | Snap.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"});
- \*/
- Snap.getElementByPoint = function (x, y) {
- var paper = this,
- svg = paper.canvas,
- target = glob.doc.elementFromPoint(x, y);
- if (glob.win.opera && target.tagName == "svg") {
- var so = getOffset(target),
- sr = target.createSVGRect();
- sr.x = x - so.x;
- sr.y = y - so.y;
- sr.width = sr.height = 1;
- var hits = target.getIntersectionList(sr, null);
- if (hits.length) {
- target = hits[hits.length - 1];
- }
- }
- if (!target) {
- return null;
- }
- return wrap(target);
- };
- /*\
- * Snap.plugin
- [ method ]
- **
- * Let you write plugins. You pass in a function with five arguments, like this:
- | Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
- | Snap.newmethod = function () {};
- | Element.prototype.newmethod = function () {};
- | Paper.prototype.newmethod = function () {};
- | });
- * Inside the function you have access to all main objects (and their
- * prototypes). This allow you to extend anything you want.
- **
- - f (function) your plugin body
- \*/
- Snap.plugin = function (f) {
- f(Snap, Element, Paper, glob, Fragment);
- };
- glob.win.Snap = Snap;
- return Snap;
- }(window || this));
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var elproto = Element.prototype,
- is = Snap.is,
- Str = String,
- unit2px = Snap._unit2px,
- $ = Snap._.$,
- make = Snap._.make,
- getSomeDefs = Snap._.getSomeDefs,
- has = "hasOwnProperty",
- wrap = Snap._.wrap;
- /*\
- * Element.getBBox
- [ method ]
- **
- * Returns the bounding box descriptor for the given element
- **
- = (object) bounding box descriptor:
- o {
- o cx: (number) x of the center,
- o cy: (number) x of the center,
- o h: (number) height,
- o height: (number) height,
- o path: (string) path command for the box,
- o r0: (number) radius of a circle that fully encloses the box,
- o r1: (number) radius of the smallest circle that can be enclosed,
- o r2: (number) radius of the largest circle that can be enclosed,
- o vb: (string) box as a viewbox command,
- o w: (number) width,
- o width: (number) width,
- o x2: (number) x of the right side,
- o x: (number) x of the left side,
- o y2: (number) y of the bottom edge,
- o y: (number) y of the top edge
- o }
- \*/
- elproto.getBBox = function (isWithoutTransform) {
- if (!Snap.Matrix || !Snap.path) {
- return this.node.getBBox();
- }
- var el = this,
- m = new Snap.Matrix;
- if (el.removed) {
- return Snap._.box();
- }
- while (el.type == "use") {
- if (!isWithoutTransform) {
- m = m.add(el.transform().localMatrix.translate(el.attr("x") || 0, el.attr("y") || 0));
- }
- if (el.original) {
- el = el.original;
- } else {
- var href = el.attr("xlink:href");
- el = el.original = el.node.ownerDocument.getElementById(href.substring(href.indexOf("#") + 1));
- }
- }
- var _ = el._,
- pathfinder = Snap.path.get[el.type] || Snap.path.get.deflt;
- try {
- if (isWithoutTransform) {
- _.bboxwt = pathfinder ? Snap.path.getBBox(el.realPath = pathfinder(el)) : Snap._.box(el.node.getBBox());
- return Snap._.box(_.bboxwt);
- } else {
- el.realPath = pathfinder(el);
- el.matrix = el.transform().localMatrix;
- _.bbox = Snap.path.getBBox(Snap.path.map(el.realPath, m.add(el.matrix)));
- return Snap._.box(_.bbox);
- }
- } catch (e) {
- // Firefox doesn’t give you bbox of hidden element
- return Snap._.box();
- }
- };
- var propString = function () {
- return this.string;
- };
- function extractTransform(el, tstr) {
- if (tstr == null) {
- var doReturn = true;
- if (el.type == "linearGradient" || el.type == "radialGradient") {
- tstr = el.node.getAttribute("gradientTransform");
- } else if (el.type == "pattern") {
- tstr = el.node.getAttribute("patternTransform");
- } else {
- tstr = el.node.getAttribute("transform");
- }
- if (!tstr) {
- return new Snap.Matrix;
- }
- tstr = Snap._.svgTransform2string(tstr);
- } else {
- if (!Snap._.rgTransform.test(tstr)) {
- tstr = Snap._.svgTransform2string(tstr);
- } else {
- tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);
- }
- if (is(tstr, "array")) {
- tstr = Snap.path ? Snap.path.toString.call(tstr) : Str(tstr);
- }
- el._.transform = tstr;
- }
- var m = Snap._.transform2matrix(tstr, el.getBBox(1));
- if (doReturn) {
- return m;
- } else {
- el.matrix = m;
- }
- }
- /*\
- * Element.transform
- [ method ]
- **
- * Gets or sets transformation of the element
- **
- - tstr (string) transform string in Snap or SVG format
- = (Element) the current element
- * or
- = (object) transformation descriptor:
- o {
- o string (string) transform string,
- o globalMatrix (Matrix) matrix of all transformations applied to element or its parents,
- o localMatrix (Matrix) matrix of transformations applied only to the element,
- o diffMatrix (Matrix) matrix of difference between global and local transformations,
- o global (string) global transformation as string,
- o local (string) local transformation as string,
- o toString (function) returns `string` property
- o }
- \*/
- elproto.transform = function (tstr) {
- var _ = this._;
- if (tstr == null) {
- var papa = this,
- global = new Snap.Matrix(this.node.getCTM()),
- local = extractTransform(this),
- ms = [local],
- m = new Snap.Matrix,
- i,
- localString = local.toTransformString(),
- string = Str(local) == Str(this.matrix) ?
- Str(_.transform) : localString;
- while (papa.type != "svg" && (papa = papa.parent())) {
- ms.push(extractTransform(papa));
- }
- i = ms.length;
- while (i--) {
- m.add(ms[i]);
- }
- return {
- string: string,
- globalMatrix: global,
- totalMatrix: m,
- localMatrix: local,
- diffMatrix: global.clone().add(local.invert()),
- global: global.toTransformString(),
- total: m.toTransformString(),
- local: localString,
- toString: propString
- };
- }
- if (tstr instanceof Snap.Matrix) {
- this.matrix = tstr;
- this._.transform = tstr.toTransformString();
- } else {
- extractTransform(this, tstr);
- }
-
- if (this.node) {
- if (this.type == "linearGradient" || this.type == "radialGradient") {
- $(this.node, {gradientTransform: this.matrix});
- } else if (this.type == "pattern") {
- $(this.node, {patternTransform: this.matrix});
- } else {
- $(this.node, {transform: this.matrix});
- }
- }
-
- return this;
- };
- /*\
- * Element.parent
- [ method ]
- **
- * Returns the element's parent
- **
- = (Element) the parent element
- \*/
- elproto.parent = function () {
- return wrap(this.node.parentNode);
- };
- /*\
- * Element.append
- [ method ]
- **
- * Appends the given element to current one
- **
- - el (Element|Set) element to append
- = (Element) the parent element
- \*/
- /*\
- * Element.add
- [ method ]
- **
- * See @Element.append
- \*/
- elproto.append = elproto.add = function (el) {
- if (el) {
- if (el.type == "set") {
- var it = this;
- el.forEach(function (el) {
- it.add(el);
- });
- return this;
- }
- el = wrap(el);
- this.node.appendChild(el.node);
- el.paper = this.paper;
- }
- return this;
- };
- /*\
- * Element.appendTo
- [ method ]
- **
- * Appends the current element to the given one
- **
- - el (Element) parent element to append to
- = (Element) the child element
- \*/
- elproto.appendTo = function (el) {
- if (el) {
- el = wrap(el);
- el.append(this);
- }
- return this;
- };
- /*\
- * Element.prepend
- [ method ]
- **
- * Prepends the given element to the current one
- **
- - el (Element) element to prepend
- = (Element) the parent element
- \*/
- elproto.prepend = function (el) {
- if (el) {
- if (el.type == "set") {
- var it = this,
- first;
- el.forEach(function (el) {
- if (first) {
- first.after(el);
- } else {
- it.prepend(el);
- }
- first = el;
- });
- return this;
- }
- el = wrap(el);
- var parent = el.parent();
- this.node.insertBefore(el.node, this.node.firstChild);
- this.add && this.add();
- el.paper = this.paper;
- this.parent() && this.parent().add();
- parent && parent.add();
- }
- return this;
- };
- /*\
- * Element.prependTo
- [ method ]
- **
- * Prepends the current element to the given one
- **
- - el (Element) parent element to prepend to
- = (Element) the child element
- \*/
- elproto.prependTo = function (el) {
- el = wrap(el);
- el.prepend(this);
- return this;
- };
- /*\
- * Element.before
- [ method ]
- **
- * Inserts given element before the current one
- **
- - el (Element) element to insert
- = (Element) the parent element
- \*/
- elproto.before = function (el) {
- if (el.type == "set") {
- var it = this;
- el.forEach(function (el) {
- var parent = el.parent();
- it.node.parentNode.insertBefore(el.node, it.node);
- parent && parent.add();
- });
- this.parent().add();
- return this;
- }
- el = wrap(el);
- var parent = el.parent();
- this.node.parentNode.insertBefore(el.node, this.node);
- this.parent() && this.parent().add();
- parent && parent.add();
- el.paper = this.paper;
- return this;
- };
- /*\
- * Element.after
- [ method ]
- **
- * Inserts given element after the current one
- **
- - el (Element) element to insert
- = (Element) the parent element
- \*/
- elproto.after = function (el) {
- el = wrap(el);
- var parent = el.parent();
- if (this.node.nextSibling) {
- this.node.parentNode.insertBefore(el.node, this.node.nextSibling);
- } else {
- this.node.parentNode.appendChild(el.node);
- }
- this.parent() && this.parent().add();
- parent && parent.add();
- el.paper = this.paper;
- return this;
- };
- /*\
- * Element.insertBefore
- [ method ]
- **
- * Inserts the element after the given one
- **
- - el (Element) element next to whom insert to
- = (Element) the parent element
- \*/
- elproto.insertBefore = function (el) {
- el = wrap(el);
- var parent = this.parent();
- el.node.parentNode.insertBefore(this.node, el.node);
- this.paper = el.paper;
- parent && parent.add();
- el.parent() && el.parent().add();
- return this;
- };
- /*\
- * Element.insertAfter
- [ method ]
- **
- * Inserts the element after the given one
- **
- - el (Element) element next to whom insert to
- = (Element) the parent element
- \*/
- elproto.insertAfter = function (el) {
- el = wrap(el);
- var parent = this.parent();
- el.node.parentNode.insertBefore(this.node, el.node.nextSibling);
- this.paper = el.paper;
- parent && parent.add();
- el.parent() && el.parent().add();
- return this;
- };
- /*\
- * Element.remove
- [ method ]
- **
- * Removes element from the DOM
- = (Element) the detached element
- \*/
- elproto.remove = function () {
- var parent = this.parent();
- this.node.parentNode && this.node.parentNode.removeChild(this.node);
- delete this.paper;
- this.removed = true;
- parent && parent.add();
- return this;
- };
- /*\
- * Element.select
- [ method ]
- **
- * Gathers the nested @Element matching the given set of CSS selectors
- **
- - query (string) CSS selector
- = (Element) result of query selection
- \*/
- elproto.select = function (query) {
- query = Str(query).replace(/([^\\]):/g, "$1\\:");
- return wrap(this.node.querySelector(query));
- };
- /*\
- * Element.selectAll
- [ method ]
- **
- * Gathers nested @Element objects matching the given set of CSS selectors
- **
- - query (string) CSS selector
- = (Set|array) result of query selection
- \*/
- elproto.selectAll = function (query) {
- var nodelist = this.node.querySelectorAll(query),
- set = (Snap.set || Array)();
- for (var i = 0; i < nodelist.length; i++) {
- set.push(wrap(nodelist[i]));
- }
- return set;
- };
- /*\
- * Element.asPX
- [ method ]
- **
- * Returns given attribute of the element as a `px` value (not %, em, etc.)
- **
- - attr (string) attribute name
- - value (string) #optional attribute value
- = (Element) result of query selection
- \*/
- elproto.asPX = function (attr, value) {
- if (value == null) {
- value = this.attr(attr);
- }
- return +unit2px(this, attr, value);
- };
- // SIERRA Element.use(): I suggest adding a note about how to access the original element the returned <use> instantiates. It's a part of SVG with which ordinary web developers may be least familiar.
- /*\
- * Element.use
- [ method ]
- **
- * Creates a `<use>` element linked to the current element
- **
- = (Element) the `<use>` element
- \*/
- elproto.use = function () {
- var use,
- id = this.node.id;
- if (!id) {
- id = this.id;
- $(this.node, {
- id: id
- });
- }
- if (this.type == "linearGradient" || this.type == "radialGradient" ||
- this.type == "pattern") {
- use = make(this.type, this.node.parentNode);
- } else {
- use = make("use", this.node.parentNode);
- }
- $(use.node, {
- "xlink:href": "#" + id
- });
- use.original = this;
- return use;
- };
- function fixids(el) {
- var els = el.selectAll("*"),
- it,
- url = /^\s*url\(("|'|)(.*)\1\)\s*$/,
- ids = [],
- uses = {};
- function urltest(it, name) {
- var val = $(it.node, name);
- val = val && val.match(url);
- val = val && val[2];
- if (val && val.charAt() == "#") {
- val = val.substring(1);
- } else {
- return;
- }
- if (val) {
- uses[val] = (uses[val] || []).concat(function (id) {
- var attr = {};
- attr[name] = URL(id);
- $(it.node, attr);
- });
- }
- }
- function linktest(it) {
- var val = $(it.node, "xlink:href");
- if (val && val.charAt() == "#") {
- val = val.substring(1);
- } else {
- return;
- }
- if (val) {
- uses[val] = (uses[val] || []).concat(function (id) {
- it.attr("xlink:href", "#" + id);
- });
- }
- }
- for (var i = 0, ii = els.length; i < ii; i++) {
- it = els[i];
- urltest(it, "fill");
- urltest(it, "stroke");
- urltest(it, "filter");
- urltest(it, "mask");
- urltest(it, "clip-path");
- linktest(it);
- var oldid = $(it.node, "id");
- if (oldid) {
- $(it.node, {id: it.id});
- ids.push({
- old: oldid,
- id: it.id
- });
- }
- }
- for (i = 0, ii = ids.length; i < ii; i++) {
- var fs = uses[ids[i].old];
- if (fs) {
- for (var j = 0, jj = fs.length; j < jj; j++) {
- fs[j](ids[i].id);
- }
- }
- }
- }
- /*\
- * Element.clone
- [ method ]
- **
- * Creates a clone of the element and inserts it after the element
- **
- = (Element) the clone
- \*/
- elproto.clone = function () {
- var clone = wrap(this.node.cloneNode(true));
- if ($(clone.node, "id")) {
- $(clone.node, {id: clone.id});
- }
- fixids(clone);
- clone.insertAfter(this);
- return clone;
- };
- /*\
- * Element.toDefs
- [ method ]
- **
- * Moves element to the shared `<defs>` area
- **
- = (Element) the element
- \*/
- elproto.toDefs = function () {
- var defs = getSomeDefs(this);
- defs.appendChild(this.node);
- return this;
- };
- /*\
- * Element.toPattern
- [ method ]
- **
- * Creates a `<pattern>` element from the current element
- **
- * To create a pattern you have to specify the pattern rect:
- - x (string|number)
- - y (string|number)
- - width (string|number)
- - height (string|number)
- = (Element) the `<pattern>` element
- * You can use pattern later on as an argument for `fill` attribute:
- | var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
- | fill: "none",
- | stroke: "#bada55",
- | strokeWidth: 5
- | }).pattern(0, 0, 10, 10),
- | c = paper.circle(200, 200, 100);
- | c.attr({
- | fill: p
- | });
- \*/
- elproto.pattern = elproto.toPattern = function (x, y, width, height) {
- var p = make("pattern", getSomeDefs(this));
- if (x == null) {
- x = this.getBBox();
- }
- if (is(x, "object") && "x" in x) {
- y = x.y;
- width = x.width;
- height = x.height;
- x = x.x;
- }
- $(p.node, {
- x: x,
- y: y,
- width: width,
- height: height,
- patternUnits: "userSpaceOnUse",
- id: p.id,
- viewBox: [x, y, width, height].join(" ")
- });
- p.node.appendChild(this.node);
- return p;
- };
- // SIERRA Element.marker(): clarify what a reference point is. E.g., helps you offset the object from its edge such as when centering it over a path.
- // SIERRA Element.marker(): I suggest the method should accept default reference point values. Perhaps centered with (refX = width/2) and (refY = height/2)? Also, couldn't it assume the element's current _width_ and _height_? And please specify what _x_ and _y_ mean: offsets? If so, from where? Couldn't they also be assigned default values?
- /*\
- * Element.marker
- [ method ]
- **
- * Creates a `<marker>` element from the current element
- **
- * To create a marker you have to specify the bounding rect and reference point:
- - x (number)
- - y (number)
- - width (number)
- - height (number)
- - refX (number)
- - refY (number)
- = (Element) the `<marker>` element
- * You can specify the marker later as an argument for `marker-start`, `marker-end`, `marker-mid`, and `marker` attributes. The `marker` attribute places the marker at every point along the path, and `marker-mid` places them at every point except the start and end.
- \*/
- // TODO add usage for markers
- elproto.marker = function (x, y, width, height, refX, refY) {
- var p = make("marker", getSomeDefs(this));
- if (x == null) {
- x = this.getBBox();
- }
- if (is(x, "object") && "x" in x) {
- y = x.y;
- width = x.width;
- height = x.height;
- refX = x.refX || x.cx;
- refY = x.refY || x.cy;
- x = x.x;
- }
- $(p.node, {
- viewBox: [x, y, width, height].join(" "),
- markerWidth: width,
- markerHeight: height,
- orient: "auto",
- refX: refX || 0,
- refY: refY || 0,
- id: p.id
- });
- p.node.appendChild(this.node);
- return p;
- };
- // animation
- function slice(from, to, f) {
- return function (arr) {
- var res = arr.slice(from, to);
- if (res.length == 1) {
- res = res[0];
- }
- return f ? f(res) : res;
- };
- }
- var Animation = function (attr, ms, easing, callback) {
- if (typeof easing == "function" && !easing.length) {
- callback = easing;
- easing = mina.linear;
- }
- this.attr = attr;
- this.dur = ms;
- easing && (this.easing = easing);
- callback && (this.callback = callback);
- };
- Snap._.Animation = Animation;
- /*\
- * Snap.animation
- [ method ]
- **
- * Creates an animation object
- **
- - attr (object) attributes of final destination
- - duration (number) duration of the animation, in milliseconds
- - easing (function) #optional one of easing functions of @mina or custom one
- - callback (function) #optional callback function that fires when animation ends
- = (object) animation object
- \*/
- Snap.animation = function (attr, ms, easing, callback) {
- return new Animation(attr, ms, easing, callback);
- };
- /*\
- * Element.inAnim
- [ method ]
- **
- * Returns a set of animations that may be able to manipulate the current element
- **
- = (object) in format:
- o {
- o anim (object) animation object,
- o mina (object) @mina object,
- o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished,
- o status (function) gets or sets the status of the animation,
- o stop (function) stops the animation
- o }
- \*/
- elproto.inAnim = function () {
- var el = this,
- res = [];
- for (var id in el.anims) if (el.anims[has](id)) {
- (function (a) {
- res.push({
- anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
- mina: a,
- curStatus: a.status(),
- status: function (val) {
- return a.status(val);
- },
- stop: function () {
- a.stop();
- }
- });
- }(el.anims[id]));
- }
- return res;
- };
- /*\
- * Snap.animate
- [ method ]
- **
- * Runs generic animation of one number into another with a caring function
- **
- - from (number|array) number or array of numbers
- - to (number|array) number or array of numbers
- - setter (function) caring function that accepts one number argument
- - duration (number) duration, in milliseconds
- - easing (function) #optional easing function from @mina or custom
- - callback (function) #optional callback function to execute when animation ends
- = (object) animation object in @mina format
- o {
- o id (string) animation id, consider it read-only,
- o duration (function) gets or sets the duration of the animation,
- o easing (function) easing,
- o speed (function) gets or sets the speed of the animation,
- o status (function) gets or sets the status of the animation,
- o stop (function) stops the animation
- o }
- | var rect = Snap().rect(0, 0, 10, 10);
- | Snap.animate(0, 10, function (val) {
- | rect.attr({
- | x: val
- | });
- | }, 1000);
- | // in given context is equivalent to
- | rect.animate({x: 10}, 1000);
- \*/
- Snap.animate = function (from, to, setter, ms, easing, callback) {
- if (typeof easing == "function" && !easing.length) {
- callback = easing;
- easing = mina.linear;
- }
- var now = mina.time(),
- anim = mina(from, to, now, now + ms, mina.time, setter, easing);
- callback && eve.once("mina.finish." + anim.id, callback);
- return anim;
- };
- /*\
- * Element.stop
- [ method ]
- **
- * Stops all the animations for the current element
- **
- = (Element) the current element
- \*/
- elproto.stop = function () {
- var anims = this.inAnim();
- for (var i = 0, ii = anims.length; i < ii; i++) {
- anims[i].stop();
- }
- return this;
- };
- /*\
- * Element.animate
- [ method ]
- **
- * Animates the given attributes of the element
- **
- - attrs (object) key-value pairs of destination attributes
- - duration (number) duration of the animation in milliseconds
- - easing (function) #optional easing function from @mina or custom
- - callback (function) #optional callback function that executes when the animation ends
- = (Element) the current element
- \*/
- elproto.animate = function (attrs, ms, easing, callback) {
- if (typeof easing == "function" && !easing.length) {
- callback = easing;
- easing = mina.linear;
- }
- if (attrs instanceof Animation) {
- callback = attrs.callback;
- easing = attrs.easing;
- ms = easing.dur;
- attrs = attrs.attr;
- }
- var fkeys = [], tkeys = [], keys = {}, from, to, f, eq,
- el = this;
- for (var key in attrs) if (attrs[has](key)) {
- if (el.equal) {
- eq = el.equal(key, Str(attrs[key]));
- from = eq.from;
- to = eq.to;
- f = eq.f;
- } else {
- from = +el.attr(key);
- to = +attrs[key];
- }
- var len = is(from, "array") ? from.length : 1;
- keys[key] = slice(fkeys.length, fkeys.length + len, f);
- fkeys = fkeys.concat(from);
- tkeys = tkeys.concat(to);
- }
- var now = mina.time(),
- anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) {
- var attr = {};
- for (var key in keys) if (keys[has](key)) {
- attr[key] = keys[key](val);
- }
- el.attr(attr);
- }, easing);
- el.anims[anim.id] = anim;
- anim._attrs = attrs;
- anim._callback = callback;
- eve("snap.animcreated." + el.id, anim);
- eve.once("mina.finish." + anim.id, function () {
- delete el.anims[anim.id];
- callback && callback.call(el);
- });
- eve.once("mina.stop." + anim.id, function () {
- delete el.anims[anim.id];
- });
- return el;
- };
- var eldata = {};
- /*\
- * Element.data
- [ method ]
- **
- * Adds or retrieves given value associated with given key. (Don’t confuse
- * with `data-` attributes)
- *
- * See also @Element.removeData
- - key (string) key to store data
- - value (any) #optional value to store
- = (object) @Element
- * or, if value is not specified:
- = (any) value
- > Usage
- | for (var i = 0, i < 5, i++) {
- | paper.circle(10 + 15 * i, 10, 10)
- | .attr({fill: "#000"})
- | .data("i", i)
- | .click(function () {
- | alert(this.data("i"));
- | });
- | }
- \*/
- elproto.data = function (key, value) {
- var data = eldata[this.id] = eldata[this.id] || {};
- if (arguments.length == 0){
- eve("snap.data.get." + this.id, this, data, null);
- return data;
- }
- if (arguments.length == 1) {
- if (Snap.is(key, "object")) {
- for (var i in key) if (key[has](i)) {
- this.data(i, key[i]);
- }
- return this;
- }
- eve("snap.data.get." + this.id, this, data[key], key);
- return data[key];
- }
- data[key] = value;
- eve("snap.data.set." + this.id, this, value, key);
- return this;
- };
- /*\
- * Element.removeData
- [ method ]
- **
- * Removes value associated with an element by given key.
- * If key is not provided, removes all the data of the element.
- - key (string) #optional key
- = (object) @Element
- \*/
- elproto.removeData = function (key) {
- if (key == null) {
- eldata[this.id] = {};
- } else {
- eldata[this.id] && delete eldata[this.id][key];
- }
- return this;
- };
- /*\
- * Element.outerSVG
- [ method ]
- **
- * Returns SVG code for the element, equivalent to HTML's `outerHTML`.
- *
- * See also @Element.innerSVG
- = (string) SVG code for the element
- \*/
- /*\
- * Element.toString
- [ method ]
- **
- * See @Element.outerSVG
- \*/
- elproto.outerSVG = elproto.toString = toString(1);
- /*\
- * Element.innerSVG
- [ method ]
- **
- * Returns SVG code for the element's contents, equivalent to HTML's `innerHTML`
- = (string) SVG code for the element
- \*/
- elproto.innerSVG = toString();
- function toString(type) {
- return function () {
- var res = type ? "<" + this.type : "",
- attr = this.node.attributes,
- chld = this.node.childNodes;
- if (type) {
- for (var i = 0, ii = attr.length; i < ii; i++) {
- res += " " + attr[i].name + '="' +
- attr[i].value.replace(/"/g, '\\"') + '"';
- }
- }
- if (chld.length) {
- type && (res += ">");
- for (i = 0, ii = chld.length; i < ii; i++) {
- if (chld[i].nodeType == 3) {
- res += chld[i].nodeValue;
- } else if (chld[i].nodeType == 1) {
- res += wrap(chld[i]).toString();
- }
- }
- type && (res += "</" + this.type + ">");
- } else {
- type && (res += "/>");
- }
- return res;
- };
- }
- elproto.toDataURL = function () {
- if (window && window.btoa) {
- var bb = this.getBBox(),
- svg = Snap.format('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}" viewBox="{x} {y} {width} {height}">{contents}</svg>', {
- x: +bb.x.toFixed(3),
- y: +bb.y.toFixed(3),
- width: +bb.width.toFixed(3),
- height: +bb.height.toFixed(3),
- contents: this.outerSVG()
- });
- return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svg)));
- }
- };
- /*\
- * Fragment.select
- [ method ]
- **
- * See @Element.select
- \*/
- Fragment.prototype.select = elproto.select;
- /*\
- * Fragment.selectAll
- [ method ]
- **
- * See @Element.selectAll
- \*/
- Fragment.prototype.selectAll = elproto.selectAll;
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var objectToString = Object.prototype.toString,
- Str = String,
- math = Math,
- E = "";
- function Matrix(a, b, c, d, e, f) {
- if (b == null && objectToString.call(a) == "[object SVGMatrix]") {
- this.a = a.a;
- this.b = a.b;
- this.c = a.c;
- this.d = a.d;
- this.e = a.e;
- this.f = a.f;
- return;
- }
- if (a != null) {
- this.a = +a;
- this.b = +b;
- this.c = +c;
- this.d = +d;
- this.e = +e;
- this.f = +f;
- } else {
- this.a = 1;
- this.b = 0;
- this.c = 0;
- this.d = 1;
- this.e = 0;
- this.f = 0;
- }
- }
- (function (matrixproto) {
- /*\
- * Matrix.add
- [ method ]
- **
- * Adds the given matrix to existing one
- - a (number)
- - b (number)
- - c (number)
- - d (number)
- - e (number)
- - f (number)
- * or
- - matrix (object) @Matrix
- \*/
- matrixproto.add = function (a, b, c, d, e, f) {
- var out = [[], [], []],
- m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
- matrix = [[a, c, e], [b, d, f], [0, 0, 1]],
- x, y, z, res;
-
- if (a && a instanceof Matrix) {
- matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];
- }
-
- for (x = 0; x < 3; x++) {
- for (y = 0; y < 3; y++) {
- res = 0;
- for (z = 0; z < 3; z++) {
- res += m[x][z] * matrix[z][y];
- }
- out[x][y] = res;
- }
- }
- this.a = out[0][0];
- this.b = out[1][0];
- this.c = out[0][1];
- this.d = out[1][1];
- this.e = out[0][2];
- this.f = out[1][2];
- return this;
- };
- /*\
- * Matrix.invert
- [ method ]
- **
- * Returns an inverted version of the matrix
- = (object) @Matrix
- \*/
- matrixproto.invert = function () {
- var me = this,
- x = me.a * me.d - me.b * me.c;
- return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
- };
- /*\
- * Matrix.clone
- [ method ]
- **
- * Returns a copy of the matrix
- = (object) @Matrix
- \*/
- matrixproto.clone = function () {
- return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
- };
- /*\
- * Matrix.translate
- [ method ]
- **
- * Translate the matrix
- - x (number) horizontal offset distance
- - y (number) vertical offset distance
- \*/
- matrixproto.translate = function (x, y) {
- return this.add(1, 0, 0, 1, x, y);
- };
- /*\
- * Matrix.scale
- [ method ]
- **
- * Scales the matrix
- - x (number) amount to be scaled, with `1` resulting in no change
- - y (number) #optional amount to scale along the vertical axis. (Otherwise `x` applies to both axes.)
- - cx (number) #optional horizontal origin point from which to scale
- - cy (number) #optional vertical origin point from which to scale
- * Default cx, cy is the middle point of the element.
- \*/
- matrixproto.scale = function (x, y, cx, cy) {
- y == null && (y = x);
- (cx || cy) && this.add(1, 0, 0, 1, cx, cy);
- this.add(x, 0, 0, y, 0, 0);
- (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
- return this;
- };
- /*\
- * Matrix.rotate
- [ method ]
- **
- * Rotates the matrix
- - a (number) angle of rotation, in degrees
- - x (number) horizontal origin point from which to rotate
- - y (number) vertical origin point from which to rotate
- \*/
- matrixproto.rotate = function (a, x, y) {
- a = Snap.rad(a);
- x = x || 0;
- y = y || 0;
- var cos = +math.cos(a).toFixed(9),
- sin = +math.sin(a).toFixed(9);
- this.add(cos, sin, -sin, cos, x, y);
- return this.add(1, 0, 0, 1, -x, -y);
- };
- /*\
- * Matrix.x
- [ method ]
- **
- * Returns x coordinate for given point after transformation described by the matrix. See also @Matrix.y
- - x (number)
- - y (number)
- = (number) x
- \*/
- matrixproto.x = function (x, y) {
- return x * this.a + y * this.c + this.e;
- };
- /*\
- * Matrix.y
- [ method ]
- **
- * Returns y coordinate for given point after transformation described by the matrix. See also @Matrix.x
- - x (number)
- - y (number)
- = (number) y
- \*/
- matrixproto.y = function (x, y) {
- return x * this.b + y * this.d + this.f;
- };
- matrixproto.get = function (i) {
- return +this[Str.fromCharCode(97 + i)].toFixed(4);
- };
- matrixproto.toString = function () {
- return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")";
- };
- matrixproto.offset = function () {
- return [this.e.toFixed(4), this.f.toFixed(4)];
- };
- function norm(a) {
- return a[0] * a[0] + a[1] * a[1];
- }
- function normalize(a) {
- var mag = math.sqrt(norm(a));
- a[0] && (a[0] /= mag);
- a[1] && (a[1] /= mag);
- }
- /*\
- * Matrix.determinant
- [ method ]
- **
- * Finds determinant of the given matrix.
- = (number) determinant
- \*/
- matrixproto.determinant = function () {
- return this.a * this.d - this.b * this.c;
- };
- /*\
- * Matrix.split
- [ method ]
- **
- * Splits matrix into primitive transformations
- = (object) in format:
- o dx (number) translation by x
- o dy (number) translation by y
- o scalex (number) scale by x
- o scaley (number) scale by y
- o shear (number) shear
- o rotate (number) rotation in deg
- o isSimple (boolean) could it be represented via simple transformations
- \*/
- matrixproto.split = function () {
- var out = {};
- // translation
- out.dx = this.e;
- out.dy = this.f;
-
- // scale and shear
- var row = [[this.a, this.c], [this.b, this.d]];
- out.scalex = math.sqrt(norm(row[0]));
- normalize(row[0]);
-
- out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
- row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];
-
- out.scaley = math.sqrt(norm(row[1]));
- normalize(row[1]);
- out.shear /= out.scaley;
-
- if (this.determinant() < 0) {
- out.scalex = -out.scalex;
- }
-
- // rotation
- var sin = -row[0][1],
- cos = row[1][1];
- if (cos < 0) {
- out.rotate = Snap.deg(math.acos(cos));
- if (sin < 0) {
- out.rotate = 360 - out.rotate;
- }
- } else {
- out.rotate = Snap.deg(math.asin(sin));
- }
-
- out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);
- out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;
- out.noRotation = !+out.shear.toFixed(9) && !out.rotate;
- return out;
- };
- /*\
- * Matrix.toTransformString
- [ method ]
- **
- * Returns transform string that represents given matrix
- = (string) transform string
- \*/
- matrixproto.toTransformString = function (shorter) {
- var s = shorter || this.split();
- if (!+s.shear.toFixed(9)) {
- s.scalex = +s.scalex.toFixed(4);
- s.scaley = +s.scaley.toFixed(4);
- s.rotate = +s.rotate.toFixed(4);
- return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) +
- (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) +
- (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E);
- } else {
- return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];
- }
- };
- })(Matrix.prototype);
- /*\
- * Snap.Matrix
- [ method ]
- **
- * Matrix constructor, extend on your own risk.
- * To create matrices use @Snap.matrix.
- \*/
- Snap.Matrix = Matrix;
- /*\
- * Snap.matrix
- [ method ]
- **
- * Utility method
- **
- * Returns a matrix based on the given parameters
- - a (number)
- - b (number)
- - c (number)
- - d (number)
- - e (number)
- - f (number)
- * or
- - svgMatrix (SVGMatrix)
- = (object) @Matrix
- \*/
- Snap.matrix = function (a, b, c, d, e, f) {
- return new Matrix(a, b, c, d, e, f);
- };
- });
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var has = "hasOwnProperty",
- make = Snap._.make,
- wrap = Snap._.wrap,
- is = Snap.is,
- getSomeDefs = Snap._.getSomeDefs,
- reURLValue = /^url\(#?([^)]+)\)$/,
- $ = Snap._.$,
- URL = Snap.url,
- Str = String,
- separator = Snap._.separator,
- E = "";
- // Attributes event handlers
- eve.on("snap.util.attr.mask", function (value) {
- if (value instanceof Element || value instanceof Fragment) {
- eve.stop();
- if (value instanceof Fragment && value.node.childNodes.length == 1) {
- value = value.node.firstChild;
- getSomeDefs(this).appendChild(value);
- value = wrap(value);
- }
- if (value.type == "mask") {
- var mask = value;
- } else {
- mask = make("mask", getSomeDefs(this));
- mask.node.appendChild(value.node);
- }
- !mask.node.id && $(mask.node, {
- id: mask.id
- });
- $(this.node, {
- mask: URL(mask.id)
- });
- }
- });
- (function (clipIt) {
- eve.on("snap.util.attr.clip", clipIt);
- eve.on("snap.util.attr.clip-path", clipIt);
- eve.on("snap.util.attr.clipPath", clipIt);
- }(function (value) {
- if (value instanceof Element || value instanceof Fragment) {
- eve.stop();
- if (value.type == "clipPath") {
- var clip = value;
- } else {
- clip = make("clipPath", getSomeDefs(this));
- clip.node.appendChild(value.node);
- !clip.node.id && $(clip.node, {
- id: clip.id
- });
- }
- $(this.node, {
- "clip-path": URL(clip.node.id || clip.id)
- });
- }
- }));
- function fillStroke(name) {
- return function (value) {
- eve.stop();
- if (value instanceof Fragment && value.node.childNodes.length == 1 &&
- (value.node.firstChild.tagName == "radialGradient" ||
- value.node.firstChild.tagName == "linearGradient" ||
- value.node.firstChild.tagName == "pattern")) {
- value = value.node.firstChild;
- getSomeDefs(this).appendChild(value);
- value = wrap(value);
- }
- if (value instanceof Element) {
- if (value.type == "radialGradient" || value.type == "linearGradient"
- || value.type == "pattern") {
- if (!value.node.id) {
- $(value.node, {
- id: value.id
- });
- }
- var fill = URL(value.node.id);
- } else {
- fill = value.attr(name);
- }
- } else {
- fill = Snap.color(value);
- if (fill.error) {
- var grad = Snap(getSomeDefs(this).ownerSVGElement).gradient(value);
- if (grad) {
- if (!grad.node.id) {
- $(grad.node, {
- id: grad.id
- });
- }
- fill = URL(grad.node.id);
- } else {
- fill = value;
- }
- } else {
- fill = Str(fill);
- }
- }
- var attrs = {};
- attrs[name] = fill;
- $(this.node, attrs);
- this.node.style[name] = E;
- };
- }
- eve.on("snap.util.attr.fill", fillStroke("fill"));
- eve.on("snap.util.attr.stroke", fillStroke("stroke"));
- var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i;
- eve.on("snap.util.grad.parse", function parseGrad(string) {
- string = Str(string);
- var tokens = string.match(gradrg);
- if (!tokens) {
- return null;
- }
- var type = tokens[1],
- params = tokens[2],
- stops = tokens[3];
- params = params.split(/\s*,\s*/).map(function (el) {
- return +el == el ? +el : el;
- });
- if (params.length == 1 && params[0] == 0) {
- params = [];
- }
- stops = stops.split("-");
- stops = stops.map(function (el) {
- el = el.split(":");
- var out = {
- color: el[0]
- };
- if (el[1]) {
- out.offset = parseFloat(el[1]);
- }
- return out;
- });
- return {
- type: type,
- params: params,
- stops: stops
- };
- });
-
- eve.on("snap.util.attr.d", function (value) {
- eve.stop();
- if (is(value, "array") && is(value[0], "array")) {
- value = Snap.path.toString.call(value);
- }
- value = Str(value);
- if (value.match(/[ruo]/i)) {
- value = Snap.path.toAbsolute(value);
- }
- $(this.node, {d: value});
- })(-1);
- eve.on("snap.util.attr.#text", function (value) {
- eve.stop();
- value = Str(value);
- var txt = glob.doc.createTextNode(value);
- while (this.node.firstChild) {
- this.node.removeChild(this.node.firstChild);
- }
- this.node.appendChild(txt);
- })(-1);
- eve.on("snap.util.attr.path", function (value) {
- eve.stop();
- this.attr({d: value});
- })(-1);
- eve.on("snap.util.attr.class", function (value) {
- eve.stop();
- this.node.className.baseVal = value;
- })(-1);
- eve.on("snap.util.attr.viewBox", function (value) {
- var vb;
- if (is(value, "object") && "x" in value) {
- vb = [value.x, value.y, value.width, value.height].join(" ");
- } else if (is(value, "array")) {
- vb = value.join(" ");
- } else {
- vb = value;
- }
- $(this.node, {
- viewBox: vb
- });
- eve.stop();
- })(-1);
- eve.on("snap.util.attr.transform", function (value) {
- this.transform(value);
- eve.stop();
- })(-1);
- eve.on("snap.util.attr.r", function (value) {
- if (this.type == "rect") {
- eve.stop();
- $(this.node, {
- rx: value,
- ry: value
- });
- }
- })(-1);
- eve.on("snap.util.attr.textpath", function (value) {
- eve.stop();
- if (this.type == "text") {
- var id, tp, node;
- if (!value && this.textPath) {
- tp = this.textPath;
- while (tp.node.firstChild) {
- this.node.appendChild(tp.node.firstChild);
- }
- tp.remove();
- delete this.textPath;
- return;
- }
- if (is(value, "string")) {
- var defs = getSomeDefs(this),
- path = wrap(defs.parentNode).path(value);
- defs.appendChild(path.node);
- id = path.id;
- path.attr({id: id});
- } else {
- value = wrap(value);
- if (value instanceof Element) {
- id = value.attr("id");
- if (!id) {
- id = value.id;
- value.attr({id: id});
- }
- }
- }
- if (id) {
- tp = this.textPath;
- node = this.node;
- if (tp) {
- tp.attr({"xlink:href": "#" + id});
- } else {
- tp = $("textPath", {
- "xlink:href": "#" + id
- });
- while (node.firstChild) {
- tp.appendChild(node.firstChild);
- }
- node.appendChild(tp);
- this.textPath = wrap(tp);
- }
- }
- }
- })(-1);
- eve.on("snap.util.attr.text", function (value) {
- if (this.type == "text") {
- var i = 0,
- node = this.node,
- tuner = function (chunk) {
- var out = $("tspan");
- if (is(chunk, "array")) {
- for (var i = 0; i < chunk.length; i++) {
- out.appendChild(tuner(chunk[i]));
- }
- } else {
- out.appendChild(glob.doc.createTextNode(chunk));
- }
- out.normalize && out.normalize();
- return out;
- };
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
- var tuned = tuner(value);
- while (tuned.firstChild) {
- node.appendChild(tuned.firstChild);
- }
- }
- eve.stop();
- })(-1);
- function setFontSize(value) {
- eve.stop();
- if (value == +value) {
- value += "px";
- }
- this.node.style.fontSize = value;
- }
- eve.on("snap.util.attr.fontSize", setFontSize)(-1);
- eve.on("snap.util.attr.font-size", setFontSize)(-1);
-
-
- eve.on("snap.util.getattr.transform", function () {
- eve.stop();
- return this.transform();
- })(-1);
- eve.on("snap.util.getattr.textpath", function () {
- eve.stop();
- return this.textPath;
- })(-1);
- // Markers
- (function () {
- function getter(end) {
- return function () {
- eve.stop();
- var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end);
- if (style == "none") {
- return style;
- } else {
- return Snap(glob.doc.getElementById(style.match(reURLValue)[1]));
- }
- };
- }
- function setter(end) {
- return function (value) {
- eve.stop();
- var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1);
- if (value == "" || !value) {
- this.node.style[name] = "none";
- return;
- }
- if (value.type == "marker") {
- var id = value.node.id;
- if (!id) {
- $(value.node, {id: value.id});
- }
- this.node.style[name] = URL(id);
- return;
- }
- };
- }
- eve.on("snap.util.getattr.marker-end", getter("end"))(-1);
- eve.on("snap.util.getattr.markerEnd", getter("end"))(-1);
- eve.on("snap.util.getattr.marker-start", getter("start"))(-1);
- eve.on("snap.util.getattr.markerStart", getter("start"))(-1);
- eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1);
- eve.on("snap.util.getattr.markerMid", getter("mid"))(-1);
- eve.on("snap.util.attr.marker-end", setter("end"))(-1);
- eve.on("snap.util.attr.markerEnd", setter("end"))(-1);
- eve.on("snap.util.attr.marker-start", setter("start"))(-1);
- eve.on("snap.util.attr.markerStart", setter("start"))(-1);
- eve.on("snap.util.attr.marker-mid", setter("mid"))(-1);
- eve.on("snap.util.attr.markerMid", setter("mid"))(-1);
- }());
- eve.on("snap.util.getattr.r", function () {
- if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
- eve.stop();
- return $(this.node, "rx");
- }
- })(-1);
- function textExtract(node) {
- var out = [];
- var children = node.childNodes;
- for (var i = 0, ii = children.length; i < ii; i++) {
- var chi = children[i];
- if (chi.nodeType == 3) {
- out.push(chi.nodeValue);
- }
- if (chi.tagName == "tspan") {
- if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) {
- out.push(chi.firstChild.nodeValue);
- } else {
- out.push(textExtract(chi));
- }
- }
- }
- return out;
- }
- eve.on("snap.util.getattr.text", function () {
- if (this.type == "text" || this.type == "tspan") {
- eve.stop();
- var out = textExtract(this.node);
- return out.length == 1 ? out[0] : out;
- }
- })(-1);
- eve.on("snap.util.getattr.#text", function () {
- return this.node.textContent;
- })(-1);
- eve.on("snap.util.getattr.viewBox", function () {
- eve.stop();
- var vb = $(this.node, "viewBox");
- if (vb) {
- vb = vb.split(separator);
- return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]);
- } else {
- return;
- }
- })(-1);
- eve.on("snap.util.getattr.points", function () {
- var p = $(this.node, "points");
- eve.stop();
- if (p) {
- return p.split(separator);
- } else {
- return;
- }
- })(-1);
- eve.on("snap.util.getattr.path", function () {
- var p = $(this.node, "d");
- eve.stop();
- return p;
- })(-1);
- eve.on("snap.util.getattr.class", function () {
- return this.node.className.baseVal;
- })(-1);
- function getFontSize() {
- eve.stop();
- return this.node.style.fontSize;
- }
- eve.on("snap.util.getattr.fontSize", getFontSize)(-1);
- eve.on("snap.util.getattr.font-size", getFontSize)(-1);
- });
-
- // Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var rgNotSpace = /\S+/g,
- rgBadSpace = /[\t\r\n\f]/g,
- rgTrim = /(^\s+|\s+$)/g,
- Str = String,
- elproto = Element.prototype;
- /*\
- * Element.addClass
- [ method ]
- **
- * Adds given class name or list of class names to the element.
- - value (string) class name or space separated list of class names
- **
- = (Element) original element.
- \*/
- elproto.addClass = function (value) {
- var classes = Str(value || "").match(rgNotSpace) || [],
- elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [],
- j,
- pos,
- clazz,
- finalValue;
-
- if (classes.length) {
- j = 0;
- while ((clazz = classes[j++])) {
- pos = curClasses.indexOf(clazz);
- if (!~pos) {
- curClasses.push(clazz);
- }
- }
-
- finalValue = curClasses.join(" ");
- if (className != finalValue) {
- elem.className.baseVal = finalValue;
- }
- }
- return this;
- };
- /*\
- * Element.removeClass
- [ method ]
- **
- * Removes given class name or list of class names from the element.
- - value (string) class name or space separated list of class names
- **
- = (Element) original element.
- \*/
- elproto.removeClass = function (value) {
- var classes = Str(value || "").match(rgNotSpace) || [],
- elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [],
- j,
- pos,
- clazz,
- finalValue;
- if (curClasses.length) {
- j = 0;
- while ((clazz = classes[j++])) {
- pos = curClasses.indexOf(clazz);
- if (~pos) {
- curClasses.splice(pos, 1);
- }
- }
-
- finalValue = curClasses.join(" ");
- if (className != finalValue) {
- elem.className.baseVal = finalValue;
- }
- }
- return this;
- };
- /*\
- * Element.hasClass
- [ method ]
- **
- * Checks if the element has a given class name in the list of class names applied to it.
- - value (string) class name
- **
- = (boolean) `true` if the element has given class
- \*/
- elproto.hasClass = function (value) {
- var elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [];
- return !!~curClasses.indexOf(value);
- };
- /*\
- * Element.toggleClass
- [ method ]
- **
- * Add or remove one or more classes from the element, depending on either
- * the class’s presence or the value of the `flag` argument.
- - value (string) class name or space separated list of class names
- - flag (boolean) value to determine whether the class should be added or removed
- **
- = (Element) original element.
- \*/
- elproto.toggleClass = function (value, flag) {
- if (flag != null) {
- if (flag) {
- return this.addClass(value);
- } else {
- return this.removeClass(value);
- }
- }
- var classes = (value || "").match(rgNotSpace) || [],
- elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [],
- j,
- pos,
- clazz,
- finalValue;
- j = 0;
- while ((clazz = classes[j++])) {
- pos = curClasses.indexOf(clazz);
- if (~pos) {
- curClasses.splice(pos, 1);
- } else {
- curClasses.push(clazz);
- }
- }
-
- finalValue = curClasses.join(" ");
- if (className != finalValue) {
- elem.className.baseVal = finalValue;
- }
- return this;
- };
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var operators = {
- "+": function (x, y) {
- return x + y;
- },
- "-": function (x, y) {
- return x - y;
- },
- "/": function (x, y) {
- return x / y;
- },
- "*": function (x, y) {
- return x * y;
- }
- },
- Str = String,
- reUnit = /[a-z]+$/i,
- reAddon = /^\s*([+\-\/*])\s*=\s*([\d.eE+\-]+)\s*([^\d\s]+)?\s*$/;
- function getNumber(val) {
- return val;
- }
- function getUnit(unit) {
- return function (val) {
- return +val.toFixed(3) + unit;
- };
- }
- eve.on("snap.util.attr", function (val) {
- var plus = Str(val).match(reAddon);
- if (plus) {
- var evnt = eve.nt(),
- name = evnt.substring(evnt.lastIndexOf(".") + 1),
- a = this.attr(name),
- atr = {};
- eve.stop();
- var unit = plus[3] || "",
- aUnit = a.match(reUnit),
- op = operators[plus[1]];
- if (aUnit && aUnit == unit) {
- val = op(parseFloat(a), +plus[2]);
- } else {
- a = this.asPX(name);
- val = op(this.asPX(name), this.asPX(name, plus[2] + unit));
- }
- if (isNaN(a) || isNaN(val)) {
- return;
- }
- atr[name] = val;
- this.attr(atr);
- }
- })(-10);
- eve.on("snap.util.equal", function (name, b) {
- var A, B, a = Str(this.attr(name) || ""),
- el = this,
- bplus = Str(b).match(reAddon);
- if (bplus) {
- eve.stop();
- var unit = bplus[3] || "",
- aUnit = a.match(reUnit),
- op = operators[bplus[1]];
- if (aUnit && aUnit == unit) {
- return {
- from: parseFloat(a),
- to: op(parseFloat(a), +bplus[2]),
- f: getUnit(aUnit)
- };
- } else {
- a = this.asPX(name);
- return {
- from: a,
- to: op(a, this.asPX(name, bplus[2] + unit)),
- f: getNumber
- };
- }
- }
- })(-10);
- });
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var proto = Paper.prototype,
- is = Snap.is;
- /*\
- * Paper.rect
- [ method ]
- *
- * Draws a rectangle
- **
- - x (number) x coordinate of the top left corner
- - y (number) y coordinate of the top left corner
- - width (number) width
- - height (number) height
- - rx (number) #optional horizontal radius for rounded corners, default is 0
- - ry (number) #optional vertical radius for rounded corners, default is rx or 0
- = (object) the `rect` element
- **
- > Usage
- | // regular rectangle
- | var c = paper.rect(10, 10, 50, 50);
- | // rectangle with rounded corners
- | var c = paper.rect(40, 40, 50, 50, 10);
- \*/
- proto.rect = function (x, y, w, h, rx, ry) {
- var attr;
- if (ry == null) {
- ry = rx;
- }
- if (is(x, "object") && x == "[object Object]") {
- attr = x;
- } else if (x != null) {
- attr = {
- x: x,
- y: y,
- width: w,
- height: h
- };
- if (rx != null) {
- attr.rx = rx;
- attr.ry = ry;
- }
- }
- return this.el("rect", attr);
- };
- /*\
- * Paper.circle
- [ method ]
- **
- * Draws a circle
- **
- - x (number) x coordinate of the centre
- - y (number) y coordinate of the centre
- - r (number) radius
- = (object) the `circle` element
- **
- > Usage
- | var c = paper.circle(50, 50, 40);
- \*/
- proto.circle = function (cx, cy, r) {
- var attr;
- if (is(cx, "object") && cx == "[object Object]") {
- attr = cx;
- } else if (cx != null) {
- attr = {
- cx: cx,
- cy: cy,
- r: r
- };
- }
- return this.el("circle", attr);
- };
-
- var preload = (function () {
- function onerror() {
- this.parentNode.removeChild(this);
- }
- return function (src, f) {
- var img = glob.doc.createElement("img"),
- body = glob.doc.body;
- img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
- img.onload = function () {
- f.call(img);
- img.onload = img.onerror = null;
- body.removeChild(img);
- };
- img.onerror = onerror;
- body.appendChild(img);
- img.src = src;
- };
- }());
-
- /*\
- * Paper.image
- [ method ]
- **
- * Places an image on the surface
- **
- - src (string) URI of the source image
- - x (number) x offset position
- - y (number) y offset position
- - width (number) width of the image
- - height (number) height of the image
- = (object) the `image` element
- * or
- = (object) Snap element object with type `image`
- **
- > Usage
- | var c = paper.image("apple.png", 10, 10, 80, 80);
- \*/
- proto.image = function (src, x, y, width, height) {
- var el = this.el("image");
- if (is(src, "object") && "src" in src) {
- el.attr(src);
- } else if (src != null) {
- var set = {
- "xlink:href": src,
- preserveAspectRatio: "none"
- };
- if (x != null && y != null) {
- set.x = x;
- set.y = y;
- }
- if (width != null && height != null) {
- set.width = width;
- set.height = height;
- } else {
- preload(src, function () {
- Snap._.$(el.node, {
- width: this.offsetWidth,
- height: this.offsetHeight
- });
- });
- }
- Snap._.$(el.node, set);
- }
- return el;
- };
- /*\
- * Paper.ellipse
- [ method ]
- **
- * Draws an ellipse
- **
- - x (number) x coordinate of the centre
- - y (number) y coordinate of the centre
- - rx (number) horizontal radius
- - ry (number) vertical radius
- = (object) the `ellipse` element
- **
- > Usage
- | var c = paper.ellipse(50, 50, 40, 20);
- \*/
- proto.ellipse = function (cx, cy, rx, ry) {
- var attr;
- if (is(cx, "object") && cx == "[object Object]") {
- attr = cx;
- } else if (cx != null) {
- attr ={
- cx: cx,
- cy: cy,
- rx: rx,
- ry: ry
- };
- }
- return this.el("ellipse", attr);
- };
- // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is, and why it would make life any easier.
- /*\
- * Paper.path
- [ method ]
- **
- * Creates a `<path>` element using the given string as the path's definition
- - pathString (string) #optional path string in SVG format
- * Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example:
- | "M10,20L30,40"
- * This example features two commands: `M`, with arguments `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates.
- *
- # <p>Here is short list of commands available, for more details see <a href="http://www.w3.org/TR/SVG/paths.html#PathData" title="Details of a path's data attribute's format are described in the SVG specification.">SVG path string format</a> or <a href="https://developer.mozilla.org/en/SVG/Tutorial/Paths">article about path strings at MDN</a>.</p>
- # <table><thead><tr><th>Command</th><th>Name</th><th>Parameters</th></tr></thead><tbody>
- # <tr><td>M</td><td>moveto</td><td>(x y)+</td></tr>
- # <tr><td>Z</td><td>closepath</td><td>(none)</td></tr>
- # <tr><td>L</td><td>lineto</td><td>(x y)+</td></tr>
- # <tr><td>H</td><td>horizontal lineto</td><td>x+</td></tr>
- # <tr><td>V</td><td>vertical lineto</td><td>y+</td></tr>
- # <tr><td>C</td><td>curveto</td><td>(x1 y1 x2 y2 x y)+</td></tr>
- # <tr><td>S</td><td>smooth curveto</td><td>(x2 y2 x y)+</td></tr>
- # <tr><td>Q</td><td>quadratic Bézier curveto</td><td>(x1 y1 x y)+</td></tr>
- # <tr><td>T</td><td>smooth quadratic Bézier curveto</td><td>(x y)+</td></tr>
- # <tr><td>A</td><td>elliptical arc</td><td>(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+</td></tr>
- # <tr><td>R</td><td><a href="http://en.wikipedia.org/wiki/Catmull–Rom_spline#Catmull.E2.80.93Rom_spline">Catmull-Rom curveto</a>*</td><td>x1 y1 (x y)+</td></tr></tbody></table>
- * * _Catmull-Rom curveto_ is a not standard SVG command and added to make life easier.
- * Note: there is a special case when a path consists of only three commands: `M10,10R…z`. In this case the path connects back to its starting point.
- > Usage
- | var c = paper.path("M10 10L90 90");
- | // draw a diagonal line:
- | // move to 10,10, line to 90,90
- \*/
- proto.path = function (d) {
- var attr;
- if (is(d, "object") && !is(d, "array")) {
- attr = d;
- } else if (d) {
- attr = {d: d};
- }
- return this.el("path", attr);
- };
- /*\
- * Paper.g
- [ method ]
- **
- * Creates a group element
- **
- - varargs (…) #optional elements to nest within the group
- = (object) the `g` element
- **
- > Usage
- | var c1 = paper.circle(),
- | c2 = paper.rect(),
- | g = paper.g(c2, c1); // note that the order of elements is different
- * or
- | var c1 = paper.circle(),
- | c2 = paper.rect(),
- | g = paper.g();
- | g.add(c2, c1);
- \*/
- /*\
- * Paper.group
- [ method ]
- **
- * See @Paper.g
- \*/
- proto.group = proto.g = function (first) {
- var attr,
- el = this.el("g");
- if (arguments.length == 1 && first && !first.type) {
- el.attr(first);
- } else if (arguments.length) {
- el.add(Array.prototype.slice.call(arguments, 0));
- }
- return el;
- };
- /*\
- * Paper.svg
- [ method ]
- **
- * Creates a nested SVG element.
- - x (number) @optional X of the element
- - y (number) @optional Y of the element
- - width (number) @optional width of the element
- - height (number) @optional height of the element
- - vbx (number) @optional viewbox X
- - vby (number) @optional viewbox Y
- - vbw (number) @optional viewbox width
- - vbh (number) @optional viewbox height
- **
- = (object) the `svg` element
- **
- \*/
- proto.svg = function (x, y, width, height, vbx, vby, vbw, vbh) {
- var attrs = {};
- if (is(x, "object") && y == null) {
- attrs = x;
- } else {
- if (x != null) {
- attrs.x = x;
- }
- if (y != null) {
- attrs.y = y;
- }
- if (width != null) {
- attrs.width = width;
- }
- if (height != null) {
- attrs.height = height;
- }
- if (vbx != null && vby != null && vbw != null && vbh != null) {
- attrs.viewBox = [vbx, vby, vbw, vbh];
- }
- }
- return this.el("svg", attrs);
- };
- /*\
- * Paper.mask
- [ method ]
- **
- * Equivalent in behaviour to @Paper.g, except it’s a mask.
- **
- = (object) the `mask` element
- **
- \*/
- proto.mask = function (first) {
- var attr,
- el = this.el("mask");
- if (arguments.length == 1 && first && !first.type) {
- el.attr(first);
- } else if (arguments.length) {
- el.add(Array.prototype.slice.call(arguments, 0));
- }
- return el;
- };
- /*\
- * Paper.ptrn
- [ method ]
- **
- * Equivalent in behaviour to @Paper.g, except it’s a pattern.
- - x (number) @optional X of the element
- - y (number) @optional Y of the element
- - width (number) @optional width of the element
- - height (number) @optional height of the element
- - vbx (number) @optional viewbox X
- - vby (number) @optional viewbox Y
- - vbw (number) @optional viewbox width
- - vbh (number) @optional viewbox height
- **
- = (object) the `pattern` element
- **
- \*/
- proto.ptrn = function (x, y, width, height, vx, vy, vw, vh) {
- if (is(x, "object")) {
- var attr = x;
- } else {
- attr = {patternUnits: "userSpaceOnUse"};
- if (x) {
- attr.x = x;
- }
- if (y) {
- attr.y = y;
- }
- if (width != null) {
- attr.width = width;
- }
- if (height != null) {
- attr.height = height;
- }
- if (vx != null && vy != null && vw != null && vh != null) {
- attr.viewBox = [vx, vy, vw, vh];
- } else {
- attr.viewBox = [x || 0, y || 0, width || 0, height || 0];
- }
- }
- return this.el("pattern", attr);
- };
- /*\
- * Paper.use
- [ method ]
- **
- * Creates a <use> element.
- - id (string) @optional id of element to link
- * or
- - id (Element) @optional element to link
- **
- = (object) the `use` element
- **
- \*/
- proto.use = function (id) {
- if (id != null) {
- if (id instanceof Element) {
- if (!id.attr("id")) {
- id.attr({id: Snap._.id(id)});
- }
- id = id.attr("id");
- }
- if (String(id).charAt() == "#") {
- id = id.substring(1);
- }
- return this.el("use", {"xlink:href": "#" + id});
- } else {
- return Element.prototype.use.call(this);
- }
- };
- /*\
- * Paper.symbol
- [ method ]
- **
- * Creates a <symbol> element.
- - vbx (number) @optional viewbox X
- - vby (number) @optional viewbox Y
- - vbw (number) @optional viewbox width
- - vbh (number) @optional viewbox height
- = (object) the `symbol` element
- **
- \*/
- proto.symbol = function (vx, vy, vw, vh) {
- var attr = {};
- if (vx != null && vy != null && vw != null && vh != null) {
- attr.viewBox = [vx, vy, vw, vh];
- }
-
- return this.el("symbol", attr);
- };
- /*\
- * Paper.text
- [ method ]
- **
- * Draws a text string
- **
- - x (number) x coordinate position
- - y (number) y coordinate position
- - text (string|array) The text string to draw or array of strings to nest within separate `<tspan>` elements
- = (object) the `text` element
- **
- > Usage
- | var t1 = paper.text(50, 50, "Snap");
- | var t2 = paper.text(50, 50, ["S","n","a","p"]);
- | // Text path usage
- | t1.attr({textpath: "M10,10L100,100"});
- | // or
- | var pth = paper.path("M10,10L100,100");
- | t1.attr({textpath: pth});
- \*/
- proto.text = function (x, y, text) {
- var attr = {};
- if (is(x, "object")) {
- attr = x;
- } else if (x != null) {
- attr = {
- x: x,
- y: y,
- text: text || ""
- };
- }
- return this.el("text", attr);
- };
- /*\
- * Paper.line
- [ method ]
- **
- * Draws a line
- **
- - x1 (number) x coordinate position of the start
- - y1 (number) y coordinate position of the start
- - x2 (number) x coordinate position of the end
- - y2 (number) y coordinate position of the end
- = (object) the `line` element
- **
- > Usage
- | var t1 = paper.line(50, 50, 100, 100);
- \*/
- proto.line = function (x1, y1, x2, y2) {
- var attr = {};
- if (is(x1, "object")) {
- attr = x1;
- } else if (x1 != null) {
- attr = {
- x1: x1,
- x2: x2,
- y1: y1,
- y2: y2
- };
- }
- return this.el("line", attr);
- };
- /*\
- * Paper.polyline
- [ method ]
- **
- * Draws a polyline
- **
- - points (array) array of points
- * or
- - varargs (…) points
- = (object) the `polyline` element
- **
- > Usage
- | var p1 = paper.polyline([10, 10, 100, 100]);
- | var p2 = paper.polyline(10, 10, 100, 100);
- \*/
- proto.polyline = function (points) {
- if (arguments.length > 1) {
- points = Array.prototype.slice.call(arguments, 0);
- }
- var attr = {};
- if (is(points, "object") && !is(points, "array")) {
- attr = points;
- } else if (points != null) {
- attr = {points: points};
- }
- return this.el("polyline", attr);
- };
- /*\
- * Paper.polygon
- [ method ]
- **
- * Draws a polygon. See @Paper.polyline
- \*/
- proto.polygon = function (points) {
- if (arguments.length > 1) {
- points = Array.prototype.slice.call(arguments, 0);
- }
- var attr = {};
- if (is(points, "object") && !is(points, "array")) {
- attr = points;
- } else if (points != null) {
- attr = {points: points};
- }
- return this.el("polygon", attr);
- };
- // gradients
- (function () {
- var $ = Snap._.$;
- // gradients' helpers
- function Gstops() {
- return this.selectAll("stop");
- }
- function GaddStop(color, offset) {
- var stop = $("stop"),
- attr = {
- offset: +offset + "%"
- };
- color = Snap.color(color);
- attr["stop-color"] = color.hex;
- if (color.opacity < 1) {
- attr["stop-opacity"] = color.opacity;
- }
- $(stop, attr);
- this.node.appendChild(stop);
- return this;
- }
- function GgetBBox() {
- if (this.type == "linearGradient") {
- var x1 = $(this.node, "x1") || 0,
- x2 = $(this.node, "x2") || 1,
- y1 = $(this.node, "y1") || 0,
- y2 = $(this.node, "y2") || 0;
- return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1));
- } else {
- var cx = this.node.cx || .5,
- cy = this.node.cy || .5,
- r = this.node.r || 0;
- return Snap._.box(cx - r, cy - r, r * 2, r * 2);
- }
- }
- function gradient(defs, str) {
- var grad = eve("snap.util.grad.parse", null, str).firstDefined(),
- el;
- if (!grad) {
- return null;
- }
- grad.params.unshift(defs);
- if (grad.type.toLowerCase() == "l") {
- el = gradientLinear.apply(0, grad.params);
- } else {
- el = gradientRadial.apply(0, grad.params);
- }
- if (grad.type != grad.type.toLowerCase()) {
- $(el.node, {
- gradientUnits: "userSpaceOnUse"
- });
- }
- var stops = grad.stops,
- len = stops.length,
- start = 0,
- j = 0;
- function seed(i, end) {
- var step = (end - start) / (i - j);
- for (var k = j; k < i; k++) {
- stops[k].offset = +(+start + step * (k - j)).toFixed(2);
- }
- j = i;
- start = end;
- }
- len--;
- for (var i = 0; i < len; i++) if ("offset" in stops[i]) {
- seed(i, stops[i].offset);
- }
- stops[len].offset = stops[len].offset || 100;
- seed(len, stops[len].offset);
- for (i = 0; i <= len; i++) {
- var stop = stops[i];
- el.addStop(stop.color, stop.offset);
- }
- return el;
- }
- function gradientLinear(defs, x1, y1, x2, y2) {
- var el = Snap._.make("linearGradient", defs);
- el.stops = Gstops;
- el.addStop = GaddStop;
- el.getBBox = GgetBBox;
- if (x1 != null) {
- $(el.node, {
- x1: x1,
- y1: y1,
- x2: x2,
- y2: y2
- });
- }
- return el;
- }
- function gradientRadial(defs, cx, cy, r, fx, fy) {
- var el = Snap._.make("radialGradient", defs);
- el.stops = Gstops;
- el.addStop = GaddStop;
- el.getBBox = GgetBBox;
- if (cx != null) {
- $(el.node, {
- cx: cx,
- cy: cy,
- r: r
- });
- }
- if (fx != null && fy != null) {
- $(el.node, {
- fx: fx,
- fy: fy
- });
- }
- return el;
- }
- /*\
- * Paper.gradient
- [ method ]
- **
- * Creates a gradient element
- **
- - gradient (string) gradient descriptor
- > Gradient Descriptor
- * The gradient descriptor is an expression formatted as
- * follows: `<type>(<coords>)<colors>`. The `<type>` can be
- * either linear or radial. The uppercase `L` or `R` letters
- * indicate absolute coordinates offset from the SVG surface.
- * Lowercase `l` or `r` letters indicate coordinates
- * calculated relative to the element to which the gradient is
- * applied. Coordinates specify a linear gradient vector as
- * `x1`, `y1`, `x2`, `y2`, or a radial gradient as `cx`, `cy`,
- * `r` and optional `fx`, `fy` specifying a focal point away
- * from the center of the circle. Specify `<colors>` as a list
- * of dash-separated CSS color values. Each color may be
- * followed by a custom offset value, separated with a colon
- * character.
- > Examples
- * Linear gradient, relative from top-left corner to bottom-right
- * corner, from black through red to white:
- | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
- * Linear gradient, absolute from (0, 0) to (100, 100), from black
- * through red at 25% to white:
- | var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff");
- * Radial gradient, relative from the center of the element with radius
- * half the width, from black to white:
- | var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff");
- * To apply the gradient:
- | paper.circle(50, 50, 40).attr({
- | fill: g
- | });
- = (object) the `gradient` element
- \*/
- proto.gradient = function (str) {
- return gradient(this.defs, str);
- };
- proto.gradientLinear = function (x1, y1, x2, y2) {
- return gradientLinear(this.defs, x1, y1, x2, y2);
- };
- proto.gradientRadial = function (cx, cy, r, fx, fy) {
- return gradientRadial(this.defs, cx, cy, r, fx, fy);
- };
- /*\
- * Paper.toString
- [ method ]
- **
- * Returns SVG code for the @Paper
- = (string) SVG code for the @Paper
- \*/
- proto.toString = function () {
- var doc = this.node.ownerDocument,
- f = doc.createDocumentFragment(),
- d = doc.createElement("div"),
- svg = this.node.cloneNode(true),
- res;
- f.appendChild(d);
- d.appendChild(svg);
- Snap._.$(svg, {xmlns: "http://www.w3.org/2000/svg"});
- res = d.innerHTML;
- f.removeChild(f.firstChild);
- return res;
- };
- /*\
- * Paper.toDataURL
- [ method ]
- **
- * Returns SVG code for the @Paper as Data URI string.
- = (string) Data URI string
- \*/
- proto.toDataURL = function () {
- if (window && window.btoa) {
- return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(this)));
- }
- };
- /*\
- * Paper.clear
- [ method ]
- **
- * Removes all child nodes of the paper, except <defs>.
- \*/
- proto.clear = function () {
- var node = this.node.firstChild,
- next;
- while (node) {
- next = node.nextSibling;
- if (node.tagName != "defs") {
- node.parentNode.removeChild(node);
- } else {
- proto.clear.call({node: node});
- }
- node = next;
- }
- };
- }());
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob) {
- var elproto = Element.prototype,
- is = Snap.is,
- clone = Snap._.clone,
- has = "hasOwnProperty",
- p2s = /,?([a-z]),?/gi,
- toFloat = parseFloat,
- math = Math,
- PI = math.PI,
- mmin = math.min,
- mmax = math.max,
- pow = math.pow,
- abs = math.abs;
- function paths(ps) {
- var p = paths.ps = paths.ps || {};
- if (p[ps]) {
- p[ps].sleep = 100;
- } else {
- p[ps] = {
- sleep: 100
- };
- }
- setTimeout(function () {
- for (var key in p) if (p[has](key) && key != ps) {
- p[key].sleep--;
- !p[key].sleep && delete p[key];
- }
- });
- return p[ps];
- }
- function box(x, y, width, height) {
- if (x == null) {
- x = y = width = height = 0;
- }
- if (y == null) {
- y = x.y;
- width = x.width;
- height = x.height;
- x = x.x;
- }
- return {
- x: x,
- y: y,
- width: width,
- w: width,
- height: height,
- h: height,
- x2: x + width,
- y2: y + height,
- cx: x + width / 2,
- cy: y + height / 2,
- r1: math.min(width, height) / 2,
- r2: math.max(width, height) / 2,
- r0: math.sqrt(width * width + height * height) / 2,
- path: rectPath(x, y, width, height),
- vb: [x, y, width, height].join(" ")
- };
- }
- function toString() {
- return this.join(",").replace(p2s, "$1");
- }
- function pathClone(pathArray) {
- var res = clone(pathArray);
- res.toString = toString;
- return res;
- }
- function getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {
- if (length == null) {
- return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
- } else {
- return findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y,
- getTotLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length));
- }
- }
- function getLengthFactory(istotal, subpath) {
- function O(val) {
- return +(+val).toFixed(3);
- }
- return Snap._.cacher(function (path, length, onlystart) {
- if (path instanceof Element) {
- path = path.attr("d");
- }
- path = path2curve(path);
- var x, y, p, l, sp = "", subpaths = {}, point,
- len = 0;
- for (var i = 0, ii = path.length; i < ii; i++) {
- p = path[i];
- if (p[0] == "M") {
- x = +p[1];
- y = +p[2];
- } else {
- l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
- if (len + l > length) {
- if (subpath && !subpaths.start) {
- point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
- sp += [
- "C" + O(point.start.x),
- O(point.start.y),
- O(point.m.x),
- O(point.m.y),
- O(point.x),
- O(point.y)
- ];
- if (onlystart) {return sp;}
- subpaths.start = sp;
- sp = [
- "M" + O(point.x),
- O(point.y) + "C" + O(point.n.x),
- O(point.n.y),
- O(point.end.x),
- O(point.end.y),
- O(p[5]),
- O(p[6])
- ].join();
- len += l;
- x = +p[5];
- y = +p[6];
- continue;
- }
- if (!istotal && !subpath) {
- point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
- return point;
- }
- }
- len += l;
- x = +p[5];
- y = +p[6];
- }
- sp += p.shift() + p;
- }
- subpaths.end = sp;
- point = istotal ? len : subpath ? subpaths : findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);
- return point;
- }, null, Snap._.clone);
- }
- var getTotalLength = getLengthFactory(1),
- getPointAtLength = getLengthFactory(),
- getSubpathsAtLength = getLengthFactory(0, 1);
- function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
- var t1 = 1 - t,
- t13 = pow(t1, 3),
- t12 = pow(t1, 2),
- t2 = t * t,
- t3 = t2 * t,
- x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,
- y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y,
- mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x),
- my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y),
- nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x),
- ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y),
- ax = t1 * p1x + t * c1x,
- ay = t1 * p1y + t * c1y,
- cx = t1 * c2x + t * p2x,
- cy = t1 * c2y + t * p2y,
- alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);
- // (mx > nx || my < ny) && (alpha += 180);
- return {
- x: x,
- y: y,
- m: {x: mx, y: my},
- n: {x: nx, y: ny},
- start: {x: ax, y: ay},
- end: {x: cx, y: cy},
- alpha: alpha
- };
- }
- function bezierBBox(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
- if (!Snap.is(p1x, "array")) {
- p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];
- }
- var bbox = curveDim.apply(null, p1x);
- return box(
- bbox.min.x,
- bbox.min.y,
- bbox.max.x - bbox.min.x,
- bbox.max.y - bbox.min.y
- );
- }
- function isPointInsideBBox(bbox, x, y) {
- return x >= bbox.x &&
- x <= bbox.x + bbox.width &&
- y >= bbox.y &&
- y <= bbox.y + bbox.height;
- }
- function isBBoxIntersect(bbox1, bbox2) {
- bbox1 = box(bbox1);
- bbox2 = box(bbox2);
- return isPointInsideBBox(bbox2, bbox1.x, bbox1.y)
- || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y)
- || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2)
- || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2)
- || isPointInsideBBox(bbox1, bbox2.x, bbox2.y)
- || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y)
- || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2)
- || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2)
- || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x
- || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x)
- && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y
- || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);
- }
- function base3(t, p1, p2, p3, p4) {
- var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
- t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
- return t * t2 - 3 * p1 + 3 * p2;
- }
- function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {
- if (z == null) {
- z = 1;
- }
- z = z > 1 ? 1 : z < 0 ? 0 : z;
- var z2 = z / 2,
- n = 12,
- Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],
- Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472],
- sum = 0;
- for (var i = 0; i < n; i++) {
- var ct = z2 * Tvalues[i] + z2,
- xbase = base3(ct, x1, x2, x3, x4),
- ybase = base3(ct, y1, y2, y3, y4),
- comb = xbase * xbase + ybase * ybase;
- sum += Cvalues[i] * math.sqrt(comb);
- }
- return z2 * sum;
- }
- function getTotLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) {
- if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) {
- return;
- }
- var t = 1,
- step = t / 2,
- t2 = t - step,
- l,
- e = .01;
- l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
- while (abs(l - ll) > e) {
- step /= 2;
- t2 += (l < ll ? 1 : -1) * step;
- l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
- }
- return t2;
- }
- function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
- if (
- mmax(x1, x2) < mmin(x3, x4) ||
- mmin(x1, x2) > mmax(x3, x4) ||
- mmax(y1, y2) < mmin(y3, y4) ||
- mmin(y1, y2) > mmax(y3, y4)
- ) {
- return;
- }
- var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),
- ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),
- denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-
- if (!denominator) {
- return;
- }
- var px = nx / denominator,
- py = ny / denominator,
- px2 = +px.toFixed(2),
- py2 = +py.toFixed(2);
- if (
- px2 < +mmin(x1, x2).toFixed(2) ||
- px2 > +mmax(x1, x2).toFixed(2) ||
- px2 < +mmin(x3, x4).toFixed(2) ||
- px2 > +mmax(x3, x4).toFixed(2) ||
- py2 < +mmin(y1, y2).toFixed(2) ||
- py2 > +mmax(y1, y2).toFixed(2) ||
- py2 < +mmin(y3, y4).toFixed(2) ||
- py2 > +mmax(y3, y4).toFixed(2)
- ) {
- return;
- }
- return {x: px, y: py};
- }
- function inter(bez1, bez2) {
- return interHelper(bez1, bez2);
- }
- function interCount(bez1, bez2) {
- return interHelper(bez1, bez2, 1);
- }
- function interHelper(bez1, bez2, justCount) {
- var bbox1 = bezierBBox(bez1),
- bbox2 = bezierBBox(bez2);
- if (!isBBoxIntersect(bbox1, bbox2)) {
- return justCount ? 0 : [];
- }
- var l1 = bezlen.apply(0, bez1),
- l2 = bezlen.apply(0, bez2),
- n1 = ~~(l1 / 8),
- n2 = ~~(l2 / 8),
- dots1 = [],
- dots2 = [],
- xy = {},
- res = justCount ? 0 : [];
- for (var i = 0; i < n1 + 1; i++) {
- var p = findDotsAtSegment.apply(0, bez1.concat(i / n1));
- dots1.push({x: p.x, y: p.y, t: i / n1});
- }
- for (i = 0; i < n2 + 1; i++) {
- p = findDotsAtSegment.apply(0, bez2.concat(i / n2));
- dots2.push({x: p.x, y: p.y, t: i / n2});
- }
- for (i = 0; i < n1; i++) {
- for (var j = 0; j < n2; j++) {
- var di = dots1[i],
- di1 = dots1[i + 1],
- dj = dots2[j],
- dj1 = dots2[j + 1],
- ci = abs(di1.x - di.x) < .001 ? "y" : "x",
- cj = abs(dj1.x - dj.x) < .001 ? "y" : "x",
- is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);
- if (is) {
- if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) {
- continue;
- }
- xy[is.x.toFixed(4)] = is.y.toFixed(4);
- var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),
- t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);
- if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
- if (justCount) {
- res++;
- } else {
- res.push({
- x: is.x,
- y: is.y,
- t1: t1,
- t2: t2
- });
- }
- }
- }
- }
- }
- return res;
- }
- function pathIntersection(path1, path2) {
- return interPathHelper(path1, path2);
- }
- function pathIntersectionNumber(path1, path2) {
- return interPathHelper(path1, path2, 1);
- }
- function interPathHelper(path1, path2, justCount) {
- path1 = path2curve(path1);
- path2 = path2curve(path2);
- var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2,
- res = justCount ? 0 : [];
- for (var i = 0, ii = path1.length; i < ii; i++) {
- var pi = path1[i];
- if (pi[0] == "M") {
- x1 = x1m = pi[1];
- y1 = y1m = pi[2];
- } else {
- if (pi[0] == "C") {
- bez1 = [x1, y1].concat(pi.slice(1));
- x1 = bez1[6];
- y1 = bez1[7];
- } else {
- bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];
- x1 = x1m;
- y1 = y1m;
- }
- for (var j = 0, jj = path2.length; j < jj; j++) {
- var pj = path2[j];
- if (pj[0] == "M") {
- x2 = x2m = pj[1];
- y2 = y2m = pj[2];
- } else {
- if (pj[0] == "C") {
- bez2 = [x2, y2].concat(pj.slice(1));
- x2 = bez2[6];
- y2 = bez2[7];
- } else {
- bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];
- x2 = x2m;
- y2 = y2m;
- }
- var intr = interHelper(bez1, bez2, justCount);
- if (justCount) {
- res += intr;
- } else {
- for (var k = 0, kk = intr.length; k < kk; k++) {
- intr[k].segment1 = i;
- intr[k].segment2 = j;
- intr[k].bez1 = bez1;
- intr[k].bez2 = bez2;
- }
- res = res.concat(intr);
- }
- }
- }
- }
- }
- return res;
- }
- function isPointInsidePath(path, x, y) {
- var bbox = pathBBox(path);
- return isPointInsideBBox(bbox, x, y) &&
- interPathHelper(path, [["M", x, y], ["H", bbox.x2 + 10]], 1) % 2 == 1;
- }
- function pathBBox(path) {
- var pth = paths(path);
- if (pth.bbox) {
- return clone(pth.bbox);
- }
- if (!path) {
- return box();
- }
- path = path2curve(path);
- var x = 0,
- y = 0,
- X = [],
- Y = [],
- p;
- for (var i = 0, ii = path.length; i < ii; i++) {
- p = path[i];
- if (p[0] == "M") {
- x = p[1];
- y = p[2];
- X.push(x);
- Y.push(y);
- } else {
- var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
- X = X.concat(dim.min.x, dim.max.x);
- Y = Y.concat(dim.min.y, dim.max.y);
- x = p[5];
- y = p[6];
- }
- }
- var xmin = mmin.apply(0, X),
- ymin = mmin.apply(0, Y),
- xmax = mmax.apply(0, X),
- ymax = mmax.apply(0, Y),
- bb = box(xmin, ymin, xmax - xmin, ymax - ymin);
- pth.bbox = clone(bb);
- return bb;
- }
- function rectPath(x, y, w, h, r) {
- if (r) {
- return [
- ["M", +x + (+r), y],
- ["l", w - r * 2, 0],
- ["a", r, r, 0, 0, 1, r, r],
- ["l", 0, h - r * 2],
- ["a", r, r, 0, 0, 1, -r, r],
- ["l", r * 2 - w, 0],
- ["a", r, r, 0, 0, 1, -r, -r],
- ["l", 0, r * 2 - h],
- ["a", r, r, 0, 0, 1, r, -r],
- ["z"]
- ];
- }
- var res = [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];
- res.toString = toString;
- return res;
- }
- function ellipsePath(x, y, rx, ry, a) {
- if (a == null && ry == null) {
- ry = rx;
- }
- x = +x;
- y = +y;
- rx = +rx;
- ry = +ry;
- if (a != null) {
- var rad = Math.PI / 180,
- x1 = x + rx * Math.cos(-ry * rad),
- x2 = x + rx * Math.cos(-a * rad),
- y1 = y + rx * Math.sin(-ry * rad),
- y2 = y + rx * Math.sin(-a * rad),
- res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]];
- } else {
- res = [
- ["M", x, y],
- ["m", 0, -ry],
- ["a", rx, ry, 0, 1, 1, 0, 2 * ry],
- ["a", rx, ry, 0, 1, 1, 0, -2 * ry],
- ["z"]
- ];
- }
- res.toString = toString;
- return res;
- }
- var unit2px = Snap._unit2px,
- getPath = {
- path: function (el) {
- return el.attr("path");
- },
- circle: function (el) {
- var attr = unit2px(el);
- return ellipsePath(attr.cx, attr.cy, attr.r);
- },
- ellipse: function (el) {
- var attr = unit2px(el);
- return ellipsePath(attr.cx || 0, attr.cy || 0, attr.rx, attr.ry);
- },
- rect: function (el) {
- var attr = unit2px(el);
- return rectPath(attr.x || 0, attr.y || 0, attr.width, attr.height, attr.rx, attr.ry);
- },
- image: function (el) {
- var attr = unit2px(el);
- return rectPath(attr.x || 0, attr.y || 0, attr.width, attr.height);
- },
- line: function (el) {
- return "M" + [el.attr("x1") || 0, el.attr("y1") || 0, el.attr("x2"), el.attr("y2")];
- },
- polyline: function (el) {
- return "M" + el.attr("points");
- },
- polygon: function (el) {
- return "M" + el.attr("points") + "z";
- },
- deflt: function (el) {
- var bbox = el.node.getBBox();
- return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
- }
- };
- function pathToRelative(pathArray) {
- var pth = paths(pathArray),
- lowerCase = String.prototype.toLowerCase;
- if (pth.rel) {
- return pathClone(pth.rel);
- }
- if (!Snap.is(pathArray, "array") || !Snap.is(pathArray && pathArray[0], "array")) {
- pathArray = Snap.parsePathString(pathArray);
- }
- var res = [],
- x = 0,
- y = 0,
- mx = 0,
- my = 0,
- start = 0;
- if (pathArray[0][0] == "M") {
- x = pathArray[0][1];
- y = pathArray[0][2];
- mx = x;
- my = y;
- start++;
- res.push(["M", x, y]);
- }
- for (var i = start, ii = pathArray.length; i < ii; i++) {
- var r = res[i] = [],
- pa = pathArray[i];
- if (pa[0] != lowerCase.call(pa[0])) {
- r[0] = lowerCase.call(pa[0]);
- switch (r[0]) {
- case "a":
- r[1] = pa[1];
- r[2] = pa[2];
- r[3] = pa[3];
- r[4] = pa[4];
- r[5] = pa[5];
- r[6] = +(pa[6] - x).toFixed(3);
- r[7] = +(pa[7] - y).toFixed(3);
- break;
- case "v":
- r[1] = +(pa[1] - y).toFixed(3);
- break;
- case "m":
- mx = pa[1];
- my = pa[2];
- default:
- for (var j = 1, jj = pa.length; j < jj; j++) {
- r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);
- }
- }
- } else {
- r = res[i] = [];
- if (pa[0] == "m") {
- mx = pa[1] + x;
- my = pa[2] + y;
- }
- for (var k = 0, kk = pa.length; k < kk; k++) {
- res[i][k] = pa[k];
- }
- }
- var len = res[i].length;
- switch (res[i][0]) {
- case "z":
- x = mx;
- y = my;
- break;
- case "h":
- x += +res[i][len - 1];
- break;
- case "v":
- y += +res[i][len - 1];
- break;
- default:
- x += +res[i][len - 2];
- y += +res[i][len - 1];
- }
- }
- res.toString = toString;
- pth.rel = pathClone(res);
- return res;
- }
- function pathToAbsolute(pathArray) {
- var pth = paths(pathArray);
- if (pth.abs) {
- return pathClone(pth.abs);
- }
- if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough assumption
- pathArray = Snap.parsePathString(pathArray);
- }
- if (!pathArray || !pathArray.length) {
- return [["M", 0, 0]];
- }
- var res = [],
- x = 0,
- y = 0,
- mx = 0,
- my = 0,
- start = 0,
- pa0;
- if (pathArray[0][0] == "M") {
- x = +pathArray[0][1];
- y = +pathArray[0][2];
- mx = x;
- my = y;
- start++;
- res[0] = ["M", x, y];
- }
- var crz = pathArray.length == 3 &&
- pathArray[0][0] == "M" &&
- pathArray[1][0].toUpperCase() == "R" &&
- pathArray[2][0].toUpperCase() == "Z";
- for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
- res.push(r = []);
- pa = pathArray[i];
- pa0 = pa[0];
- if (pa0 != pa0.toUpperCase()) {
- r[0] = pa0.toUpperCase();
- switch (r[0]) {
- case "A":
- r[1] = pa[1];
- r[2] = pa[2];
- r[3] = pa[3];
- r[4] = pa[4];
- r[5] = pa[5];
- r[6] = +pa[6] + x;
- r[7] = +pa[7] + y;
- break;
- case "V":
- r[1] = +pa[1] + y;
- break;
- case "H":
- r[1] = +pa[1] + x;
- break;
- case "R":
- var dots = [x, y].concat(pa.slice(1));
- for (var j = 2, jj = dots.length; j < jj; j++) {
- dots[j] = +dots[j] + x;
- dots[++j] = +dots[j] + y;
- }
- res.pop();
- res = res.concat(catmullRom2bezier(dots, crz));
- break;
- case "O":
- res.pop();
- dots = ellipsePath(x, y, pa[1], pa[2]);
- dots.push(dots[0]);
- res = res.concat(dots);
- break;
- case "U":
- res.pop();
- res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
- r = ["U"].concat(res[res.length - 1].slice(-2));
- break;
- case "M":
- mx = +pa[1] + x;
- my = +pa[2] + y;
- default:
- for (j = 1, jj = pa.length; j < jj; j++) {
- r[j] = +pa[j] + ((j % 2) ? x : y);
- }
- }
- } else if (pa0 == "R") {
- dots = [x, y].concat(pa.slice(1));
- res.pop();
- res = res.concat(catmullRom2bezier(dots, crz));
- r = ["R"].concat(pa.slice(-2));
- } else if (pa0 == "O") {
- res.pop();
- dots = ellipsePath(x, y, pa[1], pa[2]);
- dots.push(dots[0]);
- res = res.concat(dots);
- } else if (pa0 == "U") {
- res.pop();
- res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
- r = ["U"].concat(res[res.length - 1].slice(-2));
- } else {
- for (var k = 0, kk = pa.length; k < kk; k++) {
- r[k] = pa[k];
- }
- }
- pa0 = pa0.toUpperCase();
- if (pa0 != "O") {
- switch (r[0]) {
- case "Z":
- x = +mx;
- y = +my;
- break;
- case "H":
- x = r[1];
- break;
- case "V":
- y = r[1];
- break;
- case "M":
- mx = r[r.length - 2];
- my = r[r.length - 1];
- default:
- x = r[r.length - 2];
- y = r[r.length - 1];
- }
- }
- }
- res.toString = toString;
- pth.abs = pathClone(res);
- return res;
- }
- function l2c(x1, y1, x2, y2) {
- return [x1, y1, x2, y2, x2, y2];
- }
- function q2c(x1, y1, ax, ay, x2, y2) {
- var _13 = 1 / 3,
- _23 = 2 / 3;
- return [
- _13 * x1 + _23 * ax,
- _13 * y1 + _23 * ay,
- _13 * x2 + _23 * ax,
- _13 * y2 + _23 * ay,
- x2,
- y2
- ];
- }
- function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
- // for more information of where this math came from visit:
- // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
- var _120 = PI * 120 / 180,
- rad = PI / 180 * (+angle || 0),
- res = [],
- xy,
- rotate = Snap._.cacher(function (x, y, rad) {
- var X = x * math.cos(rad) - y * math.sin(rad),
- Y = x * math.sin(rad) + y * math.cos(rad);
- return {x: X, y: Y};
- });
- if (!recursive) {
- xy = rotate(x1, y1, -rad);
- x1 = xy.x;
- y1 = xy.y;
- xy = rotate(x2, y2, -rad);
- x2 = xy.x;
- y2 = xy.y;
- var cos = math.cos(PI / 180 * angle),
- sin = math.sin(PI / 180 * angle),
- x = (x1 - x2) / 2,
- y = (y1 - y2) / 2;
- var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
- if (h > 1) {
- h = math.sqrt(h);
- rx = h * rx;
- ry = h * ry;
- }
- var rx2 = rx * rx,
- ry2 = ry * ry,
- k = (large_arc_flag == sweep_flag ? -1 : 1) *
- math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
- cx = k * rx * y / ry + (x1 + x2) / 2,
- cy = k * -ry * x / rx + (y1 + y2) / 2,
- f1 = math.asin(((y1 - cy) / ry).toFixed(9)),
- f2 = math.asin(((y2 - cy) / ry).toFixed(9));
-
- f1 = x1 < cx ? PI - f1 : f1;
- f2 = x2 < cx ? PI - f2 : f2;
- f1 < 0 && (f1 = PI * 2 + f1);
- f2 < 0 && (f2 = PI * 2 + f2);
- if (sweep_flag && f1 > f2) {
- f1 = f1 - PI * 2;
- }
- if (!sweep_flag && f2 > f1) {
- f2 = f2 - PI * 2;
- }
- } else {
- f1 = recursive[0];
- f2 = recursive[1];
- cx = recursive[2];
- cy = recursive[3];
- }
- var df = f2 - f1;
- if (abs(df) > _120) {
- var f2old = f2,
- x2old = x2,
- y2old = y2;
- f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
- x2 = cx + rx * math.cos(f2);
- y2 = cy + ry * math.sin(f2);
- res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
- }
- df = f2 - f1;
- var c1 = math.cos(f1),
- s1 = math.sin(f1),
- c2 = math.cos(f2),
- s2 = math.sin(f2),
- t = math.tan(df / 4),
- hx = 4 / 3 * rx * t,
- hy = 4 / 3 * ry * t,
- m1 = [x1, y1],
- m2 = [x1 + hx * s1, y1 - hy * c1],
- m3 = [x2 + hx * s2, y2 - hy * c2],
- m4 = [x2, y2];
- m2[0] = 2 * m1[0] - m2[0];
- m2[1] = 2 * m1[1] - m2[1];
- if (recursive) {
- return [m2, m3, m4].concat(res);
- } else {
- res = [m2, m3, m4].concat(res).join().split(",");
- var newres = [];
- for (var i = 0, ii = res.length; i < ii; i++) {
- newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
- }
- return newres;
- }
- }
- function findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
- var t1 = 1 - t;
- return {
- x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
- y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y
- };
- }
-
- // Returns bounding box of cubic bezier curve.
- // Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
- // Original version: NISHIO Hirokazu
- // Modifications: https://github.com/timo22345
- function curveDim(x0, y0, x1, y1, x2, y2, x3, y3) {
- var tvalues = [],
- bounds = [[], []],
- a, b, c, t, t1, t2, b2ac, sqrtb2ac;
- for (var i = 0; i < 2; ++i) {
- if (i == 0) {
- b = 6 * x0 - 12 * x1 + 6 * x2;
- a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
- c = 3 * x1 - 3 * x0;
- } else {
- b = 6 * y0 - 12 * y1 + 6 * y2;
- a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
- c = 3 * y1 - 3 * y0;
- }
- if (abs(a) < 1e-12) {
- if (abs(b) < 1e-12) {
- continue;
- }
- t = -c / b;
- if (0 < t && t < 1) {
- tvalues.push(t);
- }
- continue;
- }
- b2ac = b * b - 4 * c * a;
- sqrtb2ac = math.sqrt(b2ac);
- if (b2ac < 0) {
- continue;
- }
- t1 = (-b + sqrtb2ac) / (2 * a);
- if (0 < t1 && t1 < 1) {
- tvalues.push(t1);
- }
- t2 = (-b - sqrtb2ac) / (2 * a);
- if (0 < t2 && t2 < 1) {
- tvalues.push(t2);
- }
- }
-
- var x, y, j = tvalues.length,
- jlen = j,
- mt;
- while (j--) {
- t = tvalues[j];
- mt = 1 - t;
- bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
- bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
- }
-
- bounds[0][jlen] = x0;
- bounds[1][jlen] = y0;
- bounds[0][jlen + 1] = x3;
- bounds[1][jlen + 1] = y3;
- bounds[0].length = bounds[1].length = jlen + 2;
-
-
- return {
- min: {x: mmin.apply(0, bounds[0]), y: mmin.apply(0, bounds[1])},
- max: {x: mmax.apply(0, bounds[0]), y: mmax.apply(0, bounds[1])}
- };
- }
-
- function path2curve(path, path2) {
- var pth = !path2 && paths(path);
- if (!path2 && pth.curve) {
- return pathClone(pth.curve);
- }
- var p = pathToAbsolute(path),
- p2 = path2 && pathToAbsolute(path2),
- attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
- attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
- processPath = function (path, d, pcom) {
- var nx, ny;
- if (!path) {
- return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
- }
- !(path[0] in {T: 1, Q: 1}) && (d.qx = d.qy = null);
- switch (path[0]) {
- case "M":
- d.X = path[1];
- d.Y = path[2];
- break;
- case "A":
- path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1))));
- break;
- case "S":
- if (pcom == "C" || pcom == "S") { // In "S" case we have to take into account, if the previous command is C/S.
- nx = d.x * 2 - d.bx; // And reflect the previous
- ny = d.y * 2 - d.by; // command's control point relative to the current point.
- }
- else { // or some else or nothing
- nx = d.x;
- ny = d.y;
- }
- path = ["C", nx, ny].concat(path.slice(1));
- break;
- case "T":
- if (pcom == "Q" || pcom == "T") { // In "T" case we have to take into account, if the previous command is Q/T.
- d.qx = d.x * 2 - d.qx; // And make a reflection similar
- d.qy = d.y * 2 - d.qy; // to case "S".
- }
- else { // or something else or nothing
- d.qx = d.x;
- d.qy = d.y;
- }
- path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
- break;
- case "Q":
- d.qx = path[1];
- d.qy = path[2];
- path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
- break;
- case "L":
- path = ["C"].concat(l2c(d.x, d.y, path[1], path[2]));
- break;
- case "H":
- path = ["C"].concat(l2c(d.x, d.y, path[1], d.y));
- break;
- case "V":
- path = ["C"].concat(l2c(d.x, d.y, d.x, path[1]));
- break;
- case "Z":
- path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y));
- break;
- }
- return path;
- },
- fixArc = function (pp, i) {
- if (pp[i].length > 7) {
- pp[i].shift();
- var pi = pp[i];
- while (pi.length) {
- pcoms1[i] = "A"; // if created multiple C:s, their original seg is saved
- p2 && (pcoms2[i] = "A"); // the same as above
- pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6)));
- }
- pp.splice(i, 1);
- ii = mmax(p.length, p2 && p2.length || 0);
- }
- },
- fixM = function (path1, path2, a1, a2, i) {
- if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
- path2.splice(i, 0, ["M", a2.x, a2.y]);
- a1.bx = 0;
- a1.by = 0;
- a1.x = path1[i][1];
- a1.y = path1[i][2];
- ii = mmax(p.length, p2 && p2.length || 0);
- }
- },
- pcoms1 = [], // path commands of original path p
- pcoms2 = [], // path commands of original path p2
- pfirst = "", // temporary holder for original path command
- pcom = ""; // holder for previous path command of original path
- for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {
- p[i] && (pfirst = p[i][0]); // save current path command
-
- if (pfirst != "C") // C is not saved yet, because it may be result of conversion
- {
- pcoms1[i] = pfirst; // Save current path command
- i && ( pcom = pcoms1[i - 1]); // Get previous path command pcom
- }
- p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath
-
- if (pcoms1[i] != "A" && pfirst == "C") pcoms1[i] = "C"; // A is the only command
- // which may produce multiple C:s
- // so we have to make sure that C is also C in original path
-
- fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1
-
- if (p2) { // the same procedures is done to p2
- p2[i] && (pfirst = p2[i][0]);
- if (pfirst != "C") {
- pcoms2[i] = pfirst;
- i && (pcom = pcoms2[i - 1]);
- }
- p2[i] = processPath(p2[i], attrs2, pcom);
-
- if (pcoms2[i] != "A" && pfirst == "C") {
- pcoms2[i] = "C";
- }
-
- fixArc(p2, i);
- }
- fixM(p, p2, attrs, attrs2, i);
- fixM(p2, p, attrs2, attrs, i);
- var seg = p[i],
- seg2 = p2 && p2[i],
- seglen = seg.length,
- seg2len = p2 && seg2.length;
- attrs.x = seg[seglen - 2];
- attrs.y = seg[seglen - 1];
- attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
- attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
- attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);
- attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);
- attrs2.x = p2 && seg2[seg2len - 2];
- attrs2.y = p2 && seg2[seg2len - 1];
- }
- if (!p2) {
- pth.curve = pathClone(p);
- }
- return p2 ? [p, p2] : p;
- }
- function mapPath(path, matrix) {
- if (!matrix) {
- return path;
- }
- var x, y, i, j, ii, jj, pathi;
- path = path2curve(path);
- for (i = 0, ii = path.length; i < ii; i++) {
- pathi = path[i];
- for (j = 1, jj = pathi.length; j < jj; j += 2) {
- x = matrix.x(pathi[j], pathi[j + 1]);
- y = matrix.y(pathi[j], pathi[j + 1]);
- pathi[j] = x;
- pathi[j + 1] = y;
- }
- }
- return path;
- }
-
- // http://schepers.cc/getting-to-the-point
- function catmullRom2bezier(crp, z) {
- var d = [];
- for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
- var p = [
- {x: +crp[i - 2], y: +crp[i - 1]},
- {x: +crp[i], y: +crp[i + 1]},
- {x: +crp[i + 2], y: +crp[i + 3]},
- {x: +crp[i + 4], y: +crp[i + 5]}
- ];
- if (z) {
- if (!i) {
- p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]};
- } else if (iLen - 4 == i) {
- p[3] = {x: +crp[0], y: +crp[1]};
- } else if (iLen - 2 == i) {
- p[2] = {x: +crp[0], y: +crp[1]};
- p[3] = {x: +crp[2], y: +crp[3]};
- }
- } else {
- if (iLen - 4 == i) {
- p[3] = p[2];
- } else if (!i) {
- p[0] = {x: +crp[i], y: +crp[i + 1]};
- }
- }
- d.push(["C",
- (-p[0].x + 6 * p[1].x + p[2].x) / 6,
- (-p[0].y + 6 * p[1].y + p[2].y) / 6,
- (p[1].x + 6 * p[2].x - p[3].x) / 6,
- (p[1].y + 6*p[2].y - p[3].y) / 6,
- p[2].x,
- p[2].y
- ]);
- }
-
- return d;
- }
-
- // export
- Snap.path = paths;
-
- /*\
- * Snap.path.getTotalLength
- [ method ]
- **
- * Returns the length of the given path in pixels
- **
- - path (string) SVG path string
- **
- = (number) length
- \*/
- Snap.path.getTotalLength = getTotalLength;
- /*\
- * Snap.path.getPointAtLength
- [ method ]
- **
- * Returns the coordinates of the point located at the given length along the given path
- **
- - path (string) SVG path string
- - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps
- **
- = (object) representation of the point:
- o {
- o x: (number) x coordinate,
- o y: (number) y coordinate,
- o alpha: (number) angle of derivative
- o }
- \*/
- Snap.path.getPointAtLength = getPointAtLength;
- /*\
- * Snap.path.getSubpath
- [ method ]
- **
- * Returns the subpath of a given path between given start and end lengths
- **
- - path (string) SVG path string
- - from (number) length, in pixels, from the start of the path to the start of the segment
- - to (number) length, in pixels, from the start of the path to the end of the segment
- **
- = (string) path string definition for the segment
- \*/
- Snap.path.getSubpath = function (path, from, to) {
- if (this.getTotalLength(path) - to < 1e-6) {
- return getSubpathsAtLength(path, from).end;
- }
- var a = getSubpathsAtLength(path, to, 1);
- return from ? getSubpathsAtLength(a, from).end : a;
- };
- /*\
- * Element.getTotalLength
- [ method ]
- **
- * Returns the length of the path in pixels (only works for `path` elements)
- = (number) length
- \*/
- elproto.getTotalLength = function () {
- if (this.node.getTotalLength) {
- return this.node.getTotalLength();
- }
- };
- // SIERRA Element.getPointAtLength()/Element.getTotalLength(): If a <path> is broken into different segments, is the jump distance to the new coordinates set by the _M_ or _m_ commands calculated as part of the path's total length?
- /*\
- * Element.getPointAtLength
- [ method ]
- **
- * Returns coordinates of the point located at the given length on the given path (only works for `path` elements)
- **
- - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps
- **
- = (object) representation of the point:
- o {
- o x: (number) x coordinate,
- o y: (number) y coordinate,
- o alpha: (number) angle of derivative
- o }
- \*/
- elproto.getPointAtLength = function (length) {
- return getPointAtLength(this.attr("d"), length);
- };
- // SIERRA Element.getSubpath(): Similar to the problem for Element.getPointAtLength(). Unclear how this would work for a segmented path. Overall, the concept of _subpath_ and what I'm calling a _segment_ (series of non-_M_ or _Z_ commands) is unclear.
- /*\
- * Element.getSubpath
- [ method ]
- **
- * Returns subpath of a given element from given start and end lengths (only works for `path` elements)
- **
- - from (number) length, in pixels, from the start of the path to the start of the segment
- - to (number) length, in pixels, from the start of the path to the end of the segment
- **
- = (string) path string definition for the segment
- \*/
- elproto.getSubpath = function (from, to) {
- return Snap.path.getSubpath(this.attr("d"), from, to);
- };
- Snap._.box = box;
- /*\
- * Snap.path.findDotsAtSegment
- [ method ]
- **
- * Utility method
- **
- * Finds dot coordinates on the given cubic beziér curve at the given t
- - p1x (number) x of the first point of the curve
- - p1y (number) y of the first point of the curve
- - c1x (number) x of the first anchor of the curve
- - c1y (number) y of the first anchor of the curve
- - c2x (number) x of the second anchor of the curve
- - c2y (number) y of the second anchor of the curve
- - p2x (number) x of the second point of the curve
- - p2y (number) y of the second point of the curve
- - t (number) position on the curve (0..1)
- = (object) point information in format:
- o {
- o x: (number) x coordinate of the point,
- o y: (number) y coordinate of the point,
- o m: {
- o x: (number) x coordinate of the left anchor,
- o y: (number) y coordinate of the left anchor
- o },
- o n: {
- o x: (number) x coordinate of the right anchor,
- o y: (number) y coordinate of the right anchor
- o },
- o start: {
- o x: (number) x coordinate of the start of the curve,
- o y: (number) y coordinate of the start of the curve
- o },
- o end: {
- o x: (number) x coordinate of the end of the curve,
- o y: (number) y coordinate of the end of the curve
- o },
- o alpha: (number) angle of the curve derivative at the point
- o }
- \*/
- Snap.path.findDotsAtSegment = findDotsAtSegment;
- /*\
- * Snap.path.bezierBBox
- [ method ]
- **
- * Utility method
- **
- * Returns the bounding box of a given cubic beziér curve
- - p1x (number) x of the first point of the curve
- - p1y (number) y of the first point of the curve
- - c1x (number) x of the first anchor of the curve
- - c1y (number) y of the first anchor of the curve
- - c2x (number) x of the second anchor of the curve
- - c2y (number) y of the second anchor of the curve
- - p2x (number) x of the second point of the curve
- - p2y (number) y of the second point of the curve
- * or
- - bez (array) array of six points for beziér curve
- = (object) bounding box
- o {
- o x: (number) x coordinate of the left top point of the box,
- o y: (number) y coordinate of the left top point of the box,
- o x2: (number) x coordinate of the right bottom point of the box,
- o y2: (number) y coordinate of the right bottom point of the box,
- o width: (number) width of the box,
- o height: (number) height of the box
- o }
- \*/
- Snap.path.bezierBBox = bezierBBox;
- /*\
- * Snap.path.isPointInsideBBox
- [ method ]
- **
- * Utility method
- **
- * Returns `true` if given point is inside bounding box
- - bbox (string) bounding box
- - x (string) x coordinate of the point
- - y (string) y coordinate of the point
- = (boolean) `true` if point is inside
- \*/
- Snap.path.isPointInsideBBox = isPointInsideBBox;
- Snap.closest = function (x, y, X, Y) {
- var r = 100,
- b = box(x - r / 2, y - r / 2, r, r),
- inside = [],
- getter = X[0].hasOwnProperty("x") ? function (i) {
- return {
- x: X[i].x,
- y: X[i].y
- };
- } : function (i) {
- return {
- x: X[i],
- y: Y[i]
- };
- },
- found = 0;
- while (r <= 1e6 && !found) {
- for (var i = 0, ii = X.length; i < ii; i++) {
- var xy = getter(i);
- if (isPointInsideBBox(b, xy.x, xy.y)) {
- found++;
- inside.push(xy);
- break;
- }
- }
- if (!found) {
- r *= 2;
- b = box(x - r / 2, y - r / 2, r, r)
- }
- }
- if (r == 1e6) {
- return;
- }
- var len = Infinity,
- res;
- for (i = 0, ii = inside.length; i < ii; i++) {
- var l = Snap.len(x, y, inside[i].x, inside[i].y);
- if (len > l) {
- len = l;
- inside[i].len = l;
- res = inside[i];
- }
- }
- return res;
- };
- /*\
- * Snap.path.isBBoxIntersect
- [ method ]
- **
- * Utility method
- **
- * Returns `true` if two bounding boxes intersect
- - bbox1 (string) first bounding box
- - bbox2 (string) second bounding box
- = (boolean) `true` if bounding boxes intersect
- \*/
- Snap.path.isBBoxIntersect = isBBoxIntersect;
- /*\
- * Snap.path.intersection
- [ method ]
- **
- * Utility method
- **
- * Finds intersections of two paths
- - path1 (string) path string
- - path2 (string) path string
- = (array) dots of intersection
- o [
- o {
- o x: (number) x coordinate of the point,
- o y: (number) y coordinate of the point,
- o t1: (number) t value for segment of path1,
- o t2: (number) t value for segment of path2,
- o segment1: (number) order number for segment of path1,
- o segment2: (number) order number for segment of path2,
- o bez1: (array) eight coordinates representing beziér curve for the segment of path1,
- o bez2: (array) eight coordinates representing beziér curve for the segment of path2
- o }
- o ]
- \*/
- Snap.path.intersection = pathIntersection;
- Snap.path.intersectionNumber = pathIntersectionNumber;
- /*\
- * Snap.path.isPointInside
- [ method ]
- **
- * Utility method
- **
- * Returns `true` if given point is inside a given closed path.
- *
- * Note: fill mode doesn’t affect the result of this method.
- - path (string) path string
- - x (number) x of the point
- - y (number) y of the point
- = (boolean) `true` if point is inside the path
- \*/
- Snap.path.isPointInside = isPointInsidePath;
- /*\
- * Snap.path.getBBox
- [ method ]
- **
- * Utility method
- **
- * Returns the bounding box of a given path
- - path (string) path string
- = (object) bounding box
- o {
- o x: (number) x coordinate of the left top point of the box,
- o y: (number) y coordinate of the left top point of the box,
- o x2: (number) x coordinate of the right bottom point of the box,
- o y2: (number) y coordinate of the right bottom point of the box,
- o width: (number) width of the box,
- o height: (number) height of the box
- o }
- \*/
- Snap.path.getBBox = pathBBox;
- Snap.path.get = getPath;
- /*\
- * Snap.path.toRelative
- [ method ]
- **
- * Utility method
- **
- * Converts path coordinates into relative values
- - path (string) path string
- = (array) path string
- \*/
- Snap.path.toRelative = pathToRelative;
- /*\
- * Snap.path.toAbsolute
- [ method ]
- **
- * Utility method
- **
- * Converts path coordinates into absolute values
- - path (string) path string
- = (array) path string
- \*/
- Snap.path.toAbsolute = pathToAbsolute;
- /*\
- * Snap.path.toCubic
- [ method ]
- **
- * Utility method
- **
- * Converts path to a new path where all segments are cubic beziér curves
- - pathString (string|array) path string or array of segments
- = (array) array of segments
- \*/
- Snap.path.toCubic = path2curve;
- /*\
- * Snap.path.map
- [ method ]
- **
- * Transform the path string with the given matrix
- - path (string) path string
- - matrix (object) see @Matrix
- = (string) transformed path string
- \*/
- Snap.path.map = mapPath;
- Snap.path.toString = toString;
- Snap.path.clone = pathClone;
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob) {
- var mmax = Math.max,
- mmin = Math.min;
-
- // Set
- var Set = function (items) {
- this.items = [];
- this.bindings = {};
- this.length = 0;
- this.type = "set";
- if (items) {
- for (var i = 0, ii = items.length; i < ii; i++) {
- if (items[i]) {
- this[this.items.length] = this.items[this.items.length] = items[i];
- this.length++;
- }
- }
- }
- },
- setproto = Set.prototype;
- /*\
- * Set.push
- [ method ]
- **
- * Adds each argument to the current set
- = (object) original element
- \*/
- setproto.push = function () {
- var item,
- len;
- for (var i = 0, ii = arguments.length; i < ii; i++) {
- item = arguments[i];
- if (item) {
- len = this.items.length;
- this[len] = this.items[len] = item;
- this.length++;
- }
- }
- return this;
- };
- /*\
- * Set.pop
- [ method ]
- **
- * Removes last element and returns it
- = (object) element
- \*/
- setproto.pop = function () {
- this.length && delete this[this.length--];
- return this.items.pop();
- };
- /*\
- * Set.forEach
- [ method ]
- **
- * Executes given function for each element in the set
- *
- * If the function returns `false`, the loop stops running.
- **
- - callback (function) function to run
- - thisArg (object) context object for the callback
- = (object) Set object
- \*/
- setproto.forEach = function (callback, thisArg) {
- for (var i = 0, ii = this.items.length; i < ii; i++) {
- if (callback.call(thisArg, this.items[i], i) === false) {
- return this;
- }
- }
- return this;
- };
- /*\
- * Set.animate
- [ method ]
- **
- * Animates each element in set in sync.
- *
- **
- - attrs (object) key-value pairs of destination attributes
- - duration (number) duration of the animation in milliseconds
- - easing (function) #optional easing function from @mina or custom
- - callback (function) #optional callback function that executes when the animation ends
- * or
- - animation (array) array of animation parameter for each element in set in format `[attrs, duration, easing, callback]`
- > Usage
- | // animate all elements in set to radius 10
- | set.animate({r: 10}, 500, mina.easein);
- | // or
- | // animate first element to radius 10, but second to radius 20 and in different time
- | set.animate([{r: 10}, 500, mina.easein], [{r: 20}, 1500, mina.easein]);
- = (Element) the current element
- \*/
- setproto.animate = function (attrs, ms, easing, callback) {
- if (typeof easing == "function" && !easing.length) {
- callback = easing;
- easing = mina.linear;
- }
- if (attrs instanceof Snap._.Animation) {
- callback = attrs.callback;
- easing = attrs.easing;
- ms = easing.dur;
- attrs = attrs.attr;
- }
- var args = arguments;
- if (Snap.is(attrs, "array") && Snap.is(args[args.length - 1], "array")) {
- var each = true;
- }
- var begin,
- handler = function () {
- if (begin) {
- this.b = begin;
- } else {
- begin = this.b;
- }
- },
- cb = 0,
- set = this,
- callbacker = callback && function () {
- if (++cb == set.length) {
- callback.call(this);
- }
- };
- return this.forEach(function (el, i) {
- eve.once("snap.animcreated." + el.id, handler);
- if (each) {
- args[i] && el.animate.apply(el, args[i]);
- } else {
- el.animate(attrs, ms, easing, callbacker);
- }
- });
- };
- setproto.remove = function () {
- while (this.length) {
- this.pop().remove();
- }
- return this;
- };
- /*\
- * Set.bind
- [ method ]
- **
- * Specifies how to handle a specific attribute when applied
- * to a set.
- *
- **
- - attr (string) attribute name
- - callback (function) function to run
- * or
- - attr (string) attribute name
- - element (Element) specific element in the set to apply the attribute to
- * or
- - attr (string) attribute name
- - element (Element) specific element in the set to apply the attribute to
- - eattr (string) attribute on the element to bind the attribute to
- = (object) Set object
- \*/
- setproto.bind = function (attr, a, b) {
- var data = {};
- if (typeof a == "function") {
- this.bindings[attr] = a;
- } else {
- var aname = b || attr;
- this.bindings[attr] = function (v) {
- data[aname] = v;
- a.attr(data);
- };
- }
- return this;
- };
- setproto.attr = function (value) {
- var unbound = {};
- for (var k in value) {
- if (this.bindings[k]) {
- this.bindings[k](value[k]);
- } else {
- unbound[k] = value[k];
- }
- }
- for (var i = 0, ii = this.items.length; i < ii; i++) {
- this.items[i].attr(unbound);
- }
- return this;
- };
- /*\
- * Set.clear
- [ method ]
- **
- * Removes all elements from the set
- \*/
- setproto.clear = function () {
- while (this.length) {
- this.pop();
- }
- };
- /*\
- * Set.splice
- [ method ]
- **
- * Removes range of elements from the set
- **
- - index (number) position of the deletion
- - count (number) number of element to remove
- - insertion… (object) #optional elements to insert
- = (object) set elements that were deleted
- \*/
- setproto.splice = function (index, count, insertion) {
- index = index < 0 ? mmax(this.length + index, 0) : index;
- count = mmax(0, mmin(this.length - index, count));
- var tail = [],
- todel = [],
- args = [],
- i;
- for (i = 2; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
- for (i = 0; i < count; i++) {
- todel.push(this[index + i]);
- }
- for (; i < this.length - index; i++) {
- tail.push(this[index + i]);
- }
- var arglen = args.length;
- for (i = 0; i < arglen + tail.length; i++) {
- this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];
- }
- i = this.items.length = this.length -= count - arglen;
- while (this[i]) {
- delete this[i++];
- }
- return new Set(todel);
- };
- /*\
- * Set.exclude
- [ method ]
- **
- * Removes given element from the set
- **
- - element (object) element to remove
- = (boolean) `true` if object was found and removed from the set
- \*/
- setproto.exclude = function (el) {
- for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {
- this.splice(i, 1);
- return true;
- }
- return false;
- };
- setproto.insertAfter = function (el) {
- var i = this.items.length;
- while (i--) {
- this.items[i].insertAfter(el);
- }
- return this;
- };
- setproto.getBBox = function () {
- var x = [],
- y = [],
- x2 = [],
- y2 = [];
- for (var i = this.items.length; i--;) if (!this.items[i].removed) {
- var box = this.items[i].getBBox();
- x.push(box.x);
- y.push(box.y);
- x2.push(box.x + box.width);
- y2.push(box.y + box.height);
- }
- x = mmin.apply(0, x);
- y = mmin.apply(0, y);
- x2 = mmax.apply(0, x2);
- y2 = mmax.apply(0, y2);
- return {
- x: x,
- y: y,
- x2: x2,
- y2: y2,
- width: x2 - x,
- height: y2 - y,
- cx: x + (x2 - x) / 2,
- cy: y + (y2 - y) / 2
- };
- };
- setproto.clone = function (s) {
- s = new Set;
- for (var i = 0, ii = this.items.length; i < ii; i++) {
- s.push(this.items[i].clone());
- }
- return s;
- };
- setproto.toString = function () {
- return "Snap\u2018s set";
- };
- setproto.type = "set";
- // export
- Snap.Set = Set;
- Snap.set = function () {
- var set = new Set;
- if (arguments.length) {
- set.push.apply(set, Array.prototype.slice.call(arguments, 0));
- }
- return set;
- };
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob) {
- var names = {},
- reUnit = /[a-z]+$/i,
- Str = String;
- names.stroke = names.fill = "colour";
- function getEmpty(item) {
- var l = item[0];
- switch (l.toLowerCase()) {
- case "t": return [l, 0, 0];
- case "m": return [l, 1, 0, 0, 1, 0, 0];
- case "r": if (item.length == 4) {
- return [l, 0, item[2], item[3]];
- } else {
- return [l, 0];
- }
- case "s": if (item.length == 5) {
- return [l, 1, 1, item[3], item[4]];
- } else if (item.length == 3) {
- return [l, 1, 1];
- } else {
- return [l, 1];
- }
- }
- }
- function equaliseTransform(t1, t2, getBBox) {
- t2 = Str(t2).replace(/\.{3}|\u2026/g, t1);
- t1 = Snap.parseTransformString(t1) || [];
- t2 = Snap.parseTransformString(t2) || [];
- var maxlength = Math.max(t1.length, t2.length),
- from = [],
- to = [],
- i = 0, j, jj,
- tt1, tt2;
- for (; i < maxlength; i++) {
- tt1 = t1[i] || getEmpty(t2[i]);
- tt2 = t2[i] || getEmpty(tt1);
- if ((tt1[0] != tt2[0]) ||
- (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||
- (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))
- ) {
- t1 = Snap._.transform2matrix(t1, getBBox());
- t2 = Snap._.transform2matrix(t2, getBBox());
- from = [["m", t1.a, t1.b, t1.c, t1.d, t1.e, t1.f]];
- to = [["m", t2.a, t2.b, t2.c, t2.d, t2.e, t2.f]];
- break;
- }
- from[i] = [];
- to[i] = [];
- for (j = 0, jj = Math.max(tt1.length, tt2.length); j < jj; j++) {
- j in tt1 && (from[i][j] = tt1[j]);
- j in tt2 && (to[i][j] = tt2[j]);
- }
- }
- return {
- from: path2array(from),
- to: path2array(to),
- f: getPath(from)
- };
- }
- function getNumber(val) {
- return val;
- }
- function getUnit(unit) {
- return function (val) {
- return +val.toFixed(3) + unit;
- };
- }
- function getViewBox(val) {
- return val.join(" ");
- }
- function getColour(clr) {
- return Snap.rgb(clr[0], clr[1], clr[2]);
- }
- function getPath(path) {
- var k = 0, i, ii, j, jj, out, a, b = [];
- for (i = 0, ii = path.length; i < ii; i++) {
- out = "[";
- a = ['"' + path[i][0] + '"'];
- for (j = 1, jj = path[i].length; j < jj; j++) {
- a[j] = "val[" + (k++) + "]";
- }
- out += a + "]";
- b[i] = out;
- }
- return Function("val", "return Snap.path.toString.call([" + b + "])");
- }
- function path2array(path) {
- var out = [];
- for (var i = 0, ii = path.length; i < ii; i++) {
- for (var j = 1, jj = path[i].length; j < jj; j++) {
- out.push(path[i][j]);
- }
- }
- return out;
- }
- function isNumeric(obj) {
- return isFinite(parseFloat(obj));
- }
- function arrayEqual(arr1, arr2) {
- if (!Snap.is(arr1, "array") || !Snap.is(arr2, "array")) {
- return false;
- }
- return arr1.toString() == arr2.toString();
- }
- Element.prototype.equal = function (name, b) {
- return eve("snap.util.equal", this, name, b).firstDefined();
- };
- eve.on("snap.util.equal", function (name, b) {
- var A, B, a = Str(this.attr(name) || ""),
- el = this;
- if (isNumeric(a) && isNumeric(b)) {
- return {
- from: parseFloat(a),
- to: parseFloat(b),
- f: getNumber
- };
- }
- if (names[name] == "colour") {
- A = Snap.color(a);
- B = Snap.color(b);
- return {
- from: [A.r, A.g, A.b, A.opacity],
- to: [B.r, B.g, B.b, B.opacity],
- f: getColour
- };
- }
- if (name == "viewBox") {
- A = this.attr(name).vb.split(" ").map(Number);
- B = b.split(" ").map(Number);
- return {
- from: A,
- to: B,
- f: getViewBox
- };
- }
- if (name == "transform" || name == "gradientTransform" || name == "patternTransform") {
- if (b instanceof Snap.Matrix) {
- b = b.toTransformString();
- }
- if (!Snap._.rgTransform.test(b)) {
- b = Snap._.svgTransform2string(b);
- }
- return equaliseTransform(a, b, function () {
- return el.getBBox(1);
- });
- }
- if (name == "d" || name == "path") {
- A = Snap.path.toCubic(a, b);
- return {
- from: path2array(A[0]),
- to: path2array(A[1]),
- f: getPath(A[0])
- };
- }
- if (name == "points") {
- A = Str(a).split(Snap._.separator);
- B = Str(b).split(Snap._.separator);
- return {
- from: A,
- to: B,
- f: function (val) { return val; }
- };
- }
- var aUnit = a.match(reUnit),
- bUnit = Str(b).match(reUnit);
- if (aUnit && arrayEqual(aUnit, bUnit)) {
- return {
- from: parseFloat(a),
- to: parseFloat(b),
- f: getUnit(aUnit)
- };
- } else {
- return {
- from: this.asPX(name),
- to: this.asPX(name, b),
- f: getNumber
- };
- }
- });
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob) {
- var elproto = Element.prototype,
- has = "hasOwnProperty",
- supportsTouch = "createTouch" in glob.doc,
- events = [
- "click", "dblclick", "mousedown", "mousemove", "mouseout",
- "mouseover", "mouseup", "touchstart", "touchmove", "touchend",
- "touchcancel"
- ],
- touchMap = {
- mousedown: "touchstart",
- mousemove: "touchmove",
- mouseup: "touchend"
- },
- getScroll = function (xy, el) {
- var name = xy == "y" ? "scrollTop" : "scrollLeft",
- doc = el && el.node ? el.node.ownerDocument : glob.doc;
- return doc[name in doc.documentElement ? "documentElement" : "body"][name];
- },
- preventDefault = function () {
- this.returnValue = false;
- },
- preventTouch = function () {
- return this.originalEvent.preventDefault();
- },
- stopPropagation = function () {
- this.cancelBubble = true;
- },
- stopTouch = function () {
- return this.originalEvent.stopPropagation();
- },
- addEvent = function (obj, type, fn, element) {
- var realName = supportsTouch && touchMap[type] ? touchMap[type] : type,
- f = function (e) {
- var scrollY = getScroll("y", element),
- scrollX = getScroll("x", element);
- if (supportsTouch && touchMap[has](type)) {
- for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
- if (e.targetTouches[i].target == obj || obj.contains(e.targetTouches[i].target)) {
- var olde = e;
- e = e.targetTouches[i];
- e.originalEvent = olde;
- e.preventDefault = preventTouch;
- e.stopPropagation = stopTouch;
- break;
- }
- }
- }
- var x = e.clientX + scrollX,
- y = e.clientY + scrollY;
- return fn.call(element, e, x, y);
- };
-
- if (type !== realName) {
- obj.addEventListener(type, f, false);
- }
-
- obj.addEventListener(realName, f, false);
-
- return function () {
- if (type !== realName) {
- obj.removeEventListener(type, f, false);
- }
-
- obj.removeEventListener(realName, f, false);
- return true;
- };
- },
- drag = [],
- dragMove = function (e) {
- var x = e.clientX,
- y = e.clientY,
- scrollY = getScroll("y"),
- scrollX = getScroll("x"),
- dragi,
- j = drag.length;
- while (j--) {
- dragi = drag[j];
- if (supportsTouch) {
- var i = e.touches && e.touches.length,
- touch;
- while (i--) {
- touch = e.touches[i];
- if (touch.identifier == dragi.el._drag.id || dragi.el.node.contains(touch.target)) {
- x = touch.clientX;
- y = touch.clientY;
- (e.originalEvent ? e.originalEvent : e).preventDefault();
- break;
- }
- }
- } else {
- e.preventDefault();
- }
- var node = dragi.el.node,
- o,
- next = node.nextSibling,
- parent = node.parentNode,
- display = node.style.display;
- // glob.win.opera && parent.removeChild(node);
- // node.style.display = "none";
- // o = dragi.el.paper.getElementByPoint(x, y);
- // node.style.display = display;
- // glob.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node));
- // o && eve("snap.drag.over." + dragi.el.id, dragi.el, o);
- x += scrollX;
- y += scrollY;
- eve("snap.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);
- }
- },
- dragUp = function (e) {
- Snap.unmousemove(dragMove).unmouseup(dragUp);
- var i = drag.length,
- dragi;
- while (i--) {
- dragi = drag[i];
- dragi.el._drag = {};
- eve("snap.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);
- eve.off("snap.drag.*." + dragi.el.id);
- }
- drag = [];
- };
- /*\
- * Element.click
- [ method ]
- **
- * Adds a click event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unclick
- [ method ]
- **
- * Removes a click event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.dblclick
- [ method ]
- **
- * Adds a double click event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.undblclick
- [ method ]
- **
- * Removes a double click event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mousedown
- [ method ]
- **
- * Adds a mousedown event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmousedown
- [ method ]
- **
- * Removes a mousedown event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mousemove
- [ method ]
- **
- * Adds a mousemove event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmousemove
- [ method ]
- **
- * Removes a mousemove event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mouseout
- [ method ]
- **
- * Adds a mouseout event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmouseout
- [ method ]
- **
- * Removes a mouseout event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mouseover
- [ method ]
- **
- * Adds a mouseover event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmouseover
- [ method ]
- **
- * Removes a mouseover event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mouseup
- [ method ]
- **
- * Adds a mouseup event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmouseup
- [ method ]
- **
- * Removes a mouseup event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchstart
- [ method ]
- **
- * Adds a touchstart event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchstart
- [ method ]
- **
- * Removes a touchstart event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchmove
- [ method ]
- **
- * Adds a touchmove event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchmove
- [ method ]
- **
- * Removes a touchmove event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchend
- [ method ]
- **
- * Adds a touchend event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchend
- [ method ]
- **
- * Removes a touchend event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchcancel
- [ method ]
- **
- * Adds a touchcancel event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchcancel
- [ method ]
- **
- * Removes a touchcancel event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- for (var i = events.length; i--;) {
- (function (eventName) {
- Snap[eventName] = elproto[eventName] = function (fn, scope) {
- if (Snap.is(fn, "function")) {
- this.events = this.events || [];
- this.events.push({
- name: eventName,
- f: fn,
- unbind: addEvent(this.node || document, eventName, fn, scope || this)
- });
- } else {
- for (var i = 0, ii = this.events.length; i < ii; i++) if (this.events[i].name == eventName) {
- try {
- this.events[i].f.call(this);
- } catch (e) {}
- }
- }
- return this;
- };
- Snap["un" + eventName] =
- elproto["un" + eventName] = function (fn) {
- var events = this.events || [],
- l = events.length;
- while (l--) if (events[l].name == eventName &&
- (events[l].f == fn || !fn)) {
- events[l].unbind();
- events.splice(l, 1);
- !events.length && delete this.events;
- return this;
- }
- return this;
- };
- })(events[i]);
- }
- /*\
- * Element.hover
- [ method ]
- **
- * Adds hover event handlers to the element
- - f_in (function) handler for hover in
- - f_out (function) handler for hover out
- - icontext (object) #optional context for hover in handler
- - ocontext (object) #optional context for hover out handler
- = (object) @Element
- \*/
- elproto.hover = function (f_in, f_out, scope_in, scope_out) {
- return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);
- };
- /*\
- * Element.unhover
- [ method ]
- **
- * Removes hover event handlers from the element
- - f_in (function) handler for hover in
- - f_out (function) handler for hover out
- = (object) @Element
- \*/
- elproto.unhover = function (f_in, f_out) {
- return this.unmouseover(f_in).unmouseout(f_out);
- };
- var draggable = [];
- // SIERRA unclear what _context_ refers to for starting, ending, moving the drag gesture.
- // SIERRA Element.drag(): _x position of the mouse_: Where are the x/y values offset from?
- // SIERRA Element.drag(): much of this member's doc appears to be duplicated for some reason.
- // SIERRA Unclear about this sentence: _Additionally following drag events will be triggered: drag.start.<id> on start, drag.end.<id> on end and drag.move.<id> on every move._ Is there a global _drag_ object to which you can assign handlers keyed by an element's ID?
- /*\
- * Element.drag
- [ method ]
- **
- * Adds event handlers for an element's drag gesture
- **
- - onmove (function) handler for moving
- - onstart (function) handler for drag start
- - onend (function) handler for drag end
- - mcontext (object) #optional context for moving handler
- - scontext (object) #optional context for drag start handler
- - econtext (object) #optional context for drag end handler
- * Additionaly following `drag` events are triggered: `drag.start.<id>` on start,
- * `drag.end.<id>` on end and `drag.move.<id>` on every move. When element is dragged over another element
- * `drag.over.<id>` fires as well.
- *
- * Start event and start handler are called in specified context or in context of the element with following parameters:
- o x (number) x position of the mouse
- o y (number) y position of the mouse
- o event (object) DOM event object
- * Move event and move handler are called in specified context or in context of the element with following parameters:
- o dx (number) shift by x from the start point
- o dy (number) shift by y from the start point
- o x (number) x position of the mouse
- o y (number) y position of the mouse
- o event (object) DOM event object
- * End event and end handler are called in specified context or in context of the element with following parameters:
- o event (object) DOM event object
- = (object) @Element
- \*/
- elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {
- var el = this;
- if (!arguments.length) {
- var origTransform;
- return el.drag(function (dx, dy) {
- this.attr({
- transform: origTransform + (origTransform ? "T" : "t") + [dx, dy]
- });
- }, function () {
- origTransform = this.transform().local;
- });
- }
- function start(e, x, y) {
- (e.originalEvent || e).preventDefault();
- el._drag.x = x;
- el._drag.y = y;
- el._drag.id = e.identifier;
- !drag.length && Snap.mousemove(dragMove).mouseup(dragUp);
- drag.push({el: el, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});
- onstart && eve.on("snap.drag.start." + el.id, onstart);
- onmove && eve.on("snap.drag.move." + el.id, onmove);
- onend && eve.on("snap.drag.end." + el.id, onend);
- eve("snap.drag.start." + el.id, start_scope || move_scope || el, x, y, e);
- }
- function init(e, x, y) {
- eve("snap.draginit." + el.id, el, e, x, y);
- }
- eve.on("snap.draginit." + el.id, start);
- el._drag = {};
- draggable.push({el: el, start: start, init: init});
- el.mousedown(init);
- return el;
- };
- /*
- * Element.onDragOver
- [ method ]
- **
- * Shortcut to assign event handler for `drag.over.<id>` event, where `id` is the element's `id` (see @Element.id)
- - f (function) handler for event, first argument would be the element you are dragging over
- \*/
- // elproto.onDragOver = function (f) {
- // f ? eve.on("snap.drag.over." + this.id, f) : eve.unbind("snap.drag.over." + this.id);
- // };
- /*\
- * Element.undrag
- [ method ]
- **
- * Removes all drag event handlers from the given element
- \*/
- elproto.undrag = function () {
- var i = draggable.length;
- while (i--) if (draggable[i].el == this) {
- this.unmousedown(draggable[i].init);
- draggable.splice(i, 1);
- eve.unbind("snap.drag.*." + this.id);
- eve.unbind("snap.draginit." + this.id);
- }
- !draggable.length && Snap.unmousemove(dragMove).unmouseup(dragUp);
- return this;
- };
- });
-
- // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob) {
- var elproto = Element.prototype,
- pproto = Paper.prototype,
- rgurl = /^\s*url\((.+)\)/,
- Str = String,
- $ = Snap._.$;
- Snap.filter = {};
- /*\
- * Paper.filter
- [ method ]
- **
- * Creates a `<filter>` element
- **
- - filstr (string) SVG fragment of filter provided as a string
- = (object) @Element
- * Note: It is recommended to use filters embedded into the page inside an empty SVG element.
- > Usage
- | var f = paper.filter('<feGaussianBlur stdDeviation="2"/>'),
- | c = paper.circle(10, 10, 10).attr({
- | filter: f
- | });
- \*/
- pproto.filter = function (filstr) {
- var paper = this;
- if (paper.type != "svg") {
- paper = paper.paper;
- }
- var f = Snap.parse(Str(filstr)),
- id = Snap._.id(),
- width = paper.node.offsetWidth,
- height = paper.node.offsetHeight,
- filter = $("filter");
- $(filter, {
- id: id,
- filterUnits: "userSpaceOnUse"
- });
- filter.appendChild(f.node);
- paper.defs.appendChild(filter);
- return new Element(filter);
- };
-
- eve.on("snap.util.getattr.filter", function () {
- eve.stop();
- var p = $(this.node, "filter");
- if (p) {
- var match = Str(p).match(rgurl);
- return match && Snap.select(match[1]);
- }
- });
- eve.on("snap.util.attr.filter", function (value) {
- if (value instanceof Element && value.type == "filter") {
- eve.stop();
- var id = value.node.id;
- if (!id) {
- $(value.node, {id: value.id});
- id = value.id;
- }
- $(this.node, {
- filter: Snap.url(id)
- });
- }
- if (!value || value == "none") {
- eve.stop();
- this.node.removeAttribute("filter");
- }
- });
- /*\
- * Snap.filter.blur
- [ method ]
- **
- * Returns an SVG markup string for the blur filter
- **
- - x (number) amount of horizontal blur, in pixels
- - y (number) #optional amount of vertical blur, in pixels
- = (string) filter representation
- > Usage
- | var f = paper.filter(Snap.filter.blur(5, 10)),
- | c = paper.circle(10, 10, 10).attr({
- | filter: f
- | });
- \*/
- Snap.filter.blur = function (x, y) {
- if (x == null) {
- x = 2;
- }
- var def = y == null ? x : [x, y];
- return Snap.format('\<feGaussianBlur stdDeviation="{def}"/>', {
- def: def
- });
- };
- Snap.filter.blur.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.shadow
- [ method ]
- **
- * Returns an SVG markup string for the shadow filter
- **
- - dx (number) #optional horizontal shift of the shadow, in pixels
- - dy (number) #optional vertical shift of the shadow, in pixels
- - blur (number) #optional amount of blur
- - color (string) #optional color of the shadow
- - opacity (number) #optional `0..1` opacity of the shadow
- * or
- - dx (number) #optional horizontal shift of the shadow, in pixels
- - dy (number) #optional vertical shift of the shadow, in pixels
- - color (string) #optional color of the shadow
- - opacity (number) #optional `0..1` opacity of the shadow
- * which makes blur default to `4`. Or
- - dx (number) #optional horizontal shift of the shadow, in pixels
- - dy (number) #optional vertical shift of the shadow, in pixels
- - opacity (number) #optional `0..1` opacity of the shadow
- = (string) filter representation
- > Usage
- | var f = paper.filter(Snap.filter.shadow(0, 2, 3)),
- | c = paper.circle(10, 10, 10).attr({
- | filter: f
- | });
- \*/
- Snap.filter.shadow = function (dx, dy, blur, color, opacity) {
- if (typeof blur == "string") {
- color = blur;
- opacity = color;
- blur = 4;
- }
- if (typeof color != "string") {
- opacity = color;
- color = "#000";
- }
- color = color || "#000";
- if (blur == null) {
- blur = 4;
- }
- if (opacity == null) {
- opacity = 1;
- }
- if (dx == null) {
- dx = 0;
- dy = 2;
- }
- if (dy == null) {
- dy = dx;
- }
- color = Snap.color(color);
- return Snap.format('<feGaussianBlur in="SourceAlpha" stdDeviation="{blur}"/><feOffset dx="{dx}" dy="{dy}" result="offsetblur"/><feFlood flood-color="{color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="{opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>', {
- color: color,
- dx: dx,
- dy: dy,
- blur: blur,
- opacity: opacity
- });
- };
- Snap.filter.shadow.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.grayscale
- [ method ]
- **
- * Returns an SVG markup string for the grayscale filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.grayscale = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {b} {h} 0 0 0 0 0 1 0"/>', {
- a: 0.2126 + 0.7874 * (1 - amount),
- b: 0.7152 - 0.7152 * (1 - amount),
- c: 0.0722 - 0.0722 * (1 - amount),
- d: 0.2126 - 0.2126 * (1 - amount),
- e: 0.7152 + 0.2848 * (1 - amount),
- f: 0.0722 - 0.0722 * (1 - amount),
- g: 0.2126 - 0.2126 * (1 - amount),
- h: 0.0722 + 0.9278 * (1 - amount)
- });
- };
- Snap.filter.grayscale.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.sepia
- [ method ]
- **
- * Returns an SVG markup string for the sepia filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.sepia = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {h} {i} 0 0 0 0 0 1 0"/>', {
- a: 0.393 + 0.607 * (1 - amount),
- b: 0.769 - 0.769 * (1 - amount),
- c: 0.189 - 0.189 * (1 - amount),
- d: 0.349 - 0.349 * (1 - amount),
- e: 0.686 + 0.314 * (1 - amount),
- f: 0.168 - 0.168 * (1 - amount),
- g: 0.272 - 0.272 * (1 - amount),
- h: 0.534 - 0.534 * (1 - amount),
- i: 0.131 + 0.869 * (1 - amount)
- });
- };
- Snap.filter.sepia.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.saturate
- [ method ]
- **
- * Returns an SVG markup string for the saturate filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.saturate = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feColorMatrix type="saturate" values="{amount}"/>', {
- amount: 1 - amount
- });
- };
- Snap.filter.saturate.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.hueRotate
- [ method ]
- **
- * Returns an SVG markup string for the hue-rotate filter
- **
- - angle (number) angle of rotation
- = (string) filter representation
- \*/
- Snap.filter.hueRotate = function (angle) {
- angle = angle || 0;
- return Snap.format('<feColorMatrix type="hueRotate" values="{angle}"/>', {
- angle: angle
- });
- };
- Snap.filter.hueRotate.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.invert
- [ method ]
- **
- * Returns an SVG markup string for the invert filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.invert = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- // <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB"/>
- return Snap.format('<feComponentTransfer><feFuncR type="table" tableValues="{amount} {amount2}"/><feFuncG type="table" tableValues="{amount} {amount2}"/><feFuncB type="table" tableValues="{amount} {amount2}"/></feComponentTransfer>', {
- amount: amount,
- amount2: 1 - amount
- });
- };
- Snap.filter.invert.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.brightness
- [ method ]
- **
- * Returns an SVG markup string for the brightness filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.brightness = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}"/><feFuncG type="linear" slope="{amount}"/><feFuncB type="linear" slope="{amount}"/></feComponentTransfer>', {
- amount: amount
- });
- };
- Snap.filter.brightness.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.contrast
- [ method ]
- **
- * Returns an SVG markup string for the contrast filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.contrast = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}" intercept="{amount2}"/><feFuncG type="linear" slope="{amount}" intercept="{amount2}"/><feFuncB type="linear" slope="{amount}" intercept="{amount2}"/></feComponentTransfer>', {
- amount: amount,
- amount2: .5 - amount / 2
- });
- };
- Snap.filter.contrast.toString = function () {
- return this();
- };
- });
-
- // Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
- var box = Snap._.box,
- is = Snap.is,
- firstLetter = /^[^a-z]*([tbmlrc])/i,
- toString = function () {
- return "T" + this.dx + "," + this.dy;
- };
- /*\
- * Element.getAlign
- [ method ]
- **
- * Returns shift needed to align the element relatively to given element.
- * If no elements specified, parent `<svg>` container will be used.
- - el (object) @optional alignment element
- - way (string) one of six values: `"top"`, `"middle"`, `"bottom"`, `"left"`, `"center"`, `"right"`
- = (object|string) Object in format `{dx: , dy: }` also has a string representation as a transformation string
- > Usage
- | el.transform(el.getAlign(el2, "top"));
- * or
- | var dy = el.getAlign(el2, "top").dy;
- \*/
- Element.prototype.getAlign = function (el, way) {
- if (way == null && is(el, "string")) {
- way = el;
- el = null;
- }
- el = el || this.paper;
- var bx = el.getBBox ? el.getBBox() : box(el),
- bb = this.getBBox(),
- out = {};
- way = way && way.match(firstLetter);
- way = way ? way[1].toLowerCase() : "c";
- switch (way) {
- case "t":
- out.dx = 0;
- out.dy = bx.y - bb.y;
- break;
- case "b":
- out.dx = 0;
- out.dy = bx.y2 - bb.y2;
- break;
- case "m":
- out.dx = 0;
- out.dy = bx.cy - bb.cy;
- break;
- case "l":
- out.dx = bx.x - bb.x;
- out.dy = 0;
- break;
- case "r":
- out.dx = bx.x2 - bb.x2;
- out.dy = 0;
- break;
- default:
- out.dx = bx.cx - bb.cx;
- out.dy = 0;
- break;
- }
- out.toString = toString;
- return out;
- };
- /*\
- * Element.align
- [ method ]
- **
- * Aligns the element relatively to given one via transformation.
- * If no elements specified, parent `<svg>` container will be used.
- - el (object) @optional alignment element
- - way (string) one of six values: `"top"`, `"middle"`, `"bottom"`, `"left"`, `"center"`, `"right"`
- = (object) this element
- > Usage
- | el.align(el2, "top");
- * or
- | el.align("middle");
- \*/
- Element.prototype.align = function (el, way) {
- return this.transform("..." + this.getAlign(el, way));
- };
- });
-
- return Snap;
- }));
- }.call(window));
-
-/***/ },
-/* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
- /* Enabling us to resize a shape width a handler
- #http://stackoverflow.com/questions/32390028/how-to-drag-and-resize-svg-rectangle-using-cursor-types
- */
- eventEmitter = __webpack_require__(4)({});
-
- var ShapeResizer = function (paper, shape) {
- this.paper = paper;
- this.shape = shape;
- this.handlers = [];
- this.isResizing = false;
- this.currentPosition = {};
- this.HANDLER_SIZE = 8;
- this.SHAPE_MIN_SIZE = 20;
- this.states = {};
- this.noop = function (){}
- this.init();
- }
-
- var api = ShapeResizer.prototype = {
-
- init: function () {
- this.showHandlers();
- },
-
- showHandlers: function () {
- /* show handler here */
- var bbox = this.shape.getBBox();
- var handleX = bbox.x - this.HANDLER_SIZE/2;
- var handleY = bbox.y - this.HANDLER_SIZE/2;
- handler = this.paper.rect(handleX, handleY, this.HANDLER_SIZE, this.HANDLER_SIZE).attr({fill: 'red'});
- var handlerInfos = {position: "t_r", handler: handler};
- this.handlers.push(handlerInfos);
- this.shapesGroup = this.paper.g(this.shape, handler);
- this.attachEvents();
- },
-
- /*one handlers */
- updateShapePositions: function (handlerData, dx, dy) {
- //start
- var handlerBBox = handlerData.handler.getBBox();
- var shapeBBox = this.shape.data("origBbox");
- var newX = handlerBBox.x + this.HANDLER_SIZE / 2;
- var newY = handlerBBox.y + this.HANDLER_SIZE / 2;
-
- /*to the right => reduce the size */
- var newWidth = (dx > 0) ? shapeBBox.width - dx : shapeBBox.width + Math.abs(dx);
- var newHeight = (dy > 0) ? shapeBBox.height - dy : shapeBBox.height + Math.abs(dy);
- var transformValue = this.shape.data('origTransform') + (this.shape.data('origTransform') ? "T" : "t") + [dx, dy];
- this.shape.attr({'transform': transformValue, width: newWidth, height: newHeight});
- },
-
- dragEvents: {
- onStart: function (handlerData, dx, dy, e) {
- this.startPosition = {x: e.clientX, y: e.clientY};
- this.isResizing = true;
- this.currentPosition = {};
- handlerData.handler.data("origTransform", handlerData.handler.transform().local);
- this.shape.data("origBbox", this.shape.getBBox());
- this.shape.data("origTransform", this.shape.transform().local);
- },
-
- onMove: function (handlerData, dx, dy, x, y, e) {
- var transformValue = handlerData.handler.data('origTransform') + (handlerData.handler.data('origTransform') ? "T" : "t") + [dx, dy];
- this.currentPosition.x = e.clientX;
- this.currentPosition.y = e.clientY;
- /* deal with boundaries */
- if (! this.checkBondaries(dx, dy)) { return; }
- handlerData.handler.attr({ transform: transformValue});
- this.updateShapePositions(handlerData, dx, dy);
- },
-
- onStop: function () {
- this.isResizing = false;
- this.startPosition = {};
- this.currentPosition = {};
- }
- },
-
- checkBondaries: function (dx, dy) {
- var result = true;
-
- if (this.shape.data("origBbox").width - dx <= this.SHAPE_MIN_SIZE) {
- result = false;
- }
-
- if (this.shape.data("origBbox").height - dy <= this.SHAPE_MIN_SIZE) {
- result = false;
- }
-
- return result;
- },
-
- destroy: function () {
- this.handlers.map(function (handlerData) {
- handlerData.handler.remove();
- });
- delete this;
- },
-
- attachEvents: function () {
- var self = this;
- this.handlers.map(function (handlerData) {
- handlerData.handler.drag(
- self.dragEvents.onMove.bind(self, handlerData),
- self.dragEvents.onStart.bind(self, handlerData),
- self.dragEvents.onStop.bind(self, handlerData));
- });
-
- eventEmitter.on("cutout:clear", function () {
- self.destroy();
- });
-
- this.shapesGroup.drag(function (dx, dy) {
- if (self.isResizing) { return; }
- var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy];
- this.transform(transformValue);
- }, function () {
- this.data('origTransform', this.transform().local);
- }, this.noop);
- },
- }
-
- module.exports = {
-
- apply_resize : function (paper, rect) {
- new ShapeResizer(paper, rect);
- }
- }
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var d = __webpack_require__(5)
- , callable = __webpack_require__(18)
-
- , apply = Function.prototype.apply, call = Function.prototype.call
- , create = Object.create, defineProperty = Object.defineProperty
- , defineProperties = Object.defineProperties
- , hasOwnProperty = Object.prototype.hasOwnProperty
- , descriptor = { configurable: true, enumerable: false, writable: true }
-
- , on, once, off, emit, methods, descriptors, base;
-
- on = function (type, listener) {
- var data;
-
- callable(listener);
-
- if (!hasOwnProperty.call(this, '__ee__')) {
- data = descriptor.value = create(null);
- defineProperty(this, '__ee__', descriptor);
- descriptor.value = null;
- } else {
- data = this.__ee__;
- }
- if (!data[type]) data[type] = listener;
- else if (typeof data[type] === 'object') data[type].push(listener);
- else data[type] = [data[type], listener];
-
- return this;
- };
-
- once = function (type, listener) {
- var once, self;
-
- callable(listener);
- self = this;
- on.call(this, type, once = function () {
- off.call(self, type, once);
- apply.call(listener, this, arguments);
- });
-
- once.__eeOnceListener__ = listener;
- return this;
- };
-
- off = function (type, listener) {
- var data, listeners, candidate, i;
-
- callable(listener);
-
- if (!hasOwnProperty.call(this, '__ee__')) return this;
- data = this.__ee__;
- if (!data[type]) return this;
- listeners = data[type];
-
- if (typeof listeners === 'object') {
- for (i = 0; (candidate = listeners[i]); ++i) {
- if ((candidate === listener) ||
- (candidate.__eeOnceListener__ === listener)) {
- if (listeners.length === 2) data[type] = listeners[i ? 0 : 1];
- else listeners.splice(i, 1);
- }
- }
- } else {
- if ((listeners === listener) ||
- (listeners.__eeOnceListener__ === listener)) {
- delete data[type];
- }
- }
-
- return this;
- };
-
- emit = function (type) {
- var i, l, listener, listeners, args;
-
- if (!hasOwnProperty.call(this, '__ee__')) return;
- listeners = this.__ee__[type];
- if (!listeners) return;
-
- if (typeof listeners === 'object') {
- l = arguments.length;
- args = new Array(l - 1);
- for (i = 1; i < l; ++i) args[i - 1] = arguments[i];
-
- listeners = listeners.slice();
- for (i = 0; (listener = listeners[i]); ++i) {
- apply.call(listener, this, args);
- }
- } else {
- switch (arguments.length) {
- case 1:
- call.call(listeners, this);
- break;
- case 2:
- call.call(listeners, this, arguments[1]);
- break;
- case 3:
- call.call(listeners, this, arguments[1], arguments[2]);
- break;
- default:
- l = arguments.length;
- args = new Array(l - 1);
- for (i = 1; i < l; ++i) {
- args[i - 1] = arguments[i];
- }
- apply.call(listeners, this, args);
- }
- }
- };
-
- methods = {
- on: on,
- once: once,
- off: off,
- emit: emit
- };
-
- descriptors = {
- on: d(on),
- once: d(once),
- off: d(off),
- emit: d(emit)
- };
-
- base = defineProperties({}, descriptors);
-
- module.exports = exports = function (o) {
- return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
- };
- exports.methods = methods;
-
-
-/***/ },
-/* 5 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var assign = __webpack_require__(6)
- , normalizeOpts = __webpack_require__(13)
- , isCallable = __webpack_require__(14)
- , contains = __webpack_require__(15)
-
- , d;
-
- d = module.exports = function (dscr, value/*, options*/) {
- var c, e, w, options, desc;
- if ((arguments.length < 2) || (typeof dscr !== 'string')) {
- options = value;
- value = dscr;
- dscr = null;
- } else {
- options = arguments[2];
- }
- if (dscr == null) {
- c = w = true;
- e = false;
- } else {
- c = contains.call(dscr, 'c');
- e = contains.call(dscr, 'e');
- w = contains.call(dscr, 'w');
- }
-
- desc = { value: value, configurable: c, enumerable: e, writable: w };
- return !options ? desc : assign(normalizeOpts(options), desc);
- };
-
- d.gs = function (dscr, get, set/*, options*/) {
- var c, e, options, desc;
- if (typeof dscr !== 'string') {
- options = set;
- set = get;
- get = dscr;
- dscr = null;
- } else {
- options = arguments[3];
- }
- if (get == null) {
- get = undefined;
- } else if (!isCallable(get)) {
- options = get;
- get = set = undefined;
- } else if (set == null) {
- set = undefined;
- } else if (!isCallable(set)) {
- options = set;
- set = undefined;
- }
- if (dscr == null) {
- c = true;
- e = false;
- } else {
- c = contains.call(dscr, 'c');
- e = contains.call(dscr, 'e');
- }
-
- desc = { get: get, set: set, configurable: c, enumerable: e };
- return !options ? desc : assign(normalizeOpts(options), desc);
- };
-
-
-/***/ },
-/* 6 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = __webpack_require__(7)()
- ? Object.assign
- : __webpack_require__(8);
-
-
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- module.exports = function () {
- var assign = Object.assign, obj;
- if (typeof assign !== 'function') return false;
- obj = { foo: 'raz' };
- assign(obj, { bar: 'dwa' }, { trzy: 'trzy' });
- return (obj.foo + obj.bar + obj.trzy) === 'razdwatrzy';
- };
-
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var keys = __webpack_require__(9)
- , value = __webpack_require__(12)
-
- , max = Math.max;
-
- module.exports = function (dest, src/*, …srcn*/) {
- var error, i, l = max(arguments.length, 2), assign;
- dest = Object(value(dest));
- assign = function (key) {
- try { dest[key] = src[key]; } catch (e) {
- if (!error) error = e;
- }
- };
- for (i = 1; i < l; ++i) {
- src = arguments[i];
- keys(src).forEach(assign);
- }
- if (error !== undefined) throw error;
- return dest;
- };
-
-
-/***/ },
-/* 9 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = __webpack_require__(10)()
- ? Object.keys
- : __webpack_require__(11);
-
-
-/***/ },
-/* 10 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- module.exports = function () {
- try {
- Object.keys('primitive');
- return true;
- } catch (e) { return false; }
- };
-
-
-/***/ },
-/* 11 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var keys = Object.keys;
-
- module.exports = function (object) {
- return keys(object == null ? object : Object(object));
- };
-
-
-/***/ },
-/* 12 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- module.exports = function (value) {
- if (value == null) throw new TypeError("Cannot use null or undefined");
- return value;
- };
-
-
-/***/ },
-/* 13 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var forEach = Array.prototype.forEach, create = Object.create;
-
- var process = function (src, obj) {
- var key;
- for (key in src) obj[key] = src[key];
- };
-
- module.exports = function (options/*, …options*/) {
- var result = create(null);
- forEach.call(arguments, function (options) {
- if (options == null) return;
- process(Object(options), result);
- });
- return result;
- };
-
-
-/***/ },
-/* 14 */
-/***/ function(module, exports) {
-
- // Deprecated
-
- 'use strict';
-
- module.exports = function (obj) { return typeof obj === 'function'; };
-
-
-/***/ },
-/* 15 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = __webpack_require__(16)()
- ? String.prototype.contains
- : __webpack_require__(17);
-
-
-/***/ },
-/* 16 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var str = 'razdwatrzy';
-
- module.exports = function () {
- if (typeof str.contains !== 'function') return false;
- return ((str.contains('dwa') === true) && (str.contains('foo') === false));
- };
-
-
-/***/ },
-/* 17 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var indexOf = String.prototype.indexOf;
-
- module.exports = function (searchString/*, position*/) {
- return indexOf.call(this, searchString, arguments[1]) > -1;
- };
-
-
-/***/ },
-/* 18 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- module.exports = function (fn) {
- if (typeof fn !== 'function') throw new TypeError(fn + " is not a function");
- return fn;
- };
-
-
-/***/ },
-/* 19 */
-/***/ function(module, exports, __webpack_require__) {
-
- /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["jQuery"] = __webpack_require__(20);
- /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 20 */
-/***/ function(module, exports, __webpack_require__) {
-
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
- * jQuery JavaScript Library v2.2.4
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2016-05-20T17:23Z
- */
-
- (function( global, factory ) {
-
- if ( typeof module === "object" && typeof module.exports === "object" ) {
- // For CommonJS and CommonJS-like environments where a proper `window`
- // is present, execute the factory and get jQuery.
- // For environments that do not have a `window` with a `document`
- // (such as Node.js), expose a factory as module.exports.
- // This accentuates the need for the creation of a real `window`.
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info.
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
- // Pass this if window is not defined yet
- }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
- // Support: Firefox 18+
- // Can't be in strict mode, several libs including ASP.NET trace
- // the stack via arguments.caller.callee and Firefox dies if
- // you try to trace through "use strict" call chains. (#13335)
- //"use strict";
- var arr = [];
-
- var document = window.document;
-
- var slice = arr.slice;
-
- var concat = arr.concat;
-
- var push = arr.push;
-
- var indexOf = arr.indexOf;
-
- var class2type = {};
-
- var toString = class2type.toString;
-
- var hasOwn = class2type.hasOwnProperty;
-
- var support = {};
-
-
-
- var
- version = "2.2.4",
-
- // Define a local copy of jQuery
- jQuery = function( selector, context ) {
-
- // The jQuery object is actually just the init constructor 'enhanced'
- // Need init if jQuery is called (just allow error to be thrown if not included)
- return new jQuery.fn.init( selector, context );
- },
-
- // Support: Android<4.1
- // Make sure we trim BOM and NBSP
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
- // Matches dashed string for camelizing
- rmsPrefix = /^-ms-/,
- rdashAlpha = /-([\da-z])/gi,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
- };
-
- jQuery.fn = jQuery.prototype = {
-
- // The current version of jQuery being used
- jquery: version,
-
- constructor: jQuery,
-
- // Start with an empty selector
- selector: "",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- toArray: function() {
- return slice.call( this );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num != null ?
-
- // Return just the one element from the set
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
- // Return all the elements in a clean array
- slice.call( this );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
-
- // Build a new jQuery matched element set
- var ret = jQuery.merge( this.constructor(), elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- each: function( callback ) {
- return jQuery.each( this, callback );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map( this, function( elem, i ) {
- return callback.call( elem, i, elem );
- } ) );
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ) );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- eq: function( i ) {
- var len = this.length,
- j = +i + ( i < 0 ? len : 0 );
- return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
- },
-
- end: function() {
- return this.prevObject || this.constructor();
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: arr.sort,
- splice: arr.splice
- };
-
- jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[ 0 ] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
-
- // Skip the boolean and the target
- target = arguments[ i ] || {};
- i++;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
- target = {};
- }
-
- // Extend jQuery itself if only one argument is passed
- if ( i === length ) {
- target = this;
- i--;
- }
-
- for ( ; i < length; i++ ) {
-
- // Only deal with non-null/undefined values
- if ( ( options = arguments[ i ] ) != null ) {
-
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
- ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
-
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && jQuery.isArray( src ) ? src : [];
-
- } else {
- clone = src && jQuery.isPlainObject( src ) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
- };
-
- jQuery.extend( {
-
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
- // Assume jQuery is ready without the ready module
- isReady: true,
-
- error: function( msg ) {
- throw new Error( msg );
- },
-
- noop: function() {},
-
- isFunction: function( obj ) {
- return jQuery.type( obj ) === "function";
- },
-
- isArray: Array.isArray,
-
- isWindow: function( obj ) {
- return obj != null && obj === obj.window;
- },
-
- isNumeric: function( obj ) {
-
- // parseFloat NaNs numeric-cast false positives (null|true|false|"")
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
- // subtraction forces infinities to NaN
- // adding 1 corrects loss of precision from parseFloat (#15100)
- var realStringObj = obj && obj.toString();
- return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
- },
-
- isPlainObject: function( obj ) {
- var key;
-
- // Not plain objects:
- // - Any object or value whose internal [[Class]] property is not "[object Object]"
- // - DOM nodes
- // - window
- if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- // Not own constructor property must be Object
- if ( obj.constructor &&
- !hasOwn.call( obj, "constructor" ) &&
- !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
- return false;
- }
-
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own
- for ( key in obj ) {}
-
- return key === undefined || hasOwn.call( obj, key );
- },
-
- isEmptyObject: function( obj ) {
- var name;
- for ( name in obj ) {
- return false;
- }
- return true;
- },
-
- type: function( obj ) {
- if ( obj == null ) {
- return obj + "";
- }
-
- // Support: Android<4.0, iOS<6 (functionish RegExp)
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call( obj ) ] || "object" :
- typeof obj;
- },
-
- // Evaluates a script in a global context
- globalEval: function( code ) {
- var script,
- indirect = eval;
-
- code = jQuery.trim( code );
-
- if ( code ) {
-
- // If the code includes a valid, prologue position
- // strict mode pragma, execute code by injecting a
- // script tag into the document.
- if ( code.indexOf( "use strict" ) === 1 ) {
- script = document.createElement( "script" );
- script.text = code;
- document.head.appendChild( script ).parentNode.removeChild( script );
- } else {
-
- // Otherwise, avoid the DOM node creation, insertion
- // and removal by using an indirect global eval
-
- indirect( code );
- }
- }
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Support: IE9-11+
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
- },
-
- each: function( obj, callback ) {
- var length, i = 0;
-
- if ( isArrayLike( obj ) ) {
- length = obj.length;
- for ( ; i < length; i++ ) {
- if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
- break;
- }
- }
- }
-
- return obj;
- },
-
- // Support: Android<4.1
- trim: function( text ) {
- return text == null ?
- "" :
- ( text + "" ).replace( rtrim, "" );
- },
-
- // results is for internal usage only
- makeArray: function( arr, results ) {
- var ret = results || [];
-
- if ( arr != null ) {
- if ( isArrayLike( Object( arr ) ) ) {
- jQuery.merge( ret,
- typeof arr === "string" ?
- [ arr ] : arr
- );
- } else {
- push.call( ret, arr );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, arr, i ) {
- return arr == null ? -1 : indexOf.call( arr, elem, i );
- },
-
- merge: function( first, second ) {
- var len = +second.length,
- j = 0,
- i = first.length;
-
- for ( ; j < len; j++ ) {
- first[ i++ ] = second[ j ];
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, invert ) {
- var callbackInverse,
- matches = [],
- i = 0,
- length = elems.length,
- callbackExpect = !invert;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( ; i < length; i++ ) {
- callbackInverse = !callback( elems[ i ], i );
- if ( callbackInverse !== callbackExpect ) {
- matches.push( elems[ i ] );
- }
- }
-
- return matches;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var length, value,
- i = 0,
- ret = [];
-
- // Go through the array, translating each of the items to their new values
- if ( isArrayLike( elems ) ) {
- length = elems.length;
- for ( ; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
-
- // Go through every key on the object,
- } else {
- for ( i in elems ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
- }
-
- // Flatten any nested arrays
- return concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- var tmp, args, proxy;
-
- if ( typeof context === "string" ) {
- tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- args = slice.call( arguments, 2 );
- proxy = function() {
- return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
- return proxy;
- },
-
- now: Date.now,
-
- // jQuery.support is not used in Core but other projects attach their
- // properties to it so it needs to exist.
- support: support
- } );
-
- // JSHint would error on this code due to the Symbol not being defined in ES5.
- // Defining this global in .jshintrc would create a danger of using the global
- // unguarded in another place, it seems safer to just disable JSHint for these
- // three lines.
- /* jshint ignore: start */
- if ( typeof Symbol === "function" ) {
- jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
- }
- /* jshint ignore: end */
-
- // Populate the class2type map
- jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
- function( i, name ) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
- } );
-
- function isArrayLike( obj ) {
-
- // Support: iOS 8.2 (not reproducible in simulator)
- // `in` check used to prevent JIT error (gh-2145)
- // hasOwn isn't used here due to false negatives
- // regarding Nodelist length in IE
- var length = !!obj && "length" in obj && obj.length,
- type = jQuery.type( obj );
-
- if ( type === "function" || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && ( length - 1 ) in obj;
- }
- var Sizzle =
- /*!
- * Sizzle CSS Selector Engine v2.2.1
- * http://sizzlejs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-10-17
- */
- (function( window ) {
-
- var i,
- support,
- Expr,
- getText,
- isXML,
- tokenize,
- compile,
- select,
- outermostContext,
- sortInput,
- hasDuplicate,
-
- // Local document vars
- setDocument,
- document,
- docElem,
- documentIsHTML,
- rbuggyQSA,
- rbuggyMatches,
- matches,
- contains,
-
- // Instance-specific data
- expando = "sizzle" + 1 * new Date(),
- preferredDoc = window.document,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- }
- return 0;
- },
-
- // General-purpose constants
- MAX_NEGATIVE = 1 << 31,
-
- // Instance methods
- hasOwn = ({}).hasOwnProperty,
- arr = [],
- pop = arr.pop,
- push_native = arr.push,
- push = arr.push,
- slice = arr.slice,
- // Use a stripped-down indexOf as it's faster than native
- // http://jsperf.com/thor-indexof-vs-for/5
- indexOf = function( list, elem ) {
- var i = 0,
- len = list.length;
- for ( ; i < len; i++ ) {
- if ( list[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
- // Regular expressions
-
- // http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
-
- // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
- // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
- // Operator (capture 2)
- "*([*^$|!~]?=)" + whitespace +
- // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
- "*\\]",
-
- pseudos = ":(" + identifier + ")(?:\\((" +
- // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
- // 1. quoted (capture 3; capture 4 or capture 5)
- "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
- // 2. simple (capture 6)
- "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
- // 3. anything else (capture 2)
- ".*" +
- ")\\)|)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rwhitespace = new RegExp( whitespace + "+", "g" ),
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
- rpseudo = new RegExp( pseudos ),
- ridentifier = new RegExp( "^" + identifier + "$" ),
-
- matchExpr = {
- "ID": new RegExp( "^#(" + identifier + ")" ),
- "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
- "TAG": new RegExp( "^(" + identifier + "|[*])" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
- whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
- },
-
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
-
- rnative = /^[^{]+\{\s*\[native \w/,
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
- rsibling = /[+~]/,
- rescape = /'|\\/g,
-
- // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
- funescape = function( _, escaped, escapedWhitespace ) {
- var high = "0x" + escaped - 0x10000;
- // NaN means non-codepoint
- // Support: Firefox<24
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ?
- escaped :
- high < 0 ?
- // BMP codepoint
- String.fromCharCode( high + 0x10000 ) :
- // Supplemental Plane codepoint (surrogate pair)
- String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
- },
-
- // Used for iframes
- // See setDocument()
- // Removing the function wrapper causes a "Permission Denied"
- // error in IE
- unloadHandler = function() {
- setDocument();
- };
-
- // Optimize for push.apply( _, NodeList )
- try {
- push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
- preferredDoc.childNodes
- );
- // Support: Android<4.0
- // Detect silently failing push.apply
- arr[ preferredDoc.childNodes.length ].nodeType;
- } catch ( e ) {
- push = { apply: arr.length ?
-
- // Leverage slice if possible
- function( target, els ) {
- push_native.apply( target, slice.call(els) );
- } :
-
- // Support: IE<9
- // Otherwise append directly
- function( target, els ) {
- var j = target.length,
- i = 0;
- // Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
- target.length = j - 1;
- }
- };
- }
-
- function Sizzle( selector, context, results, seed ) {
- var m, i, elem, nid, nidselect, match, groups, newSelector,
- newContext = context && context.ownerDocument,
-
- // nodeType defaults to 9, since context defaults to document
- nodeType = context ? context.nodeType : 9;
-
- results = results || [];
-
- // Return early from calls with invalid selector or context
- if ( typeof selector !== "string" || !selector ||
- nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
- return results;
- }
-
- // Try to shortcut find operations (as opposed to filters) in HTML documents
- if ( !seed ) {
-
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
- setDocument( context );
- }
- context = context || document;
-
- if ( documentIsHTML ) {
-
- // If the selector is sufficiently simple, try using a "get*By*" DOM method
- // (excepting DocumentFragment context, where the methods don't exist)
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
-
- // ID selector
- if ( (m = match[1]) ) {
-
- // Document context
- if ( nodeType === 9 ) {
- if ( (elem = context.getElementById( m )) ) {
-
- // Support: IE, Opera, Webkit
- // TODO: identify versions
- // getElementById can match elements by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
-
- // Element context
- } else {
-
- // Support: IE, Opera, Webkit
- // TODO: identify versions
- // getElementById can match elements by name instead of ID
- if ( newContext && (elem = newContext.getElementById( m )) &&
- contains( context, elem ) &&
- elem.id === m ) {
-
- results.push( elem );
- return results;
- }
- }
-
- // Type selector
- } else if ( match[2] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
- return results;
-
- // Class selector
- } else if ( (m = match[3]) && support.getElementsByClassName &&
- context.getElementsByClassName ) {
-
- push.apply( results, context.getElementsByClassName( m ) );
- return results;
- }
- }
-
- // Take advantage of querySelectorAll
- if ( support.qsa &&
- !compilerCache[ selector + " " ] &&
- (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
-
- if ( nodeType !== 1 ) {
- newContext = context;
- newSelector = selector;
-
- // qSA looks outside Element context, which is not what we want
- // Thanks to Andrew Dupont for this workaround technique
- // Support: IE <=8
- // Exclude object elements
- } else if ( context.nodeName.toLowerCase() !== "object" ) {
-
- // Capture the context ID, setting it first if necessary
- if ( (nid = context.getAttribute( "id" )) ) {
- nid = nid.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", (nid = expando) );
- }
-
- // Prefix every selector in the list
- groups = tokenize( selector );
- i = groups.length;
- nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
- while ( i-- ) {
- groups[i] = nidselect + " " + toSelector( groups[i] );
- }
- newSelector = groups.join( "," );
-
- // Expand context for sibling selectors
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
- context;
- }
-
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
- return results;
- } catch ( qsaError ) {
- } finally {
- if ( nid === expando ) {
- context.removeAttribute( "id" );
- }
- }
- }
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed );
- }
-
- /**
- * Create key-value caches of limited size
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- * deleting the oldest entry
- */
- function createCache() {
- var keys = [];
-
- function cache( key, value ) {
- // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
- // Only keep the most recent entries
- delete cache[ keys.shift() ];
- }
- return (cache[ key + " " ] = value);
- }
- return cache;
- }
-
- /**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
- function markFunction( fn ) {
- fn[ expando ] = true;
- return fn;
- }
-
- /**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
- function assert( fn ) {
- var div = document.createElement("div");
-
- try {
- return !!fn( div );
- } catch (e) {
- return false;
- } finally {
- // Remove from its parent by default
- if ( div.parentNode ) {
- div.parentNode.removeChild( div );
- }
- // release memory in IE
- div = null;
- }
- }
-
- /**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
- function addHandle( attrs, handler ) {
- var arr = attrs.split("|"),
- i = arr.length;
-
- while ( i-- ) {
- Expr.attrHandle[ arr[i] ] = handler;
- }
- }
-
- /**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
- function siblingCheck( a, b ) {
- var cur = b && a,
- diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
- ( ~b.sourceIndex || MAX_NEGATIVE ) -
- ( ~a.sourceIndex || MAX_NEGATIVE );
-
- // Use IE sourceIndex if available on both nodes
- if ( diff ) {
- return diff;
- }
-
- // Check if b follows a
- if ( cur ) {
- while ( (cur = cur.nextSibling) ) {
- if ( cur === b ) {
- return -1;
- }
- }
- }
-
- return a ? 1 : -1;
- }
-
- /**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
- function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
- }
-
- /**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
- function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
- }
-
- /**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
- function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
- }
-
- /**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
- function testContext( context ) {
- return context && typeof context.getElementsByTagName !== "undefined" && context;
- }
-
- // Expose support vars for convenience
- support = Sizzle.support = {};
-
- /**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
- isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
- };
-
- /**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
- setDocument = Sizzle.setDocument = function( node ) {
- var hasCompare, parent,
- doc = node ? node.ownerDocument || node : preferredDoc;
-
- // Return early if doc is invalid or already selected
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
- return document;
- }
-
- // Update global variables
- document = doc;
- docElem = document.documentElement;
- documentIsHTML = !isXML( document );
-
- // Support: IE 9-11, Edge
- // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
- if ( (parent = document.defaultView) && parent.top !== parent ) {
- // Support: IE 11
- if ( parent.addEventListener ) {
- parent.addEventListener( "unload", unloadHandler, false );
-
- // Support: IE 9 - 10 only
- } else if ( parent.attachEvent ) {
- parent.attachEvent( "onunload", unloadHandler );
- }
- }
-
- /* Attributes
- ---------------------------------------------------------------------- */
-
- // Support: IE<8
- // Verify that getAttribute really returns attributes and not properties
- // (excepting IE8 booleans)
- support.attributes = assert(function( div ) {
- div.className = "i";
- return !div.getAttribute("className");
- });
-
- /* getElement(s)By*
- ---------------------------------------------------------------------- */
-
- // Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function( div ) {
- div.appendChild( document.createComment("") );
- return !div.getElementsByTagName("*").length;
- });
-
- // Support: IE<9
- support.getElementsByClassName = rnative.test( document.getElementsByClassName );
-
- // Support: IE<10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programatically-set names,
- // so use a roundabout getElementsByName test
- support.getById = assert(function( div ) {
- docElem.appendChild( div ).id = expando;
- return !document.getElementsByName || !document.getElementsByName( expando ).length;
- });
-
- // ID find and filter
- if ( support.getById ) {
- Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
- var m = context.getElementById( id );
- return m ? [ m ] : [];
- }
- };
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- return elem.getAttribute("id") === attrId;
- };
- };
- } else {
- // Support: IE6/7
- // getElementById is not reliable as a find shortcut
- delete Expr.find["ID"];
-
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== "undefined" &&
- elem.getAttributeNode("id");
- return node && node.value === attrId;
- };
- };
- }
-
- // Tag
- Expr.find["TAG"] = support.getElementsByTagName ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== "undefined" ) {
- return context.getElementsByTagName( tag );
-
- // DocumentFragment nodes don't have gEBTN
- } else if ( support.qsa ) {
- return context.querySelectorAll( tag );
- }
- } :
-
- function( tag, context ) {
- var elem,
- tmp = [],
- i = 0,
- // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
- results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- while ( (elem = results[i++]) ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- };
-
- // Class
- Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
- if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
- return context.getElementsByClassName( className );
- }
- };
-
- /* QSA/matchesSelector
- ---------------------------------------------------------------------- */
-
- // QSA and matchesSelector support
-
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- rbuggyMatches = [];
-
- // qSa(:focus) reports false when true (Chrome 21)
- // We allow this because of a bug in IE8/9 that throws an error
- // whenever `document.activeElement` is accessed on an iframe
- // So, we allow :focus to pass through QSA all the time to avoid the IE error
- // See http://bugs.jquery.com/ticket/13378
- rbuggyQSA = [];
-
- if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explicitly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
- "<select id='" + expando + "-\r\\' msallowcapture=''>" +
- "<option selected=''></option></select>";
-
- // Support: IE8, Opera 11-12.16
- // Nothing should be selected when empty strings follow ^= or $= or *=
- // The test attribute must be unknown in Opera but "safe" for WinRT
- // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if ( div.querySelectorAll("[msallowcapture^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
- }
-
- // Support: IE8
- // Boolean attributes and "value" are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
- }
-
- // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
- if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
- rbuggyQSA.push("~=");
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
-
- // Support: Safari 8+, iOS 8+
- // https://bugs.webkit.org/show_bug.cgi?id=136851
- // In-page `selector#id sibing-combinator selector` fails
- if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
- rbuggyQSA.push(".#.+[+~]");
- }
- });
-
- assert(function( div ) {
- // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during .innerHTML assignment
- var input = document.createElement("input");
- input.setAttribute( "type", "hidden" );
- div.appendChild( input ).setAttribute( "name", "D" );
-
- // Support: IE8
- // Enforce case-sensitivity of name attribute
- if ( div.querySelectorAll("[name=d]").length ) {
- rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push( ":enabled", ":disabled" );
- }
-
- // Opera 10-11 does not throw on post-comma invalid pseudos
- div.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
- }
-
- if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
- docElem.webkitMatchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector) )) ) {
-
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- support.disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( div, "[s!='']:x" );
- rbuggyMatches.push( "!=", pseudos );
- });
- }
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
- /* Contains
- ---------------------------------------------------------------------- */
- hasCompare = rnative.test( docElem.compareDocumentPosition );
-
- // Element contains another
- // Purposefully self-exclusive
- // As in, an element does not contain itself
- contains = hasCompare || rnative.test( docElem.contains ) ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && (
- adown.contains ?
- adown.contains( bup ) :
- a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
- ));
- } :
- function( a, b ) {
- if ( b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- }
- return false;
- };
-
- /* Sorting
- ---------------------------------------------------------------------- */
-
- // Document order sorting
- sortOrder = hasCompare ?
- function( a, b ) {
-
- // Flag for duplicate removal
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- // Sort on method existence if only one input has compareDocumentPosition
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
- if ( compare ) {
- return compare;
- }
-
- // Calculate position if both inputs belong to the same document
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
- a.compareDocumentPosition( b ) :
-
- // Otherwise we know they are disconnected
- 1;
-
- // Disconnected nodes
- if ( compare & 1 ||
- (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
- // Choose the first element that is related to our preferred document
- if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
- return -1;
- }
- if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
- return 1;
- }
-
- // Maintain original order
- return sortInput ?
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
- 0;
- }
-
- return compare & 4 ? -1 : 1;
- } :
- function( a, b ) {
- // Exit early if the nodes are identical
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- var cur,
- i = 0,
- aup = a.parentNode,
- bup = b.parentNode,
- ap = [ a ],
- bp = [ b ];
-
- // Parentless nodes are either documents or disconnected
- if ( !aup || !bup ) {
- return a === document ? -1 :
- b === document ? 1 :
- aup ? -1 :
- bup ? 1 :
- sortInput ?
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
- 0;
-
- // If the nodes are siblings, we can do a quick check
- } else if ( aup === bup ) {
- return siblingCheck( a, b );
- }
-
- // Otherwise we need full lists of their ancestors for comparison
- cur = a;
- while ( (cur = cur.parentNode) ) {
- ap.unshift( cur );
- }
- cur = b;
- while ( (cur = cur.parentNode) ) {
- bp.unshift( cur );
- }
-
- // Walk down the tree looking for a discrepancy
- while ( ap[i] === bp[i] ) {
- i++;
- }
-
- return i ?
- // Do a sibling check if the nodes have a common ancestor
- siblingCheck( ap[i], bp[i] ) :
-
- // Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 :
- bp[i] === preferredDoc ? 1 :
- 0;
- };
-
- return document;
- };
-
- Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
- };
-
- Sizzle.matchesSelector = function( elem, expr ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- if ( support.matchesSelector && documentIsHTML &&
- !compilerCache[ expr + " " ] &&
- ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
-
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || support.disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch (e) {}
- }
-
- return Sizzle( expr, document, null, [ elem ] ).length > 0;
- };
-
- Sizzle.contains = function( context, elem ) {
- // Set document vars if needed
- if ( ( context.ownerDocument || context ) !== document ) {
- setDocument( context );
- }
- return contains( context, elem );
- };
-
- Sizzle.attr = function( elem, name ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- var fn = Expr.attrHandle[ name.toLowerCase() ],
- // Don't get fooled by Object.prototype properties (jQuery #13807)
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
- fn( elem, name, !documentIsHTML ) :
- undefined;
-
- return val !== undefined ?
- val :
- support.attributes || !documentIsHTML ?
- elem.getAttribute( name ) :
- (val = elem.getAttributeNode(name)) && val.specified ?
- val.value :
- null;
- };
-
- Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
- };
-
- /**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
- Sizzle.uniqueSort = function( results ) {
- var elem,
- duplicates = [],
- j = 0,
- i = 0;
-
- // Unless we *know* we can detect duplicates, assume their presence
- hasDuplicate = !support.detectDuplicates;
- sortInput = !support.sortStable && results.slice( 0 );
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
- if ( elem === results[ i ] ) {
- j = duplicates.push( i );
- }
- }
- while ( j-- ) {
- results.splice( duplicates[ j ], 1 );
- }
- }
-
- // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
-
- return results;
- };
-
- /**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
- getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( !nodeType ) {
- // If no nodeType, this is expected to be an array
- while ( (node = elem[i++]) ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (jQuery #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
-
- return ret;
- };
-
- Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- attrHandle: {},
-
- find: {},
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( runescape, funescape );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1].slice( 0, 3 ) === "nth" ) {
- // nth-* requires argument
- if ( !match[3] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
- match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[3] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var excess,
- unquoted = !match[6] && match[2];
-
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- // Accept quoted arguments as-is
- if ( match[3] ) {
- match[2] = match[4] || match[5] || "";
-
- // Strip excess characters from unquoted arguments
- } else if ( unquoted && rpseudo.test( unquoted ) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- match[0] = match[0].slice( 0, excess );
- match[2] = unquoted.slice( 0, excess );
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
-
- "TAG": function( nodeNameSelector ) {
- var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
- return nodeNameSelector === "*" ?
- function() { return true; } :
- function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ className + " " ];
-
- return pattern ||
- (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
- classCache( className, function( elem ) {
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
- });
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check && result.indexOf( check ) === 0 :
- operator === "*=" ? check && result.indexOf( check ) > -1 :
- operator === "$=" ? check && result.slice( -check.length ) === check :
- operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
- operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, what, argument, first, last ) {
- var simple = type.slice( 0, 3 ) !== "nth",
- forward = type.slice( -4 ) !== "last",
- ofType = what === "of-type";
-
- return first === 1 && last === 0 ?
-
- // Shortcut for :nth-*(n)
- function( elem ) {
- return !!elem.parentNode;
- } :
-
- function( elem, context, xml ) {
- var cache, uniqueCache, outerCache, node, nodeIndex, start,
- dir = simple !== forward ? "nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType,
- diff = false;
-
- if ( parent ) {
-
- // :(first|last|only)-(child|of-type)
- if ( simple ) {
- while ( dir ) {
- node = elem;
- while ( (node = node[ dir ]) ) {
- if ( ofType ?
- node.nodeName.toLowerCase() === name :
- node.nodeType === 1 ) {
-
- return false;
- }
- }
- // Reverse direction for :only-* (if we haven't yet done so)
- start = dir = type === "only" && !start && "nextSibling";
- }
- return true;
- }
-
- start = [ forward ? parent.firstChild : parent.lastChild ];
-
- // non-xml :nth-child(...) stores cache data on `parent`
- if ( forward && useCache ) {
-
- // Seek `elem` from a previously-cached index
-
- // ...in a gzip-friendly way
- node = parent;
- outerCache = node[ expando ] || (node[ expando ] = {});
-
- // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[ node.uniqueID ] ||
- (outerCache[ node.uniqueID ] = {});
-
- cache = uniqueCache[ type ] || [];
- nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
- diff = nodeIndex && cache[ 2 ];
- node = nodeIndex && parent.childNodes[ nodeIndex ];
-
- while ( (node = ++nodeIndex && node && node[ dir ] ||
-
- // Fallback to seeking `elem` from the start
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- // When found, cache indexes on `parent` and break
- if ( node.nodeType === 1 && ++diff && node === elem ) {
- uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
- break;
- }
- }
-
- } else {
- // Use previously-cached element index if available
- if ( useCache ) {
- // ...in a gzip-friendly way
- node = elem;
- outerCache = node[ expando ] || (node[ expando ] = {});
-
- // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[ node.uniqueID ] ||
- (outerCache[ node.uniqueID ] = {});
-
- cache = uniqueCache[ type ] || [];
- nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
- diff = nodeIndex;
- }
-
- // xml :nth-child(...)
- // or :nth-last-child(...) or :nth(-last)?-of-type(...)
- if ( diff === false ) {
- // Use the same loop as above to seek `elem` from the start
- while ( (node = ++nodeIndex && node && node[ dir ] ||
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- if ( ( ofType ?
- node.nodeName.toLowerCase() === name :
- node.nodeType === 1 ) &&
- ++diff ) {
-
- // Cache the index of each encountered element
- if ( useCache ) {
- outerCache = node[ expando ] || (node[ expando ] = {});
-
- // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[ node.uniqueID ] ||
- (outerCache[ node.uniqueID ] = {});
-
- uniqueCache[ type ] = [ dirruns, diff ];
- }
-
- if ( node === elem ) {
- break;
- }
- }
- }
- }
- }
-
- // Incorporate the offset, then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- // Potentially complex pseudos
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- // Don't keep the element (issue #299)
- input[0] = null;
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- text = text.replace( runescape, funescape );
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by "-".
- // The matching of C against the element's language value is performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // http://www.w3.org/TR/selectors/#lang-pseudo
- "lang": markFunction( function( lang ) {
- // lang value must be a valid identifier
- if ( !ridentifier.test(lang || "") ) {
- Sizzle.error( "unsupported lang: " + lang );
- }
- lang = lang.replace( runescape, funescape ).toLowerCase();
- return function( elem ) {
- var elemLang;
- do {
- if ( (elemLang = documentIsHTML ?
- elem.lang :
- elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
- elemLang = elemLang.toLowerCase();
- return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
- }
- } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
- return false;
- };
- }),
-
- // Miscellaneous
- "target": function( elem ) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice( 1 ) === elem.id;
- },
-
- "root": function( elem ) {
- return elem === docElem;
- },
-
- "focus": function( elem ) {
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
- },
-
- // Boolean properties
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- // Contents
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not appear as children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- if ( elem.nodeType < 6 ) {
- return false;
- }
- }
- return true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- // Element/input types
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "text": function( elem ) {
- var attr;
- return elem.nodeName.toLowerCase() === "input" &&
- elem.type === "text" &&
-
- // Support: IE<8
- // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
- },
-
- // Position-in-collection
- "first": createPositionalPseudo(function() {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length ) {
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 0;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 1;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
- };
-
- Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
- // Add button/input type pseudos
- for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
- Expr.pseudos[ i ] = createInputPseudo( i );
- }
- for ( i in { submit: true, reset: true } ) {
- Expr.pseudos[ i ] = createButtonPseudo( i );
- }
-
- // Easy API for creating new setFilters
- function setFilters() {}
- setFilters.prototype = Expr.filters = Expr.pseudos;
- Expr.setFilters = new setFilters();
-
- tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, preFilters,
- cached = tokenCache[ selector + " " ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- // Don't consume trailing commas as valid
- soFar = soFar.slice( match[0].length ) || soFar;
- }
- groups.push( (tokens = []) );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- // Cast descendant combinators to space
- type: match[0].replace( rtrim, " " )
- });
- soFar = soFar.slice( matched.length );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- (match = preFilters[ type ]( match ))) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- type: type,
- matches: match
- });
- soFar = soFar.slice( matched.length );
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
- };
-
- function toSelector( tokens ) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for ( ; i < len; i++ ) {
- selector += tokens[i].value;
- }
- return selector;
- }
-
- function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- var oldCache, uniqueCache, outerCache,
- newCache = [ dirruns, doneName ];
-
- // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
- if ( xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- if ( matcher( elem, context, xml ) ) {
- return true;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- outerCache = elem[ expando ] || (elem[ expando ] = {});
-
- // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
-
- if ( (oldCache = uniqueCache[ dir ]) &&
- oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
- // Assign to newCache so results back-propagate to previous elements
- return (newCache[ 2 ] = oldCache[ 2 ]);
- } else {
- // Reuse newcache so results back-propagate to previous elements
- uniqueCache[ dir ] = newCache;
-
- // A match means we're done; a fail means we have to keep checking
- if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
- return true;
- }
- }
- }
- }
- }
- };
- }
-
- function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
- }
-
- function multipleContexts( selector, contexts, results ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results );
- }
- return results;
- }
-
- function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
- }
-
- function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- var temp, i, elem,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- temp = condense( matcherOut, postMap );
- postFilter( temp, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = temp.length;
- while ( i-- ) {
- if ( (elem = temp[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
- }
- }
- }
-
- if ( seed ) {
- if ( postFinder || preFilter ) {
- if ( postFinder ) {
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- // Restore matcherIn since elem is not yet a final match
- temp.push( (matcherIn[i] = elem) );
- }
- }
- postFinder( null, (matcherOut = []), temp, xml );
- }
-
- // Move matched elements from seed to results to keep them synchronized
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) &&
- (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
-
- seed[temp] = !(results[temp] = elem);
- }
- }
- }
-
- // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
- }
-
- function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- // Avoid hanging onto element (issue #299)
- checkContext = null;
- return ret;
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
- } else {
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && toSelector(
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
- ).replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
- j < len && toSelector( tokens )
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
- }
-
- function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, outermost ) {
- var elem, j, matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
- // We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
- // Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
- len = elems.length;
-
- if ( outermost ) {
- outermostContext = context === document || context || outermost;
- }
-
- // Add elements passing elementMatchers directly to results
- // Support: IE<9, Safari
- // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- j = 0;
- if ( !context && elem.ownerDocument !== document ) {
- setDocument( elem );
- xml = !documentIsHTML;
- }
- while ( (matcher = elementMatchers[j++]) ) {
- if ( matcher( elem, context || document, xml) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // `i` is now the count of elements visited above, and adding it to `matchedCount`
- // makes the latter nonnegative.
- matchedCount += i;
-
- // Apply set filters to unmatched elements
- // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
- // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
- // no element matchers and no seed.
- // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
- // case, which will result in a "00" `matchedCount` that differs from `i` but is also
- // numerically zero.
- if ( bySet && i !== matchedCount ) {
- j = 0;
- while ( (matcher = setMatchers[j++]) ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
- }
-
- compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ selector + " " ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used to check each element
- if ( !match ) {
- match = tokenize( selector );
- }
- i = match.length;
- while ( i-- ) {
- cached = matcherFromTokens( match[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
- // Save selector and tokenization
- cached.selector = selector;
- }
- return cached;
- };
-
- /**
- * A low-level selection function that works with Sizzle's compiled
- * selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- * selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
- select = Sizzle.select = function( selector, context, results, seed ) {
- var i, tokens, token, type, find,
- compiled = typeof selector === "function" && selector,
- match = !seed && tokenize( (selector = compiled.selector || selector) );
-
- results = results || [];
-
- // Try to minimize operations if there is only one selector in the list and no seed
- // (the latter of which guarantees us context)
- if ( match.length === 1 ) {
-
- // Reduce context if the leading compound selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- support.getById && context.nodeType === 9 && documentIsHTML &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
- if ( !context ) {
- return results;
-
- // Precompiled matchers will still verify ancestry, so step up a level
- } else if ( compiled ) {
- context = context.parentNode;
- }
-
- selector = selector.slice( tokens.shift().value.length );
- }
-
- // Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
- while ( i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( runescape, funescape ),
- rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
- )) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && toSelector( tokens );
- if ( !selector ) {
- push.apply( results, seed );
- return results;
- }
-
- break;
- }
- }
- }
- }
-
- // Compile and execute a filtering function if one is not provided
- // Provide `match` to avoid retokenization if we modified the selector above
- ( compiled || compile( selector, match ) )(
- seed,
- context,
- !documentIsHTML,
- results,
- !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
- );
- return results;
- };
-
- // One-time assignments
-
- // Sort stability
- support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
- // Support: Chrome 14-35+
- // Always assume duplicates if they aren't passed to the comparison function
- support.detectDuplicates = !!hasDuplicate;
-
- // Initialize against the default document
- setDocument();
-
- // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
- // Detached nodes confoundingly follow *each other*
- support.sortDetached = assert(function( div1 ) {
- // Should return 1, but returns 4 (following)
- return div1.compareDocumentPosition( document.createElement("div") ) & 1;
- });
-
- // Support: IE<8
- // Prevent attribute/property "interpolation"
- // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
- if ( !assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild.getAttribute("href") === "#" ;
- }) ) {
- addHandle( "type|href|height|width", function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
- }
- });
- }
-
- // Support: IE<9
- // Use defaultValue in place of getAttribute("value")
- if ( !support.attributes || !assert(function( div ) {
- div.innerHTML = "<input/>";
- div.firstChild.setAttribute( "value", "" );
- return div.firstChild.getAttribute( "value" ) === "";
- }) ) {
- addHandle( "value", function( elem, name, isXML ) {
- if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
- return elem.defaultValue;
- }
- });
- }
-
- // Support: IE<9
- // Use getAttributeNode to fetch booleans when getAttribute lies
- if ( !assert(function( div ) {
- return div.getAttribute("disabled") == null;
- }) ) {
- addHandle( booleans, function( elem, name, isXML ) {
- var val;
- if ( !isXML ) {
- return elem[ name ] === true ? name.toLowerCase() :
- (val = elem.getAttributeNode( name )) && val.specified ?
- val.value :
- null;
- }
- });
- }
-
- return Sizzle;
-
- })( window );
-
-
-
- jQuery.find = Sizzle;
- jQuery.expr = Sizzle.selectors;
- jQuery.expr[ ":" ] = jQuery.expr.pseudos;
- jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
- jQuery.text = Sizzle.getText;
- jQuery.isXMLDoc = Sizzle.isXML;
- jQuery.contains = Sizzle.contains;
-
-
-
- var dir = function( elem, dir, until ) {
- var matched = [],
- truncate = until !== undefined;
-
- while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
- if ( elem.nodeType === 1 ) {
- if ( truncate && jQuery( elem ).is( until ) ) {
- break;
- }
- matched.push( elem );
- }
- }
- return matched;
- };
-
-
- var siblings = function( n, elem ) {
- var matched = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- matched.push( n );
- }
- }
-
- return matched;
- };
-
-
- var rneedsContext = jQuery.expr.match.needsContext;
-
- var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
-
-
-
- var risSimple = /^.[^:#\[\.,]*$/;
-
- // Implement the identical functionality for filter and not
- function winnow( elements, qualifier, not ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep( elements, function( elem, i ) {
- /* jshint -W018 */
- return !!qualifier.call( elem, i, elem ) !== not;
- } );
-
- }
-
- if ( qualifier.nodeType ) {
- return jQuery.grep( elements, function( elem ) {
- return ( elem === qualifier ) !== not;
- } );
-
- }
-
- if ( typeof qualifier === "string" ) {
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
-
- qualifier = jQuery.filter( qualifier, elements );
- }
-
- return jQuery.grep( elements, function( elem ) {
- return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
- } );
- }
-
- jQuery.filter = function( expr, elems, not ) {
- var elem = elems[ 0 ];
-
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 && elem.nodeType === 1 ?
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
- return elem.nodeType === 1;
- } ) );
- };
-
- jQuery.fn.extend( {
- find: function( selector ) {
- var i,
- len = this.length,
- ret = [],
- self = this;
-
- if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector ).filter( function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( self[ i ], this ) ) {
- return true;
- }
- }
- } ) );
- }
-
- for ( i = 0; i < len; i++ ) {
- jQuery.find( selector, self[ i ], ret );
- }
-
- // Needed because $( selector, context ) becomes $( context ).find( selector )
- ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
- ret.selector = this.selector ? this.selector + " " + selector : selector;
- return ret;
- },
- filter: function( selector ) {
- return this.pushStack( winnow( this, selector || [], false ) );
- },
- not: function( selector ) {
- return this.pushStack( winnow( this, selector || [], true ) );
- },
- is: function( selector ) {
- return !!winnow(
- this,
-
- // If this is a positional/relative selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- typeof selector === "string" && rneedsContext.test( selector ) ?
- jQuery( selector ) :
- selector || [],
- false
- ).length;
- }
- } );
-
-
- // Initialize a jQuery object
-
-
- // A central reference to the root jQuery(document)
- var rootjQuery,
-
- // A simple way to check for HTML strings
- // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
- // Strict HTML recognition (#11290: must start with <)
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
- init = jQuery.fn.init = function( selector, context, root ) {
- var match, elem;
-
- // HANDLE: $(""), $(null), $(undefined), $(false)
- if ( !selector ) {
- return this;
- }
-
- // Method init() accepts an alternate rootjQuery
- // so migrate can support jQuery.sub (gh-2101)
- root = root || rootjQuery;
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- if ( selector[ 0 ] === "<" &&
- selector[ selector.length - 1 ] === ">" &&
- selector.length >= 3 ) {
-
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = rquickExpr.exec( selector );
- }
-
- // Match html or make sure no context is specified for #id
- if ( match && ( match[ 1 ] || !context ) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[ 1 ] ) {
- context = context instanceof jQuery ? context[ 0 ] : context;
-
- // Option to run scripts is true for back-compat
- // Intentionally let the error be thrown if parseHTML is not present
- jQuery.merge( this, jQuery.parseHTML(
- match[ 1 ],
- context && context.nodeType ? context.ownerDocument || context : document,
- true
- ) );
-
- // HANDLE: $(html, props)
- if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
- for ( match in context ) {
-
- // Properties of context are called as methods if possible
- if ( jQuery.isFunction( this[ match ] ) ) {
- this[ match ]( context[ match ] );
-
- // ...and otherwise set as attributes
- } else {
- this.attr( match, context[ match ] );
- }
- }
- }
-
- return this;
-
- // HANDLE: $(#id)
- } else {
- elem = document.getElementById( match[ 2 ] );
-
- // Support: Blackberry 4.6
- // gEBID returns nodes no longer in the document (#6963)
- if ( elem && elem.parentNode ) {
-
- // Inject the element directly into the jQuery object
- this.length = 1;
- this[ 0 ] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || root ).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find( selector );
- }
-
- // HANDLE: $(DOMElement)
- } else if ( selector.nodeType ) {
- this.context = this[ 0 ] = selector;
- this.length = 1;
- return this;
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return root.ready !== undefined ?
- root.ready( selector ) :
-
- // Execute immediately if ready is not present
- selector( jQuery );
- }
-
- if ( selector.selector !== undefined ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- };
-
- // Give the init function the jQuery prototype for later instantiation
- init.prototype = jQuery.fn;
-
- // Initialize central reference
- rootjQuery = jQuery( document );
-
-
- var rparentsprev = /^(?:parents|prev(?:Until|All))/,
-
- // Methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
- jQuery.fn.extend( {
- has: function( target ) {
- var targets = jQuery( target, this ),
- l = targets.length;
-
- return this.filter( function() {
- var i = 0;
- for ( ; i < l; i++ ) {
- if ( jQuery.contains( this, targets[ i ] ) ) {
- return true;
- }
- }
- } );
- },
-
- closest: function( selectors, context ) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
- jQuery( selectors, context || this.context ) :
- 0;
-
- for ( ; i < l; i++ ) {
- for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
-
- // Always skip document fragments
- if ( cur.nodeType < 11 && ( pos ?
- pos.index( cur ) > -1 :
-
- // Don't pass non-elements to Sizzle
- cur.nodeType === 1 &&
- jQuery.find.matchesSelector( cur, selectors ) ) ) {
-
- matched.push( cur );
- break;
- }
- }
- }
-
- return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
- },
-
- // Determine the position of an element within the set
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
- }
-
- // Index in selector
- if ( typeof elem === "string" ) {
- return indexOf.call( jQuery( elem ), this[ 0 ] );
- }
-
- // Locate the position of the desired element
- return indexOf.call( this,
-
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[ 0 ] : elem
- );
- },
-
- add: function( selector, context ) {
- return this.pushStack(
- jQuery.uniqueSort(
- jQuery.merge( this.get(), jQuery( selector, context ) )
- )
- );
- },
-
- addBack: function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter( selector )
- );
- }
- } );
-
- function sibling( cur, dir ) {
- while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
- return cur;
- }
-
- jQuery.each( {
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return sibling( elem, "nextSibling" );
- },
- prev: function( elem ) {
- return sibling( elem, "previousSibling" );
- },
- nextAll: function( elem ) {
- return dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return siblings( ( elem.parentNode || {} ).firstChild, elem );
- },
- children: function( elem ) {
- return siblings( elem.firstChild );
- },
- contents: function( elem ) {
- return elem.contentDocument || jQuery.merge( [], elem.childNodes );
- }
- }, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var matched = jQuery.map( this, fn, until );
-
- if ( name.slice( -5 ) !== "Until" ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- matched = jQuery.filter( selector, matched );
- }
-
- if ( this.length > 1 ) {
-
- // Remove duplicates
- if ( !guaranteedUnique[ name ] ) {
- jQuery.uniqueSort( matched );
- }
-
- // Reverse order for parents* and prev-derivatives
- if ( rparentsprev.test( name ) ) {
- matched.reverse();
- }
- }
-
- return this.pushStack( matched );
- };
- } );
- var rnotwhite = ( /\S+/g );
-
-
-
- // Convert String-formatted options into Object-formatted ones
- function createOptions( options ) {
- var object = {};
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
- object[ flag ] = true;
- } );
- return object;
- }
-
- /*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change how
- * the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
- jQuery.Callbacks = function( options ) {
-
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ?
- createOptions( options ) :
- jQuery.extend( {}, options );
-
- var // Flag to know if list is currently firing
- firing,
-
- // Last fire value for non-forgettable lists
- memory,
-
- // Flag to know if list was already fired
- fired,
-
- // Flag to prevent firing
- locked,
-
- // Actual callback list
- list = [],
-
- // Queue of execution data for repeatable lists
- queue = [],
-
- // Index of currently firing callback (modified by add/remove as needed)
- firingIndex = -1,
-
- // Fire callbacks
- fire = function() {
-
- // Enforce single-firing
- locked = options.once;
-
- // Execute callbacks for all pending executions,
- // respecting firingIndex overrides and runtime changes
- fired = firing = true;
- for ( ; queue.length; firingIndex = -1 ) {
- memory = queue.shift();
- while ( ++firingIndex < list.length ) {
-
- // Run callback and check for early termination
- if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
- options.stopOnFalse ) {
-
- // Jump to end and forget the data so .add doesn't re-fire
- firingIndex = list.length;
- memory = false;
- }
- }
- }
-
- // Forget the data if we're done with it
- if ( !options.memory ) {
- memory = false;
- }
-
- firing = false;
-
- // Clean up if we're done firing for good
- if ( locked ) {
-
- // Keep an empty list if we have data for future add calls
- if ( memory ) {
- list = [];
-
- // Otherwise, this object is spent
- } else {
- list = "";
- }
- }
- },
-
- // Actual Callbacks object
- self = {
-
- // Add a callback or a collection of callbacks to the list
- add: function() {
- if ( list ) {
-
- // If we have memory from a past run, we should fire after adding
- if ( memory && !firing ) {
- firingIndex = list.length - 1;
- queue.push( memory );
- }
-
- ( function add( args ) {
- jQuery.each( args, function( _, arg ) {
- if ( jQuery.isFunction( arg ) ) {
- if ( !options.unique || !self.has( arg ) ) {
- list.push( arg );
- }
- } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
-
- // Inspect recursively
- add( arg );
- }
- } );
- } )( arguments );
-
- if ( memory && !firing ) {
- fire();
- }
- }
- return this;
- },
-
- // Remove a callback from the list
- remove: function() {
- jQuery.each( arguments, function( _, arg ) {
- var index;
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
-
- // Handle firing indexes
- if ( index <= firingIndex ) {
- firingIndex--;
- }
- }
- } );
- return this;
- },
-
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list has callbacks attached.
- has: function( fn ) {
- return fn ?
- jQuery.inArray( fn, list ) > -1 :
- list.length > 0;
- },
-
- // Remove all callbacks from the list
- empty: function() {
- if ( list ) {
- list = [];
- }
- return this;
- },
-
- // Disable .fire and .add
- // Abort any current/pending executions
- // Clear all callbacks and values
- disable: function() {
- locked = queue = [];
- list = memory = "";
- return this;
- },
- disabled: function() {
- return !list;
- },
-
- // Disable .fire
- // Also disable .add unless we have memory (since it would have no effect)
- // Abort any pending executions
- lock: function() {
- locked = queue = [];
- if ( !memory ) {
- list = memory = "";
- }
- return this;
- },
- locked: function() {
- return !!locked;
- },
-
- // Call all callbacks with the given context and arguments
- fireWith: function( context, args ) {
- if ( !locked ) {
- args = args || [];
- args = [ context, args.slice ? args.slice() : args ];
- queue.push( args );
- if ( !firing ) {
- fire();
- }
- }
- return this;
- },
-
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
-
- // To know if the callbacks have already been called at least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
- };
-
-
- jQuery.extend( {
-
- Deferred: function( func ) {
- var tuples = [
-
- // action, add listener, listener list, final state
- [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
- [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
- [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
- ],
- state = "pending",
- promise = {
- state: function() {
- return state;
- },
- always: function() {
- deferred.done( arguments ).fail( arguments );
- return this;
- },
- then: function( /* fnDone, fnFail, fnProgress */ ) {
- var fns = arguments;
- return jQuery.Deferred( function( newDefer ) {
- jQuery.each( tuples, function( i, tuple ) {
- var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
-
- // deferred[ done | fail | progress ] for forwarding actions to newDefer
- deferred[ tuple[ 1 ] ]( function() {
- var returned = fn && fn.apply( this, arguments );
- if ( returned && jQuery.isFunction( returned.promise ) ) {
- returned.promise()
- .progress( newDefer.notify )
- .done( newDefer.resolve )
- .fail( newDefer.reject );
- } else {
- newDefer[ tuple[ 0 ] + "With" ](
- this === promise ? newDefer.promise() : this,
- fn ? [ returned ] : arguments
- );
- }
- } );
- } );
- fns = null;
- } ).promise();
- },
-
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function( obj ) {
- return obj != null ? jQuery.extend( obj, promise ) : promise;
- }
- },
- deferred = {};
-
- // Keep pipe for back-compat
- promise.pipe = promise.then;
-
- // Add list-specific methods
- jQuery.each( tuples, function( i, tuple ) {
- var list = tuple[ 2 ],
- stateString = tuple[ 3 ];
-
- // promise[ done | fail | progress ] = list.add
- promise[ tuple[ 1 ] ] = list.add;
-
- // Handle state
- if ( stateString ) {
- list.add( function() {
-
- // state = [ resolved | rejected ]
- state = stateString;
-
- // [ reject_list | resolve_list ].disable; progress_list.lock
- }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
- }
-
- // deferred[ resolve | reject | notify ]
- deferred[ tuple[ 0 ] ] = function() {
- deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
- return this;
- };
- deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
- } );
-
- // Make the deferred a promise
- promise.promise( deferred );
-
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
-
- // All done!
- return deferred;
- },
-
- // Deferred helper
- when: function( subordinate /* , ..., subordinateN */ ) {
- var i = 0,
- resolveValues = slice.call( arguments ),
- length = resolveValues.length,
-
- // the count of uncompleted subordinates
- remaining = length !== 1 ||
- ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
- // the master Deferred.
- // If resolveValues consist of only a single Deferred, just use that.
- deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
-
- // Update function for both resolve and progress values
- updateFunc = function( i, contexts, values ) {
- return function( value ) {
- contexts[ i ] = this;
- values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
- if ( values === progressValues ) {
- deferred.notifyWith( contexts, values );
- } else if ( !( --remaining ) ) {
- deferred.resolveWith( contexts, values );
- }
- };
- },
-
- progressValues, progressContexts, resolveContexts;
-
- // Add listeners to Deferred subordinates; treat others as resolved
- if ( length > 1 ) {
- progressValues = new Array( length );
- progressContexts = new Array( length );
- resolveContexts = new Array( length );
- for ( ; i < length; i++ ) {
- if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
- resolveValues[ i ].promise()
- .progress( updateFunc( i, progressContexts, progressValues ) )
- .done( updateFunc( i, resolveContexts, resolveValues ) )
- .fail( deferred.reject );
- } else {
- --remaining;
- }
- }
- }
-
- // If we're not waiting on anything, resolve the master
- if ( !remaining ) {
- deferred.resolveWith( resolveContexts, resolveValues );
- }
-
- return deferred.promise();
- }
- } );
-
-
- // The deferred used on DOM ready
- var readyList;
-
- jQuery.fn.ready = function( fn ) {
-
- // Add the callback
- jQuery.ready.promise().done( fn );
-
- return this;
- };
-
- jQuery.extend( {
-
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Hold (or release) the ready event
- holdReady: function( hold ) {
- if ( hold ) {
- jQuery.readyWait++;
- } else {
- jQuery.ready( true );
- }
- },
-
- // Handle when the DOM is ready
- ready: function( wait ) {
-
- // Abort if there are pending holds or we're already ready
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
- return;
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- readyList.resolveWith( document, [ jQuery ] );
-
- // Trigger any bound ready events
- if ( jQuery.fn.triggerHandler ) {
- jQuery( document ).triggerHandler( "ready" );
- jQuery( document ).off( "ready" );
- }
- }
- } );
-
- /**
- * The ready event handler and self cleanup method
- */
- function completed() {
- document.removeEventListener( "DOMContentLoaded", completed );
- window.removeEventListener( "load", completed );
- jQuery.ready();
- }
-
- jQuery.ready.promise = function( obj ) {
- if ( !readyList ) {
-
- readyList = jQuery.Deferred();
-
- // Catch cases where $(document).ready() is called
- // after the browser event has already occurred.
- // Support: IE9-10 only
- // Older IE sometimes signals "interactive" too soon
- if ( document.readyState === "complete" ||
- ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
-
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- window.setTimeout( jQuery.ready );
-
- } else {
-
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", completed );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed );
- }
- }
- return readyList.promise( obj );
- };
-
- // Kick off the DOM ready check even if the user does not
- jQuery.ready.promise();
-
-
-
-
- // Multifunctional method to get and set values of a collection
- // The value/s can optionally be executed if it's a function
- var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
- var i = 0,
- len = elems.length,
- bulk = key == null;
-
- // Sets many values
- if ( jQuery.type( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- access( elems, fn, i, key[ i ], true, emptyGet, raw );
- }
-
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
-
- if ( !jQuery.isFunction( value ) ) {
- raw = true;
- }
-
- if ( bulk ) {
-
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
-
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, key, value ) {
- return bulk.call( jQuery( elem ), value );
- };
- }
- }
-
- if ( fn ) {
- for ( ; i < len; i++ ) {
- fn(
- elems[ i ], key, raw ?
- value :
- value.call( elems[ i ], i, fn( elems[ i ], key ) )
- );
- }
- }
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- len ? fn( elems[ 0 ], key ) : emptyGet;
- };
- var acceptData = function( owner ) {
-
- // Accepts only:
- // - Node
- // - Node.ELEMENT_NODE
- // - Node.DOCUMENT_NODE
- // - Object
- // - Any
- /* jshint -W018 */
- return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
- };
-
-
-
-
- function Data() {
- this.expando = jQuery.expando + Data.uid++;
- }
-
- Data.uid = 1;
-
- Data.prototype = {
-
- register: function( owner, initial ) {
- var value = initial || {};
-
- // If it is a node unlikely to be stringify-ed or looped over
- // use plain assignment
- if ( owner.nodeType ) {
- owner[ this.expando ] = value;
-
- // Otherwise secure it in a non-enumerable, non-writable property
- // configurability must be true to allow the property to be
- // deleted with the delete operator
- } else {
- Object.defineProperty( owner, this.expando, {
- value: value,
- writable: true,
- configurable: true
- } );
- }
- return owner[ this.expando ];
- },
- cache: function( owner ) {
-
- // We can accept data for non-element nodes in modern browsers,
- // but we should not, see #8335.
- // Always return an empty object.
- if ( !acceptData( owner ) ) {
- return {};
- }
-
- // Check if the owner object already has a cache
- var value = owner[ this.expando ];
-
- // If not, create one
- if ( !value ) {
- value = {};
-
- // We can accept data for non-element nodes in modern browsers,
- // but we should not, see #8335.
- // Always return an empty object.
- if ( acceptData( owner ) ) {
-
- // If it is a node unlikely to be stringify-ed or looped over
- // use plain assignment
- if ( owner.nodeType ) {
- owner[ this.expando ] = value;
-
- // Otherwise secure it in a non-enumerable property
- // configurable must be true to allow the property to be
- // deleted when data is removed
- } else {
- Object.defineProperty( owner, this.expando, {
- value: value,
- configurable: true
- } );
- }
- }
- }
-
- return value;
- },
- set: function( owner, data, value ) {
- var prop,
- cache = this.cache( owner );
-
- // Handle: [ owner, key, value ] args
- if ( typeof data === "string" ) {
- cache[ data ] = value;
-
- // Handle: [ owner, { properties } ] args
- } else {
-
- // Copy the properties one-by-one to the cache object
- for ( prop in data ) {
- cache[ prop ] = data[ prop ];
- }
- }
- return cache;
- },
- get: function( owner, key ) {
- return key === undefined ?
- this.cache( owner ) :
- owner[ this.expando ] && owner[ this.expando ][ key ];
- },
- access: function( owner, key, value ) {
- var stored;
-
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if ( key === undefined ||
- ( ( key && typeof key === "string" ) && value === undefined ) ) {
-
- stored = this.get( owner, key );
-
- return stored !== undefined ?
- stored : this.get( owner, jQuery.camelCase( key ) );
- }
-
- // When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set( owner, key, value );
-
- // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function( owner, key ) {
- var i, name, camel,
- cache = owner[ this.expando ];
-
- if ( cache === undefined ) {
- return;
- }
-
- if ( key === undefined ) {
- this.register( owner );
-
- } else {
-
- // Support array or space separated string of keys
- if ( jQuery.isArray( key ) ) {
-
- // If "name" is an array of keys...
- // When data is initially created, via ("key", "val") signature,
- // keys will be converted to camelCase.
- // Since there is no way to tell _how_ a key was added, remove
- // both plain key and camelCase key. #12786
- // This will only penalize the array argument path.
- name = key.concat( key.map( jQuery.camelCase ) );
- } else {
- camel = jQuery.camelCase( key );
-
- // Try the string as a key before any manipulation
- if ( key in cache ) {
- name = [ key, camel ];
- } else {
-
- // If a key with the spaces exists, use it.
- // Otherwise, create an array by matching non-whitespace
- name = camel;
- name = name in cache ?
- [ name ] : ( name.match( rnotwhite ) || [] );
- }
- }
-
- i = name.length;
-
- while ( i-- ) {
- delete cache[ name[ i ] ];
- }
- }
-
- // Remove the expando if there's no more data
- if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
-
- // Support: Chrome <= 35-45+
- // Webkit & Blink performance suffers when deleting properties
- // from DOM nodes, so set to undefined instead
- // https://code.google.com/p/chromium/issues/detail?id=378607
- if ( owner.nodeType ) {
- owner[ this.expando ] = undefined;
- } else {
- delete owner[ this.expando ];
- }
- }
- },
- hasData: function( owner ) {
- var cache = owner[ this.expando ];
- return cache !== undefined && !jQuery.isEmptyObject( cache );
- }
- };
- var dataPriv = new Data();
-
- var dataUser = new Data();
-
-
-
- // Implementation Summary
- //
- // 1. Enforce API surface and semantic compatibility with 1.9.x branch
- // 2. Improve the module's maintainability by reducing the storage
- // paths to a single mechanism.
- // 3. Use the same single mechanism to support "private" and "user" data.
- // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
- // 5. Avoid exposing implementation details on user objects (eg. expando properties)
- // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
-
- var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /[A-Z]/g;
-
- function dataAttr( elem, key, data ) {
- var name;
-
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
- name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
- data = elem.getAttribute( name );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
-
- // Only convert to a number if it doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
- } catch ( e ) {}
-
- // Make sure we set the data so it isn't changed later
- dataUser.set( elem, key, data );
- } else {
- data = undefined;
- }
- }
- return data;
- }
-
- jQuery.extend( {
- hasData: function( elem ) {
- return dataUser.hasData( elem ) || dataPriv.hasData( elem );
- },
-
- data: function( elem, name, data ) {
- return dataUser.access( elem, name, data );
- },
-
- removeData: function( elem, name ) {
- dataUser.remove( elem, name );
- },
-
- // TODO: Now that all calls to _data and _removeData have been replaced
- // with direct calls to dataPriv methods, these can be deprecated.
- _data: function( elem, name, data ) {
- return dataPriv.access( elem, name, data );
- },
-
- _removeData: function( elem, name ) {
- dataPriv.remove( elem, name );
- }
- } );
-
- jQuery.fn.extend( {
- data: function( key, value ) {
- var i, name, data,
- elem = this[ 0 ],
- attrs = elem && elem.attributes;
-
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = dataUser.get( elem );
-
- if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
- i = attrs.length;
- while ( i-- ) {
-
- // Support: IE11+
- // The attrs elements can be null (#14894)
- if ( attrs[ i ] ) {
- name = attrs[ i ].name;
- if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.slice( 5 ) );
- dataAttr( elem, name, data[ name ] );
- }
- }
- }
- dataPriv.set( elem, "hasDataAttrs", true );
- }
- }
-
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each( function() {
- dataUser.set( this, key );
- } );
- }
-
- return access( this, function( value ) {
- var data, camelKey;
-
- // The calling jQuery object (element matches) is not empty
- // (and therefore has an element appears at this[ 0 ]) and the
- // `value` parameter was not undefined. An empty jQuery object
- // will result in `undefined` for elem = this[ 0 ] which will
- // throw an exception if an attempt to read a data cache is made.
- if ( elem && value === undefined ) {
-
- // Attempt to get data from the cache
- // with the key as-is
- data = dataUser.get( elem, key ) ||
-
- // Try to find dashed key if it exists (gh-2779)
- // This is for 2.2.x only
- dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
-
- if ( data !== undefined ) {
- return data;
- }
-
- camelKey = jQuery.camelCase( key );
-
- // Attempt to get data from the cache
- // with the key camelized
- data = dataUser.get( elem, camelKey );
- if ( data !== undefined ) {
- return data;
- }
-
- // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr( elem, camelKey, undefined );
- if ( data !== undefined ) {
- return data;
- }
-
- // We tried really hard, but the data doesn't exist.
- return;
- }
-
- // Set the data...
- camelKey = jQuery.camelCase( key );
- this.each( function() {
-
- // First, attempt to store a copy or reference of any
- // data that might've been store with a camelCased key.
- var data = dataUser.get( this, camelKey );
-
- // For HTML5 data-* attribute interop, we have to
- // store property names with dashes in a camelCase form.
- // This might not apply to all properties...*
- dataUser.set( this, camelKey, value );
-
- // *... In the case of properties that might _actually_
- // have dashes, we need to also store a copy of that
- // unchanged property.
- if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
- dataUser.set( this, key, value );
- }
- } );
- }, null, value, arguments.length > 1, null, true );
- },
-
- removeData: function( key ) {
- return this.each( function() {
- dataUser.remove( this, key );
- } );
- }
- } );
-
-
- jQuery.extend( {
- queue: function( elem, type, data ) {
- var queue;
-
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- queue = dataPriv.get( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( data ) {
- if ( !queue || jQuery.isArray( data ) ) {
- queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
- } else {
- queue.push( data );
- }
- }
- return queue || [];
- }
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks( elem, type ),
- next = function() {
- jQuery.dequeue( elem, type );
- };
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- startLength--;
- }
-
- if ( fn ) {
-
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
- }
-
- // Clear up the last queue stop function
- delete hooks.stop;
- fn.call( elem, next, hooks );
- }
-
- if ( !startLength && hooks ) {
- hooks.empty.fire();
- }
- },
-
- // Not public - generate a queueHooks object, or return the current one
- _queueHooks: function( elem, type ) {
- var key = type + "queueHooks";
- return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
- empty: jQuery.Callbacks( "once memory" ).add( function() {
- dataPriv.remove( elem, [ type + "queue", key ] );
- } )
- } );
- }
- } );
-
- jQuery.fn.extend( {
- queue: function( type, data ) {
- var setter = 2;
-
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
-
- if ( arguments.length < setter ) {
- return jQuery.queue( this[ 0 ], type );
- }
-
- return data === undefined ?
- this :
- this.each( function() {
- var queue = jQuery.queue( this, type, data );
-
- // Ensure a hooks for this queue
- jQuery._queueHooks( this, type );
-
- if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- } );
- },
- dequeue: function( type ) {
- return this.each( function() {
- jQuery.dequeue( this, type );
- } );
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
-
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, obj ) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements ] );
- }
- };
-
- if ( typeof type !== "string" ) {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
-
- while ( i-- ) {
- tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
- if ( tmp && tmp.empty ) {
- count++;
- tmp.empty.add( resolve );
- }
- }
- resolve();
- return defer.promise( obj );
- }
- } );
- var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
-
- var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
-
-
- var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
- var isHidden = function( elem, el ) {
-
- // isHidden might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem;
- return jQuery.css( elem, "display" ) === "none" ||
- !jQuery.contains( elem.ownerDocument, elem );
- };
-
-
-
- function adjustCSS( elem, prop, valueParts, tween ) {
- var adjusted,
- scale = 1,
- maxIterations = 20,
- currentValue = tween ?
- function() { return tween.cur(); } :
- function() { return jQuery.css( elem, prop, "" ); },
- initial = currentValue(),
- unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
- // Starting value computation is required for potential unit mismatches
- initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
- rcssNum.exec( jQuery.css( elem, prop ) );
-
- if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
-
- // Trust units reported by jQuery.css
- unit = unit || initialInUnit[ 3 ];
-
- // Make sure we update the tween properties later on
- valueParts = valueParts || [];
-
- // Iteratively approximate from a nonzero starting point
- initialInUnit = +initial || 1;
-
- do {
-
- // If previous iteration zeroed out, double until we get *something*.
- // Use string for doubling so we don't accidentally see scale as unchanged below
- scale = scale || ".5";
-
- // Adjust and apply
- initialInUnit = initialInUnit / scale;
- jQuery.style( elem, prop, initialInUnit + unit );
-
- // Update scale, tolerating zero or NaN from tween.cur()
- // Break the loop if scale is unchanged or perfect, or if we've just had enough.
- } while (
- scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
- );
- }
-
- if ( valueParts ) {
- initialInUnit = +initialInUnit || +initial || 0;
-
- // Apply relative offset (+=/-=) if specified
- adjusted = valueParts[ 1 ] ?
- initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
- +valueParts[ 2 ];
- if ( tween ) {
- tween.unit = unit;
- tween.start = initialInUnit;
- tween.end = adjusted;
- }
- }
- return adjusted;
- }
- var rcheckableType = ( /^(?:checkbox|radio)$/i );
-
- var rtagName = ( /<([\w:-]+)/ );
-
- var rscriptType = ( /^$|\/(?:java|ecma)script/i );
-
-
-
- // We have to close these tags to support XHTML (#13200)
- var wrapMap = {
-
- // Support: IE9
- option: [ 1, "<select multiple='multiple'>", "</select>" ],
-
- // XHTML parsers do not magically insert elements in the
- // same way that tag soup parsers do. So we cannot shorten
- // this by omitting <tbody> or other required elements.
- thead: [ 1, "<table>", "</table>" ],
- col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
- tr: [ 2, "<table><tbody>", "</tbody></table>" ],
- td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-
- _default: [ 0, "", "" ]
- };
-
- // Support: IE9
- wrapMap.optgroup = wrapMap.option;
-
- wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
- wrapMap.th = wrapMap.td;
-
-
- function getAll( context, tag ) {
-
- // Support: IE9-11+
- // Use typeof to avoid zero-argument method invocation on host objects (#15151)
- var ret = typeof context.getElementsByTagName !== "undefined" ?
- context.getElementsByTagName( tag || "*" ) :
- typeof context.querySelectorAll !== "undefined" ?
- context.querySelectorAll( tag || "*" ) :
- [];
-
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
- jQuery.merge( [ context ], ret ) :
- ret;
- }
-
-
- // Mark scripts as having already been evaluated
- function setGlobalEval( elems, refElements ) {
- var i = 0,
- l = elems.length;
-
- for ( ; i < l; i++ ) {
- dataPriv.set(
- elems[ i ],
- "globalEval",
- !refElements || dataPriv.get( refElements[ i ], "globalEval" )
- );
- }
- }
-
-
- var rhtml = /<|&#?\w+;/;
-
- function buildFragment( elems, context, scripts, selection, ignored ) {
- var elem, tmp, tag, wrap, contains, j,
- fragment = context.createDocumentFragment(),
- nodes = [],
- i = 0,
- l = elems.length;
-
- for ( ; i < l; i++ ) {
- elem = elems[ i ];
-
- if ( elem || elem === 0 ) {
-
- // Add nodes directly
- if ( jQuery.type( elem ) === "object" ) {
-
- // Support: Android<4.1, PhantomJS<2
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
-
- // Convert non-html into a text node
- } else if ( !rhtml.test( elem ) ) {
- nodes.push( context.createTextNode( elem ) );
-
- // Convert html into DOM nodes
- } else {
- tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
-
- // Deserialize a standard representation
- tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
- wrap = wrapMap[ tag ] || wrapMap._default;
- tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
-
- // Descend through wrappers to the right content
- j = wrap[ 0 ];
- while ( j-- ) {
- tmp = tmp.lastChild;
- }
-
- // Support: Android<4.1, PhantomJS<2
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge( nodes, tmp.childNodes );
-
- // Remember the top-level container
- tmp = fragment.firstChild;
-
- // Ensure the created nodes are orphaned (#12392)
- tmp.textContent = "";
- }
- }
- }
-
- // Remove wrapper from fragment
- fragment.textContent = "";
-
- i = 0;
- while ( ( elem = nodes[ i++ ] ) ) {
-
- // Skip elements already in the context collection (trac-4087)
- if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
- if ( ignored ) {
- ignored.push( elem );
- }
- continue;
- }
-
- contains = jQuery.contains( elem.ownerDocument, elem );
-
- // Append to fragment
- tmp = getAll( fragment.appendChild( elem ), "script" );
-
- // Preserve script evaluation history
- if ( contains ) {
- setGlobalEval( tmp );
- }
-
- // Capture executables
- if ( scripts ) {
- j = 0;
- while ( ( elem = tmp[ j++ ] ) ) {
- if ( rscriptType.test( elem.type || "" ) ) {
- scripts.push( elem );
- }
- }
- }
- }
-
- return fragment;
- }
-
-
- ( function() {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild( document.createElement( "div" ) ),
- input = document.createElement( "input" );
-
- // Support: Android 4.0-4.3, Safari<=5.1
- // Check state lost if the name is set (#11217)
- // Support: Windows Web Apps (WWA)
- // `name` and `type` must use .setAttribute for WWA (#14901)
- input.setAttribute( "type", "radio" );
- input.setAttribute( "checked", "checked" );
- input.setAttribute( "name", "t" );
-
- div.appendChild( input );
-
- // Support: Safari<=5.1, Android<4.2
- // Older WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
- // Support: IE<=11+
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- div.innerHTML = "<textarea>x</textarea>";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
- } )();
-
-
- var
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
-
- function returnTrue() {
- return true;
- }
-
- function returnFalse() {
- return false;
- }
-
- // Support: IE9
- // See #13393 for more info
- function safeActiveElement() {
- try {
- return document.activeElement;
- } catch ( err ) { }
- }
-
- function on( elem, types, selector, data, fn, one ) {
- var origFn, type;
-
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
-
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) {
-
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- on( elem, type, selector, data, types[ type ], one );
- }
- return elem;
- }
-
- if ( data == null && fn == null ) {
-
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
-
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
-
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return elem;
- }
-
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
-
- // Can use an empty set, since event contains the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
-
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
- }
- return elem.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- } );
- }
-
- /*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
- jQuery.event = {
-
- global: {},
-
- add: function( elem, types, handler, data, selector ) {
-
- var handleObjIn, eventHandle, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = dataPriv.get( elem );
-
- // Don't attach events to noData or text/comment nodes (but allow plain objects)
- if ( !elemData ) {
- return;
- }
-
- // Caller can pass in an object of custom data in lieu of the handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- }
-
- // Make sure that the handler has a unique ID, used to find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure and main handler, if this is the first
- if ( !( events = elemData.events ) ) {
- events = elemData.events = {};
- }
- if ( !( eventHandle = elemData.handle ) ) {
- eventHandle = elemData.handle = function( e ) {
-
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
- jQuery.event.dispatch.apply( elem, arguments ) : undefined;
- };
- }
-
- // Handle multiple events separated by a space
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[ t ] ) || [];
- type = origType = tmp[ 1 ];
- namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
-
- // There *must* be a type, no attaching namespace-only handlers
- if ( !type ) {
- continue;
- }
-
- // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[ type ] || {};
-
- // If selector defined, determine special event api type, otherwise given type
- type = ( selector ? special.delegateType : special.bindType ) || type;
-
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
-
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend( {
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join( "." )
- }, handleObjIn );
-
- // Init the event handler queue if we're the first
- if ( !( handlers = events[ type ] ) ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
-
- // Only use addEventListener if the special events handler returns false
- if ( !special.setup ||
- special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
-
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0, handleObj );
- } else {
- handlers.push( handleObj );
- }
-
- // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[ type ] = true;
- }
-
- },
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
-
- var j, origCount, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
-
- if ( !elemData || !( events = elemData.events ) ) {
- return;
- }
-
- // Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[ t ] ) || [];
- type = origType = tmp[ 1 ];
- namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
-
- // Unbind all events (on this namespace, if provided) for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
- }
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
- type = ( selector ? special.delegateType : special.bindType ) || type;
- handlers = events[ type ] || [];
- tmp = tmp[ 2 ] &&
- new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
-
- // Remove matching events
- origCount = j = handlers.length;
- while ( j-- ) {
- handleObj = handlers[ j ];
-
- if ( ( mappedTypes || origType === handleObj.origType ) &&
- ( !handler || handler.guid === handleObj.guid ) &&
- ( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector ||
- selector === "**" && handleObj.selector ) ) {
- handlers.splice( j, 1 );
-
- if ( handleObj.selector ) {
- handlers.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
- }
-
- // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if ( origCount && !handlers.length ) {
- if ( !special.teardown ||
- special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
-
- jQuery.removeEvent( elem, type, elemData.handle );
- }
-
- delete events[ type ];
- }
- }
-
- // Remove data and the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- dataPriv.remove( elem, "handle events" );
- }
- },
-
- dispatch: function( event ) {
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event );
-
- var i, j, ret, matched, handleObj,
- handlerQueue = [],
- args = slice.call( arguments ),
- handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
- special = jQuery.event.special[ event.type ] || {};
-
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[ 0 ] = event;
- event.delegateTarget = this;
-
- // Call the preDispatch hook for the mapped type, and let it bail if desired
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
- return;
- }
-
- // Determine handlers
- handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
- // Run delegates first; they may want to stop propagation beneath us
- i = 0;
- while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
- event.currentTarget = matched.elem;
-
- j = 0;
- while ( ( handleObj = matched.handlers[ j++ ] ) &&
- !event.isImmediatePropagationStopped() ) {
-
- // Triggered event must either 1) have no namespace, or 2) have namespace(s)
- // a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
-
- event.handleObj = handleObj;
- event.data = handleObj.data;
-
- ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
- handleObj.handler ).apply( matched.elem, args );
-
- if ( ret !== undefined ) {
- if ( ( event.result = ret ) === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
-
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
- }
-
- return event.result;
- },
-
- handlers: function( event, handlers ) {
- var i, matches, sel, handleObj,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target;
-
- // Support (at least): Chrome, IE9
- // Find delegate handlers
- // Black-hole SVG <use> instance trees (#13180)
- //
- // Support: Firefox<=42+
- // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
- if ( delegateCount && cur.nodeType &&
- ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
-
- for ( ; cur !== this; cur = cur.parentNode || this ) {
-
- // Don't check non-elements (#13208)
- // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
- matches = [];
- for ( i = 0; i < delegateCount; i++ ) {
- handleObj = handlers[ i ];
-
- // Don't conflict with Object.prototype properties (#13203)
- sel = handleObj.selector + " ";
-
- if ( matches[ sel ] === undefined ) {
- matches[ sel ] = handleObj.needsContext ?
- jQuery( sel, this ).index( cur ) > -1 :
- jQuery.find( sel, this, null, [ cur ] ).length;
- }
- if ( matches[ sel ] ) {
- matches.push( handleObj );
- }
- }
- if ( matches.length ) {
- handlerQueue.push( { elem: cur, handlers: matches } );
- }
- }
- }
- }
-
- // Add the remaining (directly-bound) handlers
- if ( delegateCount < handlers.length ) {
- handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
- }
-
- return handlerQueue;
- },
-
- // Includes some event props shared by KeyEvent and MouseEvent
- props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
- "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split( " " ),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ? original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
- "screenX screenY toElement" ).split( " " ),
- filter: function( event, original ) {
- var eventDoc, doc, body,
- button = original.button;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument || document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX +
- ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
- ( doc && doc.clientLeft || body && body.clientLeft || 0 );
- event.pageY = original.clientY +
- ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
- ( doc && doc.clientTop || body && body.clientTop || 0 );
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
- }
-
- return event;
- }
- },
-
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize some properties
- var i, prop, copy,
- type = event.type,
- originalEvent = event,
- fixHook = this.fixHooks[ type ];
-
- if ( !fixHook ) {
- this.fixHooks[ type ] = fixHook =
- rmouseEvent.test( type ) ? this.mouseHooks :
- rkeyEvent.test( type ) ? this.keyHooks :
- {};
- }
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
- event = new jQuery.Event( originalEvent );
-
- i = copy.length;
- while ( i-- ) {
- prop = copy[ i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Support: Cordova 2.5 (WebKit) (#13255)
- // All events should have a target; Cordova deviceready doesn't
- if ( !event.target ) {
- event.target = document;
- }
-
- // Support: Safari 6.0+, Chrome<28
- // Target should not be a text node (#504, #13143)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
- },
-
- special: {
- load: {
-
- // Prevent triggered image.load events from bubbling to window.load
- noBubble: true
- },
- focus: {
-
- // Fire native event if possible so blur/focus sequence is correct
- trigger: function() {
- if ( this !== safeActiveElement() && this.focus ) {
- this.focus();
- return false;
- }
- },
- delegateType: "focusin"
- },
- blur: {
- trigger: function() {
- if ( this === safeActiveElement() && this.blur ) {
- this.blur();
- return false;
- }
- },
- delegateType: "focusout"
- },
- click: {
-
- // For checkbox, fire native event so checked state will be right
- trigger: function() {
- if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
- this.click();
- return false;
- }
- },
-
- // For cross-browser consistency, don't fire native .click() on links
- _default: function( event ) {
- return jQuery.nodeName( event.target, "a" );
- }
- },
-
- beforeunload: {
- postDispatch: function( event ) {
-
- // Support: Firefox 20+
- // Firefox doesn't alert if the returnValue field is not set.
- if ( event.result !== undefined && event.originalEvent ) {
- event.originalEvent.returnValue = event.result;
- }
- }
- }
- }
- };
-
- jQuery.removeEvent = function( elem, type, handle ) {
-
- // This "if" is needed for plain objects
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle );
- }
- };
-
- jQuery.Event = function( src, props ) {
-
- // Allow instantiation without the 'new' keyword
- if ( !( this instanceof jQuery.Event ) ) {
- return new jQuery.Event( src, props );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
-
- // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = src.defaultPrevented ||
- src.defaultPrevented === undefined &&
-
- // Support: Android<4.0
- src.returnValue === false ?
- returnTrue :
- returnFalse;
-
- // Event type
- } else {
- this.type = src;
- }
-
- // Put explicitly provided properties onto the event object
- if ( props ) {
- jQuery.extend( this, props );
- }
-
- // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || jQuery.now();
-
- // Mark it as fixed
- this[ jQuery.expando ] = true;
- };
-
- // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
- // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
- jQuery.Event.prototype = {
- constructor: jQuery.Event,
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse,
- isSimulated: false,
-
- preventDefault: function() {
- var e = this.originalEvent;
-
- this.isDefaultPrevented = returnTrue;
-
- if ( e && !this.isSimulated ) {
- e.preventDefault();
- }
- },
- stopPropagation: function() {
- var e = this.originalEvent;
-
- this.isPropagationStopped = returnTrue;
-
- if ( e && !this.isSimulated ) {
- e.stopPropagation();
- }
- },
- stopImmediatePropagation: function() {
- var e = this.originalEvent;
-
- this.isImmediatePropagationStopped = returnTrue;
-
- if ( e && !this.isSimulated ) {
- e.stopImmediatePropagation();
- }
-
- this.stopPropagation();
- }
- };
-
- // Create mouseenter/leave events using mouseover/out and event-time checks
- // so that event delegation works in jQuery.
- // Do the same for pointerenter/pointerleave and pointerover/pointerout
- //
- // Support: Safari 7 only
- // Safari sends mouseenter too often; see:
- // https://code.google.com/p/chromium/issues/detail?id=470258
- // for the description of the bug (it existed in older Chrome versions as well).
- jQuery.each( {
- mouseenter: "mouseover",
- mouseleave: "mouseout",
- pointerenter: "pointerover",
- pointerleave: "pointerout"
- }, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- delegateType: fix,
- bindType: fix,
-
- handle: function( event ) {
- var ret,
- target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj;
-
- // For mouseenter/leave call the handler if related is outside the target.
- // NB: No relatedTarget if the mouse left/entered the browser window
- if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply( this, arguments );
- event.type = fix;
- }
- return ret;
- }
- };
- } );
-
- jQuery.fn.extend( {
- on: function( types, selector, data, fn ) {
- return on( this, types, selector, data, fn );
- },
- one: function( types, selector, data, fn ) {
- return on( this, types, selector, data, fn, 1 );
- },
- off: function( types, selector, fn ) {
- var handleObj, type;
- if ( types && types.preventDefault && types.handleObj ) {
-
- // ( event ) dispatched jQuery.Event
- handleObj = types.handleObj;
- jQuery( types.delegateTarget ).off(
- handleObj.namespace ?
- handleObj.origType + "." + handleObj.namespace :
- handleObj.origType,
- handleObj.selector,
- handleObj.handler
- );
- return this;
- }
- if ( typeof types === "object" ) {
-
- // ( types-object [, selector] )
- for ( type in types ) {
- this.off( type, selector, types[ type ] );
- }
- return this;
- }
- if ( selector === false || typeof selector === "function" ) {
-
- // ( types [, fn] )
- fn = selector;
- selector = undefined;
- }
- if ( fn === false ) {
- fn = returnFalse;
- }
- return this.each( function() {
- jQuery.event.remove( this, types, fn, selector );
- } );
- }
- } );
-
-
- var
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
-
- // Support: IE 10-11, Edge 10240+
- // In IE/Edge using regex groups here causes severe slowdowns.
- // See https://connect.microsoft.com/IE/feedback/details/1736512/
- rnoInnerhtml = /<script|<style|<link/i,
-
- // checked="checked" or checked
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
- rscriptTypeMasked = /^true\/(.*)/,
- rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
-
- // Manipulating tables requires a tbody
- function manipulationTarget( elem, content ) {
- return jQuery.nodeName( elem, "table" ) &&
- jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
-
- elem.getElementsByTagName( "tbody" )[ 0 ] ||
- elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
- elem;
- }
-
- // Replace/restore the type attribute of script elements for safe DOM manipulation
- function disableScript( elem ) {
- elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
- return elem;
- }
- function restoreScript( elem ) {
- var match = rscriptTypeMasked.exec( elem.type );
-
- if ( match ) {
- elem.type = match[ 1 ];
- } else {
- elem.removeAttribute( "type" );
- }
-
- return elem;
- }
-
- function cloneCopyEvent( src, dest ) {
- var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
-
- if ( dest.nodeType !== 1 ) {
- return;
- }
-
- // 1. Copy private data: events, handlers, etc.
- if ( dataPriv.hasData( src ) ) {
- pdataOld = dataPriv.access( src );
- pdataCur = dataPriv.set( dest, pdataOld );
- events = pdataOld.events;
-
- if ( events ) {
- delete pdataCur.handle;
- pdataCur.events = {};
-
- for ( type in events ) {
- for ( i = 0, l = events[ type ].length; i < l; i++ ) {
- jQuery.event.add( dest, type, events[ type ][ i ] );
- }
- }
- }
- }
-
- // 2. Copy user data
- if ( dataUser.hasData( src ) ) {
- udataOld = dataUser.access( src );
- udataCur = jQuery.extend( {}, udataOld );
-
- dataUser.set( dest, udataCur );
- }
- }
-
- // Fix IE bugs, see support tests
- function fixInput( src, dest ) {
- var nodeName = dest.nodeName.toLowerCase();
-
- // Fails to persist the checked state of a cloned checkbox or radio button.
- if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
- dest.checked = src.checked;
-
- // Fails to return the selected option to the default selected state when cloning options
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
- dest.defaultValue = src.defaultValue;
- }
- }
-
- function domManip( collection, args, callback, ignored ) {
-
- // Flatten any nested arrays
- args = concat.apply( [], args );
-
- var fragment, first, scripts, hasScripts, node, doc,
- i = 0,
- l = collection.length,
- iNoClone = l - 1,
- value = args[ 0 ],
- isFunction = jQuery.isFunction( value );
-
- // We can't cloneNode fragments that contain checked, in WebKit
- if ( isFunction ||
- ( l > 1 && typeof value === "string" &&
- !support.checkClone && rchecked.test( value ) ) ) {
- return collection.each( function( index ) {
- var self = collection.eq( index );
- if ( isFunction ) {
- args[ 0 ] = value.call( this, index, self.html() );
- }
- domManip( self, args, callback, ignored );
- } );
- }
-
- if ( l ) {
- fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
- first = fragment.firstChild;
-
- if ( fragment.childNodes.length === 1 ) {
- fragment = first;
- }
-
- // Require either new content or an interest in ignored elements to invoke the callback
- if ( first || ignored ) {
- scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
- hasScripts = scripts.length;
-
- // Use the original fragment for the last item
- // instead of the first because it can end up
- // being emptied incorrectly in certain situations (#8070).
- for ( ; i < l; i++ ) {
- node = fragment;
-
- if ( i !== iNoClone ) {
- node = jQuery.clone( node, true, true );
-
- // Keep references to cloned scripts for later restoration
- if ( hasScripts ) {
-
- // Support: Android<4.1, PhantomJS<2
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge( scripts, getAll( node, "script" ) );
- }
- }
-
- callback.call( collection[ i ], node, i );
- }
-
- if ( hasScripts ) {
- doc = scripts[ scripts.length - 1 ].ownerDocument;
-
- // Reenable scripts
- jQuery.map( scripts, restoreScript );
-
- // Evaluate executable scripts on first document insertion
- for ( i = 0; i < hasScripts; i++ ) {
- node = scripts[ i ];
- if ( rscriptType.test( node.type || "" ) &&
- !dataPriv.access( node, "globalEval" ) &&
- jQuery.contains( doc, node ) ) {
-
- if ( node.src ) {
-
- // Optional AJAX dependency, but won't run scripts if not present
- if ( jQuery._evalUrl ) {
- jQuery._evalUrl( node.src );
- }
- } else {
- jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
- }
- }
- }
- }
- }
- }
-
- return collection;
- }
-
- function remove( elem, selector, keepData ) {
- var node,
- nodes = selector ? jQuery.filter( selector, elem ) : elem,
- i = 0;
-
- for ( ; ( node = nodes[ i ] ) != null; i++ ) {
- if ( !keepData && node.nodeType === 1 ) {
- jQuery.cleanData( getAll( node ) );
- }
-
- if ( node.parentNode ) {
- if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
- setGlobalEval( getAll( node, "script" ) );
- }
- node.parentNode.removeChild( node );
- }
- }
-
- return elem;
- }
-
- jQuery.extend( {
- htmlPrefilter: function( html ) {
- return html.replace( rxhtmlTag, "<$1></$2>" );
- },
-
- clone: function( elem, dataAndEvents, deepDataAndEvents ) {
- var i, l, srcElements, destElements,
- clone = elem.cloneNode( true ),
- inPage = jQuery.contains( elem.ownerDocument, elem );
-
- // Fix IE cloning issues
- if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
- !jQuery.isXMLDoc( elem ) ) {
-
- // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
- destElements = getAll( clone );
- srcElements = getAll( elem );
-
- for ( i = 0, l = srcElements.length; i < l; i++ ) {
- fixInput( srcElements[ i ], destElements[ i ] );
- }
- }
-
- // Copy the events from the original to the clone
- if ( dataAndEvents ) {
- if ( deepDataAndEvents ) {
- srcElements = srcElements || getAll( elem );
- destElements = destElements || getAll( clone );
-
- for ( i = 0, l = srcElements.length; i < l; i++ ) {
- cloneCopyEvent( srcElements[ i ], destElements[ i ] );
- }
- } else {
- cloneCopyEvent( elem, clone );
- }
- }
-
- // Preserve script evaluation history
- destElements = getAll( clone, "script" );
- if ( destElements.length > 0 ) {
- setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
- }
-
- // Return the cloned set
- return clone;
- },
-
- cleanData: function( elems ) {
- var data, elem, type,
- special = jQuery.event.special,
- i = 0;
-
- for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
- if ( acceptData( elem ) ) {
- if ( ( data = elem[ dataPriv.expando ] ) ) {
- if ( data.events ) {
- for ( type in data.events ) {
- if ( special[ type ] ) {
- jQuery.event.remove( elem, type );
-
- // This is a shortcut to avoid jQuery.event.remove's overhead
- } else {
- jQuery.removeEvent( elem, type, data.handle );
- }
- }
- }
-
- // Support: Chrome <= 35-45+
- // Assign undefined instead of using delete, see Data#remove
- elem[ dataPriv.expando ] = undefined;
- }
- if ( elem[ dataUser.expando ] ) {
-
- // Support: Chrome <= 35-45+
- // Assign undefined instead of using delete, see Data#remove
- elem[ dataUser.expando ] = undefined;
- }
- }
- }
- }
- } );
-
- jQuery.fn.extend( {
-
- // Keep domManip exposed until 3.0 (gh-2225)
- domManip: domManip,
-
- detach: function( selector ) {
- return remove( this, selector, true );
- },
-
- remove: function( selector ) {
- return remove( this, selector );
- },
-
- text: function( value ) {
- return access( this, function( value ) {
- return value === undefined ?
- jQuery.text( this ) :
- this.empty().each( function() {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- this.textContent = value;
- }
- } );
- }, null, value, arguments.length );
- },
-
- append: function() {
- return domManip( this, arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.appendChild( elem );
- }
- } );
- },
-
- prepend: function() {
- return domManip( this, arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.insertBefore( elem, target.firstChild );
- }
- } );
- },
-
- before: function() {
- return domManip( this, arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this );
- }
- } );
- },
-
- after: function() {
- return domManip( this, arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this.nextSibling );
- }
- } );
- },
-
- empty: function() {
- var elem,
- i = 0;
-
- for ( ; ( elem = this[ i ] ) != null; i++ ) {
- if ( elem.nodeType === 1 ) {
-
- // Prevent memory leaks
- jQuery.cleanData( getAll( elem, false ) );
-
- // Remove any remaining nodes
- elem.textContent = "";
- }
- }
-
- return this;
- },
-
- clone: function( dataAndEvents, deepDataAndEvents ) {
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
- return this.map( function() {
- return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
- } );
- },
-
- html: function( value ) {
- return access( this, function( value ) {
- var elem = this[ 0 ] || {},
- i = 0,
- l = this.length;
-
- if ( value === undefined && elem.nodeType === 1 ) {
- return elem.innerHTML;
- }
-
- // See if we can take a shortcut and just use innerHTML
- if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
- !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
-
- value = jQuery.htmlPrefilter( value );
-
- try {
- for ( ; i < l; i++ ) {
- elem = this[ i ] || {};
-
- // Remove element nodes and prevent memory leaks
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem, false ) );
- elem.innerHTML = value;
- }
- }
-
- elem = 0;
-
- // If using innerHTML throws an exception, use the fallback method
- } catch ( e ) {}
- }
-
- if ( elem ) {
- this.empty().append( value );
- }
- }, null, value, arguments.length );
- },
-
- replaceWith: function() {
- var ignored = [];
-
- // Make the changes, replacing each non-ignored context element with the new content
- return domManip( this, arguments, function( elem ) {
- var parent = this.parentNode;
-
- if ( jQuery.inArray( this, ignored ) < 0 ) {
- jQuery.cleanData( getAll( this ) );
- if ( parent ) {
- parent.replaceChild( elem, this );
- }
- }
-
- // Force callback invocation
- }, ignored );
- }
- } );
-
- jQuery.each( {
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
- }, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var elems,
- ret = [],
- insert = jQuery( selector ),
- last = insert.length - 1,
- i = 0;
-
- for ( ; i <= last; i++ ) {
- elems = i === last ? this : this.clone( true );
- jQuery( insert[ i ] )[ original ]( elems );
-
- // Support: QtWebKit
- // .get() because push.apply(_, arraylike) throws
- push.apply( ret, elems.get() );
- }
-
- return this.pushStack( ret );
- };
- } );
-
-
- var iframe,
- elemdisplay = {
-
- // Support: Firefox
- // We have to pre-define these values for FF (#10227)
- HTML: "block",
- BODY: "block"
- };
-
- /**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-
- // Called only from within defaultDisplay
- function actualDisplay( name, doc ) {
- var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
- display = jQuery.css( elem[ 0 ], "display" );
-
- // We don't have any data stored on the element,
- // so use "detach" method as fast way to get rid of the element
- elem.detach();
-
- return display;
- }
-
- /**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
- function defaultDisplay( nodeName ) {
- var doc = document,
- display = elemdisplay[ nodeName ];
-
- if ( !display ) {
- display = actualDisplay( nodeName, doc );
-
- // If the simple way fails, read from inside an iframe
- if ( display === "none" || !display ) {
-
- // Use the already-created iframe if possible
- iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
- .appendTo( doc.documentElement );
-
- // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
- doc = iframe[ 0 ].contentDocument;
-
- // Support: IE
- doc.write();
- doc.close();
-
- display = actualDisplay( nodeName, doc );
- iframe.detach();
- }
-
- // Store the correct default display
- elemdisplay[ nodeName ] = display;
- }
-
- return display;
- }
- var rmargin = ( /^margin/ );
-
- var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
- var getStyles = function( elem ) {
-
- // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
- // IE throws on elements created in popups
- // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
- var view = elem.ownerDocument.defaultView;
-
- if ( !view || !view.opener ) {
- view = window;
- }
-
- return view.getComputedStyle( elem );
- };
-
- var swap = function( elem, options, callback, args ) {
- var ret, name,
- old = {};
-
- // Remember the old values, and insert the new ones
- for ( name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- ret = callback.apply( elem, args || [] );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
-
- return ret;
- };
-
-
- var documentElement = document.documentElement;
-
-
-
- ( function() {
- var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
- container = document.createElement( "div" ),
- div = document.createElement( "div" );
-
- // Finish early in limited (non-browser) environments
- if ( !div.style ) {
- return;
- }
-
- // Support: IE9-11+
- // Style of cloned element affects source element cloned (#8908)
- div.style.backgroundClip = "content-box";
- div.cloneNode( true ).style.backgroundClip = "";
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
- container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
- "padding:0;margin-top:1px;position:absolute";
- container.appendChild( div );
-
- // Executing both pixelPosition & boxSizingReliable tests require only one layout
- // so they're executed at the same time to save the second computation.
- function computeStyleTests() {
- div.style.cssText =
-
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
- "position:relative;display:block;" +
- "margin:auto;border:1px;padding:1px;" +
- "top:1%;width:50%";
- div.innerHTML = "";
- documentElement.appendChild( container );
-
- var divStyle = window.getComputedStyle( div );
- pixelPositionVal = divStyle.top !== "1%";
- reliableMarginLeftVal = divStyle.marginLeft === "2px";
- boxSizingReliableVal = divStyle.width === "4px";
-
- // Support: Android 4.0 - 4.3 only
- // Some styles come back with percentage values, even though they shouldn't
- div.style.marginRight = "50%";
- pixelMarginRightVal = divStyle.marginRight === "4px";
-
- documentElement.removeChild( container );
- }
-
- jQuery.extend( support, {
- pixelPosition: function() {
-
- // This test is executed only once but we still do memoizing
- // since we can use the boxSizingReliable pre-computing.
- // No need to check if the test was already performed, though.
- computeStyleTests();
- return pixelPositionVal;
- },
- boxSizingReliable: function() {
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
- return boxSizingReliableVal;
- },
- pixelMarginRight: function() {
-
- // Support: Android 4.0-4.3
- // We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
- // since that compresses better and they're computed together anyway.
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
- return pixelMarginRightVal;
- },
- reliableMarginLeft: function() {
-
- // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
- return reliableMarginLeftVal;
- },
- reliableMarginRight: function() {
-
- // Support: Android 2.3
- // Check if div with explicit width and no margin-right incorrectly
- // gets computed margin-right based on width of container. (#3333)
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- // This support function is only executed once so no memoizing is needed.
- var ret,
- marginDiv = div.appendChild( document.createElement( "div" ) );
-
- // Reset CSS: box-sizing; display; margin; border; padding
- marginDiv.style.cssText = div.style.cssText =
-
- // Support: Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:content-box;box-sizing:content-box;" +
- "display:block;margin:0;border:0;padding:0";
- marginDiv.style.marginRight = marginDiv.style.width = "0";
- div.style.width = "1px";
- documentElement.appendChild( container );
-
- ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
-
- documentElement.removeChild( container );
- div.removeChild( marginDiv );
-
- return ret;
- }
- } );
- } )();
-
-
- function curCSS( elem, name, computed ) {
- var width, minWidth, maxWidth, ret,
- style = elem.style;
-
- computed = computed || getStyles( elem );
- ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
-
- // Support: Opera 12.1x only
- // Fall back to style even without computed
- // computed is undefined for elems on document fragments
- if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
- ret = jQuery.style( elem, name );
- }
-
- // Support: IE9
- // getPropertyValue is only needed for .css('filter') (#12537)
- if ( computed ) {
-
- // A tribute to the "awesome hack by Dean Edwards"
- // Android Browser returns percentage for some values,
- // but width seems to be reliably pixels.
- // This is against the CSSOM draft spec:
- // http://dev.w3.org/csswg/cssom/#resolved-values
- if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
-
- // Remember the original values
- width = style.width;
- minWidth = style.minWidth;
- maxWidth = style.maxWidth;
-
- // Put in the new values to get a computed value out
- style.minWidth = style.maxWidth = style.width = ret;
- ret = computed.width;
-
- // Revert the changed values
- style.width = width;
- style.minWidth = minWidth;
- style.maxWidth = maxWidth;
- }
- }
-
- return ret !== undefined ?
-
- // Support: IE9-11+
- // IE returns zIndex value as an integer.
- ret + "" :
- ret;
- }
-
-
- function addGetHookIf( conditionFn, hookFn ) {
-
- // Define the hook, we'll check on the first run if it's really needed.
- return {
- get: function() {
- if ( conditionFn() ) {
-
- // Hook not needed (or it's not possible to use it due
- // to missing dependency), remove it.
- delete this.get;
- return;
- }
-
- // Hook needed; redefine it so that the support test is not executed again.
- return ( this.get = hookFn ).apply( this, arguments );
- }
- };
- }
-
-
- var
-
- // Swappable if display is none or starts with table
- // except "table", "table-cell", or "table-caption"
- // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
-
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
- cssNormalTransform = {
- letterSpacing: "0",
- fontWeight: "400"
- },
-
- cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
- emptyStyle = document.createElement( "div" ).style;
-
- // Return a css property mapped to a potentially vendor prefixed property
- function vendorPropName( name ) {
-
- // Shortcut for names that are not vendor prefixed
- if ( name in emptyStyle ) {
- return name;
- }
-
- // Check for vendor prefixed names
- var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
- i = cssPrefixes.length;
-
- while ( i-- ) {
- name = cssPrefixes[ i ] + capName;
- if ( name in emptyStyle ) {
- return name;
- }
- }
- }
-
- function setPositiveNumber( elem, value, subtract ) {
-
- // Any relative (+/-) values have already been
- // normalized at this point
- var matches = rcssNum.exec( value );
- return matches ?
-
- // Guard against undefined "subtract", e.g., when used as in cssHooks
- Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
- value;
- }
-
- function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
- var i = extra === ( isBorderBox ? "border" : "content" ) ?
-
- // If we already have the right measurement, avoid augmentation
- 4 :
-
- // Otherwise initialize for horizontal or vertical properties
- name === "width" ? 1 : 0,
-
- val = 0;
-
- for ( ; i < 4; i += 2 ) {
-
- // Both box models exclude margin, so add it if we want it
- if ( extra === "margin" ) {
- val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
- }
-
- if ( isBorderBox ) {
-
- // border-box includes padding, so remove it if we want content
- if ( extra === "content" ) {
- val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
- }
-
- // At this point, extra isn't border nor margin, so remove border
- if ( extra !== "margin" ) {
- val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
- }
- } else {
-
- // At this point, extra isn't content, so add padding
- val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-
- // At this point, extra isn't content nor padding, so add border
- if ( extra !== "padding" ) {
- val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
- }
- }
- }
-
- return val;
- }
-
- function getWidthOrHeight( elem, name, extra ) {
-
- // Start with offset property, which is equivalent to the border-box value
- var valueIsBorderBox = true,
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
- styles = getStyles( elem ),
- isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
-
- // Some non-html elements return undefined for offsetWidth, so check for null/undefined
- // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
- // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
- if ( val <= 0 || val == null ) {
-
- // Fall back to computed then uncomputed css if necessary
- val = curCSS( elem, name, styles );
- if ( val < 0 || val == null ) {
- val = elem.style[ name ];
- }
-
- // Computed unit is not pixels. Stop here and return.
- if ( rnumnonpx.test( val ) ) {
- return val;
- }
-
- // Check for style in case a browser which returns unreliable values
- // for getComputedStyle silently falls back to the reliable elem.style
- valueIsBorderBox = isBorderBox &&
- ( support.boxSizingReliable() || val === elem.style[ name ] );
-
- // Normalize "", auto, and prepare for extra
- val = parseFloat( val ) || 0;
- }
-
- // Use the active box-sizing model to add/subtract irrelevant styles
- return ( val +
- augmentWidthOrHeight(
- elem,
- name,
- extra || ( isBorderBox ? "border" : "content" ),
- valueIsBorderBox,
- styles
- )
- ) + "px";
- }
-
- function showHide( elements, show ) {
- var display, elem, hidden,
- values = [],
- index = 0,
- length = elements.length;
-
- for ( ; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
-
- values[ index ] = dataPriv.get( elem, "olddisplay" );
- display = elem.style.display;
- if ( show ) {
-
- // Reset the inline display of this element to learn if it is
- // being hidden by cascaded rules or not
- if ( !values[ index ] && display === "none" ) {
- elem.style.display = "";
- }
-
- // Set elements which have been overridden with display: none
- // in a stylesheet to whatever the default browser style is
- // for such an element
- if ( elem.style.display === "" && isHidden( elem ) ) {
- values[ index ] = dataPriv.access(
- elem,
- "olddisplay",
- defaultDisplay( elem.nodeName )
- );
- }
- } else {
- hidden = isHidden( elem );
-
- if ( display !== "none" || !hidden ) {
- dataPriv.set(
- elem,
- "olddisplay",
- hidden ? display : jQuery.css( elem, "display" )
- );
- }
- }
- }
-
- // Set the display of most of the elements in a second loop
- // to avoid the constant reflow
- for ( index = 0; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
- if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
- elem.style.display = show ? values[ index ] || "" : "none";
- }
- }
-
- return elements;
- }
-
- jQuery.extend( {
-
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function( elem, computed ) {
- if ( computed ) {
-
- // We should always get a number back from opacity
- var ret = curCSS( elem, "opacity" );
- return ret === "" ? "1" : ret;
- }
- }
- }
- },
-
- // Don't automatically add "px" to these possibly-unitless properties
- cssNumber: {
- "animationIterationCount": true,
- "columnCount": true,
- "fillOpacity": true,
- "flexGrow": true,
- "flexShrink": true,
- "fontWeight": true,
- "lineHeight": true,
- "opacity": true,
- "order": true,
- "orphans": true,
- "widows": true,
- "zIndex": true,
- "zoom": true
- },
-
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {
- "float": "cssFloat"
- },
-
- // Get and set the style property on a DOM Node
- style: function( elem, name, value, extra ) {
-
- // Don't set styles on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
- return;
- }
-
- // Make sure that we're working with the right name
- var ret, type, hooks,
- origName = jQuery.camelCase( name ),
- style = elem.style;
-
- name = jQuery.cssProps[ origName ] ||
- ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
-
- // Gets hook for the prefixed version, then unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // Check if we're setting a value
- if ( value !== undefined ) {
- type = typeof value;
-
- // Convert "+=" or "-=" to relative numbers (#7345)
- if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
- value = adjustCSS( elem, name, ret );
-
- // Fixes bug #9237
- type = "number";
- }
-
- // Make sure that null and NaN values aren't set (#7116)
- if ( value == null || value !== value ) {
- return;
- }
-
- // If a number was passed in, add the unit (except for certain CSS properties)
- if ( type === "number" ) {
- value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
- }
-
- // Support: IE9-11+
- // background-* props affect original clone's values
- if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
- style[ name ] = "inherit";
- }
-
- // If a hook was provided, use that value, otherwise just set the specified value
- if ( !hooks || !( "set" in hooks ) ||
- ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
-
- style[ name ] = value;
- }
-
- } else {
-
- // If a hook was provided get the non-computed value from there
- if ( hooks && "get" in hooks &&
- ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
-
- return ret;
- }
-
- // Otherwise just get the value from the style object
- return style[ name ];
- }
- },
-
- css: function( elem, name, extra, styles ) {
- var val, num, hooks,
- origName = jQuery.camelCase( name );
-
- // Make sure that we're working with the right name
- name = jQuery.cssProps[ origName ] ||
- ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
-
- // Try prefixed name followed by the unprefixed name
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // If a hook was provided get the computed value from there
- if ( hooks && "get" in hooks ) {
- val = hooks.get( elem, true, extra );
- }
-
- // Otherwise, if a way to get the computed value exists, use that
- if ( val === undefined ) {
- val = curCSS( elem, name, styles );
- }
-
- // Convert "normal" to computed value
- if ( val === "normal" && name in cssNormalTransform ) {
- val = cssNormalTransform[ name ];
- }
-
- // Make numeric if forced or a qualifier was provided and val looks numeric
- if ( extra === "" || extra ) {
- num = parseFloat( val );
- return extra === true || isFinite( num ) ? num || 0 : val;
- }
- return val;
- }
- } );
-
- jQuery.each( [ "height", "width" ], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- if ( computed ) {
-
- // Certain elements can have dimension info if we invisibly show them
- // but it must have a current display style that would benefit
- return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
- elem.offsetWidth === 0 ?
- swap( elem, cssShow, function() {
- return getWidthOrHeight( elem, name, extra );
- } ) :
- getWidthOrHeight( elem, name, extra );
- }
- },
-
- set: function( elem, value, extra ) {
- var matches,
- styles = extra && getStyles( elem ),
- subtract = extra && augmentWidthOrHeight(
- elem,
- name,
- extra,
- jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
- styles
- );
-
- // Convert to pixels if value adjustment is needed
- if ( subtract && ( matches = rcssNum.exec( value ) ) &&
- ( matches[ 3 ] || "px" ) !== "px" ) {
-
- elem.style[ name ] = value;
- value = jQuery.css( elem, name );
- }
-
- return setPositiveNumber( elem, value, subtract );
- }
- };
- } );
-
- jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
- function( elem, computed ) {
- if ( computed ) {
- return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
- elem.getBoundingClientRect().left -
- swap( elem, { marginLeft: 0 }, function() {
- return elem.getBoundingClientRect().left;
- } )
- ) + "px";
- }
- }
- );
-
- // Support: Android 2.3
- jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
- function( elem, computed ) {
- if ( computed ) {
- return swap( elem, { "display": "inline-block" },
- curCSS, [ elem, "marginRight" ] );
- }
- }
- );
-
- // These hooks are used by animate to expand properties
- jQuery.each( {
- margin: "",
- padding: "",
- border: "Width"
- }, function( prefix, suffix ) {
- jQuery.cssHooks[ prefix + suffix ] = {
- expand: function( value ) {
- var i = 0,
- expanded = {},
-
- // Assumes a single number if not a string
- parts = typeof value === "string" ? value.split( " " ) : [ value ];
-
- for ( ; i < 4; i++ ) {
- expanded[ prefix + cssExpand[ i ] + suffix ] =
- parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
- }
-
- return expanded;
- }
- };
-
- if ( !rmargin.test( prefix ) ) {
- jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
- }
- } );
-
- jQuery.fn.extend( {
- css: function( name, value ) {
- return access( this, function( elem, name, value ) {
- var styles, len,
- map = {},
- i = 0;
-
- if ( jQuery.isArray( name ) ) {
- styles = getStyles( elem );
- len = name.length;
-
- for ( ; i < len; i++ ) {
- map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
- }
-
- return map;
- }
-
- return value !== undefined ?
- jQuery.style( elem, name, value ) :
- jQuery.css( elem, name );
- }, name, value, arguments.length > 1 );
- },
- show: function() {
- return showHide( this, true );
- },
- hide: function() {
- return showHide( this );
- },
- toggle: function( state ) {
- if ( typeof state === "boolean" ) {
- return state ? this.show() : this.hide();
- }
-
- return this.each( function() {
- if ( isHidden( this ) ) {
- jQuery( this ).show();
- } else {
- jQuery( this ).hide();
- }
- } );
- }
- } );
-
-
- function Tween( elem, options, prop, end, easing ) {
- return new Tween.prototype.init( elem, options, prop, end, easing );
- }
- jQuery.Tween = Tween;
-
- Tween.prototype = {
- constructor: Tween,
- init: function( elem, options, prop, end, easing, unit ) {
- this.elem = elem;
- this.prop = prop;
- this.easing = easing || jQuery.easing._default;
- this.options = options;
- this.start = this.now = this.cur();
- this.end = end;
- this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
- },
- cur: function() {
- var hooks = Tween.propHooks[ this.prop ];
-
- return hooks && hooks.get ?
- hooks.get( this ) :
- Tween.propHooks._default.get( this );
- },
- run: function( percent ) {
- var eased,
- hooks = Tween.propHooks[ this.prop ];
-
- if ( this.options.duration ) {
- this.pos = eased = jQuery.easing[ this.easing ](
- percent, this.options.duration * percent, 0, 1, this.options.duration
- );
- } else {
- this.pos = eased = percent;
- }
- this.now = ( this.end - this.start ) * eased + this.start;
-
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- if ( hooks && hooks.set ) {
- hooks.set( this );
- } else {
- Tween.propHooks._default.set( this );
- }
- return this;
- }
- };
-
- Tween.prototype.init.prototype = Tween.prototype;
-
- Tween.propHooks = {
- _default: {
- get: function( tween ) {
- var result;
-
- // Use a property on the element directly when it is not a DOM element,
- // or when there is no matching style property that exists.
- if ( tween.elem.nodeType !== 1 ||
- tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
- return tween.elem[ tween.prop ];
- }
-
- // Passing an empty string as a 3rd parameter to .css will automatically
- // attempt a parseFloat and fallback to a string if the parse fails.
- // Simple values such as "10px" are parsed to Float;
- // complex values such as "rotate(1rad)" are returned as-is.
- result = jQuery.css( tween.elem, tween.prop, "" );
-
- // Empty strings, null, undefined and "auto" are converted to 0.
- return !result || result === "auto" ? 0 : result;
- },
- set: function( tween ) {
-
- // Use step hook for back compat.
- // Use cssHook if its there.
- // Use .style if available and use plain properties where available.
- if ( jQuery.fx.step[ tween.prop ] ) {
- jQuery.fx.step[ tween.prop ]( tween );
- } else if ( tween.elem.nodeType === 1 &&
- ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
- jQuery.cssHooks[ tween.prop ] ) ) {
- jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
- } else {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
- }
- };
-
- // Support: IE9
- // Panic based approach to setting things on disconnected nodes
- Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
- set: function( tween ) {
- if ( tween.elem.nodeType && tween.elem.parentNode ) {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
- };
-
- jQuery.easing = {
- linear: function( p ) {
- return p;
- },
- swing: function( p ) {
- return 0.5 - Math.cos( p * Math.PI ) / 2;
- },
- _default: "swing"
- };
-
- jQuery.fx = Tween.prototype.init;
-
- // Back Compat <1.8 extension point
- jQuery.fx.step = {};
-
-
-
-
- var
- fxNow, timerId,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rrun = /queueHooks$/;
-
- // Animations created synchronously will run synchronously
- function createFxNow() {
- window.setTimeout( function() {
- fxNow = undefined;
- } );
- return ( fxNow = jQuery.now() );
- }
-
- // Generate parameters to create a standard animation
- function genFx( type, includeWidth ) {
- var which,
- i = 0,
- attrs = { height: type };
-
- // If we include width, step value is 1 to do all cssExpand values,
- // otherwise step value is 2 to skip over Left and Right
- includeWidth = includeWidth ? 1 : 0;
- for ( ; i < 4 ; i += 2 - includeWidth ) {
- which = cssExpand[ i ];
- attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
- }
-
- if ( includeWidth ) {
- attrs.opacity = attrs.width = type;
- }
-
- return attrs;
- }
-
- function createTween( value, prop, animation ) {
- var tween,
- collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
- index = 0,
- length = collection.length;
- for ( ; index < length; index++ ) {
- if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
-
- // We're done with this property
- return tween;
- }
- }
- }
-
- function defaultPrefilter( elem, props, opts ) {
- /* jshint validthis: true */
- var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
- anim = this,
- orig = {},
- style = elem.style,
- hidden = elem.nodeType && isHidden( elem ),
- dataShow = dataPriv.get( elem, "fxshow" );
-
- // Handle queue: false promises
- if ( !opts.queue ) {
- hooks = jQuery._queueHooks( elem, "fx" );
- if ( hooks.unqueued == null ) {
- hooks.unqueued = 0;
- oldfire = hooks.empty.fire;
- hooks.empty.fire = function() {
- if ( !hooks.unqueued ) {
- oldfire();
- }
- };
- }
- hooks.unqueued++;
-
- anim.always( function() {
-
- // Ensure the complete handler is called before this completes
- anim.always( function() {
- hooks.unqueued--;
- if ( !jQuery.queue( elem, "fx" ).length ) {
- hooks.empty.fire();
- }
- } );
- } );
- }
-
- // Height/width overflow pass
- if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
-
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE9-10 do not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height animated
- display = jQuery.css( elem, "display" );
-
- // Test default display if display is currently "none"
- checkDisplay = display === "none" ?
- dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
-
- if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
- style.display = "inline-block";
- }
- }
-
- if ( opts.overflow ) {
- style.overflow = "hidden";
- anim.always( function() {
- style.overflow = opts.overflow[ 0 ];
- style.overflowX = opts.overflow[ 1 ];
- style.overflowY = opts.overflow[ 2 ];
- } );
- }
-
- // show/hide pass
- for ( prop in props ) {
- value = props[ prop ];
- if ( rfxtypes.exec( value ) ) {
- delete props[ prop ];
- toggle = toggle || value === "toggle";
- if ( value === ( hidden ? "hide" : "show" ) ) {
-
- // If there is dataShow left over from a stopped hide or show
- // and we are going to proceed with show, we should pretend to be hidden
- if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
- hidden = true;
- } else {
- continue;
- }
- }
- orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
-
- // Any non-fx value stops us from restoring the original display value
- } else {
- display = undefined;
- }
- }
-
- if ( !jQuery.isEmptyObject( orig ) ) {
- if ( dataShow ) {
- if ( "hidden" in dataShow ) {
- hidden = dataShow.hidden;
- }
- } else {
- dataShow = dataPriv.access( elem, "fxshow", {} );
- }
-
- // Store state if its toggle - enables .stop().toggle() to "reverse"
- if ( toggle ) {
- dataShow.hidden = !hidden;
- }
- if ( hidden ) {
- jQuery( elem ).show();
- } else {
- anim.done( function() {
- jQuery( elem ).hide();
- } );
- }
- anim.done( function() {
- var prop;
-
- dataPriv.remove( elem, "fxshow" );
- for ( prop in orig ) {
- jQuery.style( elem, prop, orig[ prop ] );
- }
- } );
- for ( prop in orig ) {
- tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
-
- if ( !( prop in dataShow ) ) {
- dataShow[ prop ] = tween.start;
- if ( hidden ) {
- tween.end = tween.start;
- tween.start = prop === "width" || prop === "height" ? 1 : 0;
- }
- }
- }
-
- // If this is a noop like .hide().hide(), restore an overwritten display value
- } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
- style.display = display;
- }
- }
-
- function propFilter( props, specialEasing ) {
- var index, name, easing, value, hooks;
-
- // camelCase, specialEasing and expand cssHook pass
- for ( index in props ) {
- name = jQuery.camelCase( index );
- easing = specialEasing[ name ];
- value = props[ index ];
- if ( jQuery.isArray( value ) ) {
- easing = value[ 1 ];
- value = props[ index ] = value[ 0 ];
- }
-
- if ( index !== name ) {
- props[ name ] = value;
- delete props[ index ];
- }
-
- hooks = jQuery.cssHooks[ name ];
- if ( hooks && "expand" in hooks ) {
- value = hooks.expand( value );
- delete props[ name ];
-
- // Not quite $.extend, this won't overwrite existing keys.
- // Reusing 'index' because we have the correct "name"
- for ( index in value ) {
- if ( !( index in props ) ) {
- props[ index ] = value[ index ];
- specialEasing[ index ] = easing;
- }
- }
- } else {
- specialEasing[ name ] = easing;
- }
- }
- }
-
- function Animation( elem, properties, options ) {
- var result,
- stopped,
- index = 0,
- length = Animation.prefilters.length,
- deferred = jQuery.Deferred().always( function() {
-
- // Don't match elem in the :animated selector
- delete tick.elem;
- } ),
- tick = function() {
- if ( stopped ) {
- return false;
- }
- var currentTime = fxNow || createFxNow(),
- remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
-
- // Support: Android 2.3
- // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
- temp = remaining / animation.duration || 0,
- percent = 1 - temp,
- index = 0,
- length = animation.tweens.length;
-
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( percent );
- }
-
- deferred.notifyWith( elem, [ animation, percent, remaining ] );
-
- if ( percent < 1 && length ) {
- return remaining;
- } else {
- deferred.resolveWith( elem, [ animation ] );
- return false;
- }
- },
- animation = deferred.promise( {
- elem: elem,
- props: jQuery.extend( {}, properties ),
- opts: jQuery.extend( true, {
- specialEasing: {},
- easing: jQuery.easing._default
- }, options ),
- originalProperties: properties,
- originalOptions: options,
- startTime: fxNow || createFxNow(),
- duration: options.duration,
- tweens: [],
- createTween: function( prop, end ) {
- var tween = jQuery.Tween( elem, animation.opts, prop, end,
- animation.opts.specialEasing[ prop ] || animation.opts.easing );
- animation.tweens.push( tween );
- return tween;
- },
- stop: function( gotoEnd ) {
- var index = 0,
-
- // If we are going to the end, we want to run all the tweens
- // otherwise we skip this part
- length = gotoEnd ? animation.tweens.length : 0;
- if ( stopped ) {
- return this;
- }
- stopped = true;
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( 1 );
- }
-
- // Resolve when we played the last frame; otherwise, reject
- if ( gotoEnd ) {
- deferred.notifyWith( elem, [ animation, 1, 0 ] );
- deferred.resolveWith( elem, [ animation, gotoEnd ] );
- } else {
- deferred.rejectWith( elem, [ animation, gotoEnd ] );
- }
- return this;
- }
- } ),
- props = animation.props;
-
- propFilter( props, animation.opts.specialEasing );
-
- for ( ; index < length ; index++ ) {
- result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
- if ( result ) {
- if ( jQuery.isFunction( result.stop ) ) {
- jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
- jQuery.proxy( result.stop, result );
- }
- return result;
- }
- }
-
- jQuery.map( props, createTween, animation );
-
- if ( jQuery.isFunction( animation.opts.start ) ) {
- animation.opts.start.call( elem, animation );
- }
-
- jQuery.fx.timer(
- jQuery.extend( tick, {
- elem: elem,
- anim: animation,
- queue: animation.opts.queue
- } )
- );
-
- // attach callbacks from options
- return animation.progress( animation.opts.progress )
- .done( animation.opts.done, animation.opts.complete )
- .fail( animation.opts.fail )
- .always( animation.opts.always );
- }
-
- jQuery.Animation = jQuery.extend( Animation, {
- tweeners: {
- "*": [ function( prop, value ) {
- var tween = this.createTween( prop, value );
- adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
- return tween;
- } ]
- },
-
- tweener: function( props, callback ) {
- if ( jQuery.isFunction( props ) ) {
- callback = props;
- props = [ "*" ];
- } else {
- props = props.match( rnotwhite );
- }
-
- var prop,
- index = 0,
- length = props.length;
-
- for ( ; index < length ; index++ ) {
- prop = props[ index ];
- Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
- Animation.tweeners[ prop ].unshift( callback );
- }
- },
-
- prefilters: [ defaultPrefilter ],
-
- prefilter: function( callback, prepend ) {
- if ( prepend ) {
- Animation.prefilters.unshift( callback );
- } else {
- Animation.prefilters.push( callback );
- }
- }
- } );
-
- jQuery.speed = function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
- opt.duration : opt.duration in jQuery.fx.speeds ?
- jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
- // Normalize opt.queue - true/undefined/null -> "fx"
- if ( opt.queue == null || opt.queue === true ) {
- opt.queue = "fx";
- }
-
- // Queueing
- opt.old = opt.complete;
-
- opt.complete = function() {
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
-
- if ( opt.queue ) {
- jQuery.dequeue( this, opt.queue );
- }
- };
-
- return opt;
- };
-
- jQuery.fn.extend( {
- fadeTo: function( speed, to, easing, callback ) {
-
- // Show any hidden elements after setting opacity to 0
- return this.filter( isHidden ).css( "opacity", 0 ).show()
-
- // Animate to the value specified
- .end().animate( { opacity: to }, speed, easing, callback );
- },
- animate: function( prop, speed, easing, callback ) {
- var empty = jQuery.isEmptyObject( prop ),
- optall = jQuery.speed( speed, easing, callback ),
- doAnimation = function() {
-
- // Operate on a copy of prop so per-property easing won't be lost
- var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
- // Empty animations, or finishing resolves immediately
- if ( empty || dataPriv.get( this, "finish" ) ) {
- anim.stop( true );
- }
- };
- doAnimation.finish = doAnimation;
-
- return empty || optall.queue === false ?
- this.each( doAnimation ) :
- this.queue( optall.queue, doAnimation );
- },
- stop: function( type, clearQueue, gotoEnd ) {
- var stopQueue = function( hooks ) {
- var stop = hooks.stop;
- delete hooks.stop;
- stop( gotoEnd );
- };
-
- if ( typeof type !== "string" ) {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if ( clearQueue && type !== false ) {
- this.queue( type || "fx", [] );
- }
-
- return this.each( function() {
- var dequeue = true,
- index = type != null && type + "queueHooks",
- timers = jQuery.timers,
- data = dataPriv.get( this );
-
- if ( index ) {
- if ( data[ index ] && data[ index ].stop ) {
- stopQueue( data[ index ] );
- }
- } else {
- for ( index in data ) {
- if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
- stopQueue( data[ index ] );
- }
- }
- }
-
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this &&
- ( type == null || timers[ index ].queue === type ) ) {
-
- timers[ index ].anim.stop( gotoEnd );
- dequeue = false;
- timers.splice( index, 1 );
- }
- }
-
- // Start the next in the queue if the last step wasn't forced.
- // Timers currently will call their complete callbacks, which
- // will dequeue but only if they were gotoEnd.
- if ( dequeue || !gotoEnd ) {
- jQuery.dequeue( this, type );
- }
- } );
- },
- finish: function( type ) {
- if ( type !== false ) {
- type = type || "fx";
- }
- return this.each( function() {
- var index,
- data = dataPriv.get( this ),
- queue = data[ type + "queue" ],
- hooks = data[ type + "queueHooks" ],
- timers = jQuery.timers,
- length = queue ? queue.length : 0;
-
- // Enable finishing flag on private data
- data.finish = true;
-
- // Empty the queue first
- jQuery.queue( this, type, [] );
-
- if ( hooks && hooks.stop ) {
- hooks.stop.call( this, true );
- }
-
- // Look for any active animations, and finish them
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
- timers[ index ].anim.stop( true );
- timers.splice( index, 1 );
- }
- }
-
- // Look for any animations in the old queue and finish them
- for ( index = 0; index < length; index++ ) {
- if ( queue[ index ] && queue[ index ].finish ) {
- queue[ index ].finish.call( this );
- }
- }
-
- // Turn off finishing flag
- delete data.finish;
- } );
- }
- } );
-
- jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
- var cssFn = jQuery.fn[ name ];
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return speed == null || typeof speed === "boolean" ?
- cssFn.apply( this, arguments ) :
- this.animate( genFx( name, true ), speed, easing, callback );
- };
- } );
-
- // Generate shortcuts for custom animations
- jQuery.each( {
- slideDown: genFx( "show" ),
- slideUp: genFx( "hide" ),
- slideToggle: genFx( "toggle" ),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
- }, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
- } );
-
- jQuery.timers = [];
- jQuery.fx.tick = function() {
- var timer,
- i = 0,
- timers = jQuery.timers;
-
- fxNow = jQuery.now();
-
- for ( ; i < timers.length; i++ ) {
- timer = timers[ i ];
-
- // Checks the timer has not already been removed
- if ( !timer() && timers[ i ] === timer ) {
- timers.splice( i--, 1 );
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- fxNow = undefined;
- };
-
- jQuery.fx.timer = function( timer ) {
- jQuery.timers.push( timer );
- if ( timer() ) {
- jQuery.fx.start();
- } else {
- jQuery.timers.pop();
- }
- };
-
- jQuery.fx.interval = 13;
- jQuery.fx.start = function() {
- if ( !timerId ) {
- timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
- }
- };
-
- jQuery.fx.stop = function() {
- window.clearInterval( timerId );
-
- timerId = null;
- };
-
- jQuery.fx.speeds = {
- slow: 600,
- fast: 200,
-
- // Default speed
- _default: 400
- };
-
-
- // Based off of the plugin by Clint Helfers, with permission.
- // http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
- jQuery.fn.delay = function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
- type = type || "fx";
-
- return this.queue( type, function( next, hooks ) {
- var timeout = window.setTimeout( next, time );
- hooks.stop = function() {
- window.clearTimeout( timeout );
- };
- } );
- };
-
-
- ( function() {
- var input = document.createElement( "input" ),
- select = document.createElement( "select" ),
- opt = select.appendChild( document.createElement( "option" ) );
-
- input.type = "checkbox";
-
- // Support: iOS<=5.1, Android<=4.2+
- // Default value for a checkbox should be "on"
- support.checkOn = input.value !== "";
-
- // Support: IE<=11+
- // Must access selectedIndex to make default options select
- support.optSelected = opt.selected;
-
- // Support: Android<=2.3
- // Options inside disabled selects are incorrectly marked as disabled
- select.disabled = true;
- support.optDisabled = !opt.disabled;
-
- // Support: IE<=11+
- // An input loses its value after becoming a radio
- input = document.createElement( "input" );
- input.value = "t";
- input.type = "radio";
- support.radioValue = input.value === "t";
- } )();
-
-
- var boolHook,
- attrHandle = jQuery.expr.attrHandle;
-
- jQuery.fn.extend( {
- attr: function( name, value ) {
- return access( this, jQuery.attr, name, value, arguments.length > 1 );
- },
-
- removeAttr: function( name ) {
- return this.each( function() {
- jQuery.removeAttr( this, name );
- } );
- }
- } );
-
- jQuery.extend( {
- attr: function( elem, name, value ) {
- var ret, hooks,
- nType = elem.nodeType;
-
- // Don't get/set attributes on text, comment and attribute nodes
- if ( nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- // Fallback to prop when attributes are not supported
- if ( typeof elem.getAttribute === "undefined" ) {
- return jQuery.prop( elem, name, value );
- }
-
- // All attributes are lowercase
- // Grab necessary hook if one is defined
- if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
- name = name.toLowerCase();
- hooks = jQuery.attrHooks[ name ] ||
- ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
- }
-
- if ( value !== undefined ) {
- if ( value === null ) {
- jQuery.removeAttr( elem, name );
- return;
- }
-
- if ( hooks && "set" in hooks &&
- ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
- return ret;
- }
-
- elem.setAttribute( name, value + "" );
- return value;
- }
-
- if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
- return ret;
- }
-
- ret = jQuery.find.attr( elem, name );
-
- // Non-existent attributes return null, we normalize to undefined
- return ret == null ? undefined : ret;
- },
-
- attrHooks: {
- type: {
- set: function( elem, value ) {
- if ( !support.radioValue && value === "radio" &&
- jQuery.nodeName( elem, "input" ) ) {
- var val = elem.value;
- elem.setAttribute( "type", value );
- if ( val ) {
- elem.value = val;
- }
- return value;
- }
- }
- }
- },
-
- removeAttr: function( elem, value ) {
- var name, propName,
- i = 0,
- attrNames = value && value.match( rnotwhite );
-
- if ( attrNames && elem.nodeType === 1 ) {
- while ( ( name = attrNames[ i++ ] ) ) {
- propName = jQuery.propFix[ name ] || name;
-
- // Boolean attributes get special treatment (#10870)
- if ( jQuery.expr.match.bool.test( name ) ) {
-
- // Set corresponding property to false
- elem[ propName ] = false;
- }
-
- elem.removeAttribute( name );
- }
- }
- }
- } );
-
- // Hooks for boolean attributes
- boolHook = {
- set: function( elem, value, name ) {
- if ( value === false ) {
-
- // Remove boolean attributes when set to false
- jQuery.removeAttr( elem, name );
- } else {
- elem.setAttribute( name, name );
- }
- return name;
- }
- };
- jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
- var getter = attrHandle[ name ] || jQuery.find.attr;
-
- attrHandle[ name ] = function( elem, name, isXML ) {
- var ret, handle;
- if ( !isXML ) {
-
- // Avoid an infinite loop by temporarily removing this function from the getter
- handle = attrHandle[ name ];
- attrHandle[ name ] = ret;
- ret = getter( elem, name, isXML ) != null ?
- name.toLowerCase() :
- null;
- attrHandle[ name ] = handle;
- }
- return ret;
- };
- } );
-
-
-
-
- var rfocusable = /^(?:input|select|textarea|button)$/i,
- rclickable = /^(?:a|area)$/i;
-
- jQuery.fn.extend( {
- prop: function( name, value ) {
- return access( this, jQuery.prop, name, value, arguments.length > 1 );
- },
-
- removeProp: function( name ) {
- return this.each( function() {
- delete this[ jQuery.propFix[ name ] || name ];
- } );
- }
- } );
-
- jQuery.extend( {
- prop: function( elem, name, value ) {
- var ret, hooks,
- nType = elem.nodeType;
-
- // Don't get/set properties on text, comment and attribute nodes
- if ( nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-
- // Fix name and attach hooks
- name = jQuery.propFix[ name ] || name;
- hooks = jQuery.propHooks[ name ];
- }
-
- if ( value !== undefined ) {
- if ( hooks && "set" in hooks &&
- ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
- return ret;
- }
-
- return ( elem[ name ] = value );
- }
-
- if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
- return ret;
- }
-
- return elem[ name ];
- },
-
- propHooks: {
- tabIndex: {
- get: function( elem ) {
-
- // elem.tabIndex doesn't always return the
- // correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- // Use proper attribute retrieval(#12072)
- var tabindex = jQuery.find.attr( elem, "tabindex" );
-
- return tabindex ?
- parseInt( tabindex, 10 ) :
- rfocusable.test( elem.nodeName ) ||
- rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- -1;
- }
- }
- },
-
- propFix: {
- "for": "htmlFor",
- "class": "className"
- }
- } );
-
- // Support: IE <=11 only
- // Accessing the selectedIndex property
- // forces the browser to respect setting selected
- // on the option
- // The getter ensures a default option is selected
- // when in an optgroup
- if ( !support.optSelected ) {
- jQuery.propHooks.selected = {
- get: function( elem ) {
- var parent = elem.parentNode;
- if ( parent && parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- return null;
- },
- set: function( elem ) {
- var parent = elem.parentNode;
- if ( parent ) {
- parent.selectedIndex;
-
- if ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
- }
- };
- }
-
- jQuery.each( [
- "tabIndex",
- "readOnly",
- "maxLength",
- "cellSpacing",
- "cellPadding",
- "rowSpan",
- "colSpan",
- "useMap",
- "frameBorder",
- "contentEditable"
- ], function() {
- jQuery.propFix[ this.toLowerCase() ] = this;
- } );
-
-
-
-
- var rclass = /[\t\r\n\f]/g;
-
- function getClass( elem ) {
- return elem.getAttribute && elem.getAttribute( "class" ) || "";
- }
-
- jQuery.fn.extend( {
- addClass: function( value ) {
- var classes, elem, cur, curValue, clazz, j, finalValue,
- i = 0;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each( function( j ) {
- jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
- } );
- }
-
- if ( typeof value === "string" && value ) {
- classes = value.match( rnotwhite ) || [];
-
- while ( ( elem = this[ i++ ] ) ) {
- curValue = getClass( elem );
- cur = elem.nodeType === 1 &&
- ( " " + curValue + " " ).replace( rclass, " " );
-
- if ( cur ) {
- j = 0;
- while ( ( clazz = classes[ j++ ] ) ) {
- if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
- cur += clazz + " ";
- }
- }
-
- // Only assign if different to avoid unneeded rendering.
- finalValue = jQuery.trim( cur );
- if ( curValue !== finalValue ) {
- elem.setAttribute( "class", finalValue );
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- var classes, elem, cur, curValue, clazz, j, finalValue,
- i = 0;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each( function( j ) {
- jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
- } );
- }
-
- if ( !arguments.length ) {
- return this.attr( "class", "" );
- }
-
- if ( typeof value === "string" && value ) {
- classes = value.match( rnotwhite ) || [];
-
- while ( ( elem = this[ i++ ] ) ) {
- curValue = getClass( elem );
-
- // This expression is here for better compressibility (see addClass)
- cur = elem.nodeType === 1 &&
- ( " " + curValue + " " ).replace( rclass, " " );
-
- if ( cur ) {
- j = 0;
- while ( ( clazz = classes[ j++ ] ) ) {
-
- // Remove *all* instances
- while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
- cur = cur.replace( " " + clazz + " ", " " );
- }
- }
-
- // Only assign if different to avoid unneeded rendering.
- finalValue = jQuery.trim( cur );
- if ( curValue !== finalValue ) {
- elem.setAttribute( "class", finalValue );
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value;
-
- if ( typeof stateVal === "boolean" && type === "string" ) {
- return stateVal ? this.addClass( value ) : this.removeClass( value );
- }
-
- if ( jQuery.isFunction( value ) ) {
- return this.each( function( i ) {
- jQuery( this ).toggleClass(
- value.call( this, i, getClass( this ), stateVal ),
- stateVal
- );
- } );
- }
-
- return this.each( function() {
- var className, i, self, classNames;
-
- if ( type === "string" ) {
-
- // Toggle individual class names
- i = 0;
- self = jQuery( this );
- classNames = value.match( rnotwhite ) || [];
-
- while ( ( className = classNames[ i++ ] ) ) {
-
- // Check each className given, space separated list
- if ( self.hasClass( className ) ) {
- self.removeClass( className );
- } else {
- self.addClass( className );
- }
- }
-
- // Toggle whole class name
- } else if ( value === undefined || type === "boolean" ) {
- className = getClass( this );
- if ( className ) {
-
- // Store className if set
- dataPriv.set( this, "__className__", className );
- }
-
- // If the element has a class name or if we're passed `false`,
- // then remove the whole classname (if there was one, the above saved it).
- // Otherwise bring back whatever was previously saved (if anything),
- // falling back to the empty string if nothing was stored.
- if ( this.setAttribute ) {
- this.setAttribute( "class",
- className || value === false ?
- "" :
- dataPriv.get( this, "__className__" ) || ""
- );
- }
- }
- } );
- },
-
- hasClass: function( selector ) {
- var className, elem,
- i = 0;
-
- className = " " + selector + " ";
- while ( ( elem = this[ i++ ] ) ) {
- if ( elem.nodeType === 1 &&
- ( " " + getClass( elem ) + " " ).replace( rclass, " " )
- .indexOf( className ) > -1
- ) {
- return true;
- }
- }
-
- return false;
- }
- } );
-
-
-
-
- var rreturn = /\r/g,
- rspaces = /[\x20\t\r\n\f]+/g;
-
- jQuery.fn.extend( {
- val: function( value ) {
- var hooks, ret, isFunction,
- elem = this[ 0 ];
-
- if ( !arguments.length ) {
- if ( elem ) {
- hooks = jQuery.valHooks[ elem.type ] ||
- jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
- if ( hooks &&
- "get" in hooks &&
- ( ret = hooks.get( elem, "value" ) ) !== undefined
- ) {
- return ret;
- }
-
- ret = elem.value;
-
- return typeof ret === "string" ?
-
- // Handle most common string cases
- ret.replace( rreturn, "" ) :
-
- // Handle cases where value is null/undef or number
- ret == null ? "" : ret;
- }
-
- return;
- }
-
- isFunction = jQuery.isFunction( value );
-
- return this.each( function( i ) {
- var val;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call( this, i, jQuery( this ).val() );
- } else {
- val = value;
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if ( val == null ) {
- val = "";
-
- } else if ( typeof val === "number" ) {
- val += "";
-
- } else if ( jQuery.isArray( val ) ) {
- val = jQuery.map( val, function( value ) {
- return value == null ? "" : value + "";
- } );
- }
-
- hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
- // If set returns undefined, fall back to normal setting
- if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
- this.value = val;
- }
- } );
- }
- } );
-
- jQuery.extend( {
- valHooks: {
- option: {
- get: function( elem ) {
-
- var val = jQuery.find.attr( elem, "value" );
- return val != null ?
- val :
-
- // Support: IE10-11+
- // option.text throws exceptions (#14686, #14858)
- // Strip and collapse whitespace
- // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
- jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
- }
- },
- select: {
- get: function( elem ) {
- var value, option,
- options = elem.options,
- index = elem.selectedIndex,
- one = elem.type === "select-one" || index < 0,
- values = one ? null : [],
- max = one ? index + 1 : options.length,
- i = index < 0 ?
- max :
- one ? index : 0;
-
- // Loop through all the selected options
- for ( ; i < max; i++ ) {
- option = options[ i ];
-
- // IE8-9 doesn't update selected after form reset (#2551)
- if ( ( option.selected || i === index ) &&
-
- // Don't return options that are disabled or in a disabled optgroup
- ( support.optDisabled ?
- !option.disabled : option.getAttribute( "disabled" ) === null ) &&
- ( !option.parentNode.disabled ||
- !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
-
- // Get the specific value for the option
- value = jQuery( option ).val();
-
- // We don't need an array for one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- },
-
- set: function( elem, value ) {
- var optionSet, option,
- options = elem.options,
- values = jQuery.makeArray( value ),
- i = options.length;
-
- while ( i-- ) {
- option = options[ i ];
- if ( option.selected =
- jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
- ) {
- optionSet = true;
- }
- }
-
- // Force browsers to behave consistently when non-matching value is set
- if ( !optionSet ) {
- elem.selectedIndex = -1;
- }
- return values;
- }
- }
- }
- } );
-
- // Radios and checkboxes getter/setter
- jQuery.each( [ "radio", "checkbox" ], function() {
- jQuery.valHooks[ this ] = {
- set: function( elem, value ) {
- if ( jQuery.isArray( value ) ) {
- return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
- }
- }
- };
- if ( !support.checkOn ) {
- jQuery.valHooks[ this ].get = function( elem ) {
- return elem.getAttribute( "value" ) === null ? "on" : elem.value;
- };
- }
- } );
-
-
-
-
- // Return jQuery for attributes-only inclusion
-
-
- var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
-
- jQuery.extend( jQuery.event, {
-
- trigger: function( event, data, elem, onlyHandlers ) {
-
- var i, cur, tmp, bubbleType, ontype, handle, special,
- eventPath = [ elem || document ],
- type = hasOwn.call( event, "type" ) ? event.type : event,
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
-
- cur = tmp = elem = elem || document;
-
- // Don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // focus/blur morphs to focusin/out; ensure we're not firing them right now
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
- return;
- }
-
- if ( type.indexOf( "." ) > -1 ) {
-
- // Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split( "." );
- type = namespaces.shift();
- namespaces.sort();
- }
- ontype = type.indexOf( ":" ) < 0 && "on" + type;
-
- // Caller can pass in a jQuery.Event object, Object, or just an event type string
- event = event[ jQuery.expando ] ?
- event :
- new jQuery.Event( type, typeof event === "object" && event );
-
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join( "." );
- event.rnamespace = event.namespace ?
- new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
- null;
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- if ( !event.target ) {
- event.target = elem;
- }
-
- // Clone any incoming data and prepend the event, creating the handler arg list
- data = data == null ?
- [ event ] :
- jQuery.makeArray( data, [ event ] );
-
- // Allow special events to draw outside the lines
- special = jQuery.event.special[ type ] || {};
- if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
- return;
- }
-
- // Determine event propagation path in advance, per W3C events spec (#9951)
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
- bubbleType = special.delegateType || type;
- if ( !rfocusMorph.test( bubbleType + type ) ) {
- cur = cur.parentNode;
- }
- for ( ; cur; cur = cur.parentNode ) {
- eventPath.push( cur );
- tmp = cur;
- }
-
- // Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( tmp === ( elem.ownerDocument || document ) ) {
- eventPath.push( tmp.defaultView || tmp.parentWindow || window );
- }
- }
-
- // Fire handlers on the event path
- i = 0;
- while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
-
- event.type = i > 1 ?
- bubbleType :
- special.bindType || type;
-
- // jQuery handler
- handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
- dataPriv.get( cur, "handle" );
- if ( handle ) {
- handle.apply( cur, data );
- }
-
- // Native handler
- handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && acceptData( cur ) ) {
- event.result = handle.apply( cur, data );
- if ( event.result === false ) {
- event.preventDefault();
- }
- }
- }
- event.type = type;
-
- // If nobody prevented the default action, do it now
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
- if ( ( !special._default ||
- special._default.apply( eventPath.pop(), data ) === false ) &&
- acceptData( elem ) ) {
-
- // Call a native DOM method on the target with the same name name as the event.
- // Don't do default actions on window, that's where global variables be (#6170)
- if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
-
- // Don't re-trigger an onFOO event when we call its FOO() method
- tmp = elem[ ontype ];
-
- if ( tmp ) {
- elem[ ontype ] = null;
- }
-
- // Prevent re-triggering of the same event, since we already bubbled it above
- jQuery.event.triggered = type;
- elem[ type ]();
- jQuery.event.triggered = undefined;
-
- if ( tmp ) {
- elem[ ontype ] = tmp;
- }
- }
- }
- }
-
- return event.result;
- },
-
- // Piggyback on a donor event to simulate a different one
- // Used only for `focus(in | out)` events
- simulate: function( type, elem, event ) {
- var e = jQuery.extend(
- new jQuery.Event(),
- event,
- {
- type: type,
- isSimulated: true
- }
- );
-
- jQuery.event.trigger( e, null, elem );
- }
-
- } );
-
- jQuery.fn.extend( {
-
- trigger: function( type, data ) {
- return this.each( function() {
- jQuery.event.trigger( type, data, this );
- } );
- },
- triggerHandler: function( type, data ) {
- var elem = this[ 0 ];
- if ( elem ) {
- return jQuery.event.trigger( type, data, elem, true );
- }
- }
- } );
-
-
- jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
- function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( data, fn ) {
- return arguments.length > 0 ?
- this.on( name, null, data, fn ) :
- this.trigger( name );
- };
- } );
-
- jQuery.fn.extend( {
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- }
- } );
-
-
-
-
- support.focusin = "onfocusin" in window;
-
-
- // Support: Firefox
- // Firefox doesn't have focus(in | out) events
- // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
- //
- // Support: Chrome, Safari
- // focus(in | out) events fire after focus & blur events,
- // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
- // Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
- if ( !support.focusin ) {
- jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
- // Attach a single capturing handler on the document while someone wants focusin/focusout
- var handler = function( event ) {
- jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
- };
-
- jQuery.event.special[ fix ] = {
- setup: function() {
- var doc = this.ownerDocument || this,
- attaches = dataPriv.access( doc, fix );
-
- if ( !attaches ) {
- doc.addEventListener( orig, handler, true );
- }
- dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
- },
- teardown: function() {
- var doc = this.ownerDocument || this,
- attaches = dataPriv.access( doc, fix ) - 1;
-
- if ( !attaches ) {
- doc.removeEventListener( orig, handler, true );
- dataPriv.remove( doc, fix );
-
- } else {
- dataPriv.access( doc, fix, attaches );
- }
- }
- };
- } );
- }
- var location = window.location;
-
- var nonce = jQuery.now();
-
- var rquery = ( /\?/ );
-
-
-
- // Support: Android 2.3
- // Workaround failure to string-cast null input
- jQuery.parseJSON = function( data ) {
- return JSON.parse( data + "" );
- };
-
-
- // Cross-browser xml parsing
- jQuery.parseXML = function( data ) {
- var xml;
- if ( !data || typeof data !== "string" ) {
- return null;
- }
-
- // Support: IE9
- try {
- xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
- } catch ( e ) {
- xml = undefined;
- }
-
- if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
- jQuery.error( "Invalid XML: " + data );
- }
- return xml;
- };
-
-
- var
- rhash = /#.*$/,
- rts = /([?&])_=[^&]*/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
-
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
-
- /* Prefilters
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
- * 2) These are called:
- * - BEFORE asking for a transport
- * - AFTER param serialization (s.data is a string if s.processData is true)
- * 3) key is the dataType
- * 4) the catchall symbol "*" can be used
- * 5) execution will start with transport dataType and THEN continue down to "*" if needed
- */
- prefilters = {},
-
- /* Transports bindings
- * 1) key is the dataType
- * 2) the catchall symbol "*" can be used
- * 3) selection will start with transport dataType and THEN go to "*" if needed
- */
- transports = {},
-
- // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
- allTypes = "*/".concat( "*" ),
-
- // Anchor tag for parsing the document origin
- originAnchor = document.createElement( "a" );
- originAnchor.href = location.href;
-
- // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
- function addToPrefiltersOrTransports( structure ) {
-
- // dataTypeExpression is optional and defaults to "*"
- return function( dataTypeExpression, func ) {
-
- if ( typeof dataTypeExpression !== "string" ) {
- func = dataTypeExpression;
- dataTypeExpression = "*";
- }
-
- var dataType,
- i = 0,
- dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
-
- if ( jQuery.isFunction( func ) ) {
-
- // For each dataType in the dataTypeExpression
- while ( ( dataType = dataTypes[ i++ ] ) ) {
-
- // Prepend if requested
- if ( dataType[ 0 ] === "+" ) {
- dataType = dataType.slice( 1 ) || "*";
- ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
-
- // Otherwise append
- } else {
- ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
- }
- }
- }
- };
- }
-
- // Base inspection function for prefilters and transports
- function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
-
- var inspected = {},
- seekingTransport = ( structure === transports );
-
- function inspect( dataType ) {
- var selected;
- inspected[ dataType ] = true;
- jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
- var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
- if ( typeof dataTypeOrTransport === "string" &&
- !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
-
- options.dataTypes.unshift( dataTypeOrTransport );
- inspect( dataTypeOrTransport );
- return false;
- } else if ( seekingTransport ) {
- return !( selected = dataTypeOrTransport );
- }
- } );
- return selected;
- }
-
- return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
- }
-
- // A special extend for ajax options
- // that takes "flat" options (not to be deep extended)
- // Fixes #9887
- function ajaxExtend( target, src ) {
- var key, deep,
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
- for ( key in src ) {
- if ( src[ key ] !== undefined ) {
- ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
- }
- }
- if ( deep ) {
- jQuery.extend( true, target, deep );
- }
-
- return target;
- }
-
- /* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
- function ajaxHandleResponses( s, jqXHR, responses ) {
-
- var ct, type, finalDataType, firstDataType,
- contents = s.contents,
- dataTypes = s.dataTypes;
-
- // Remove auto dataType and get content-type in the process
- while ( dataTypes[ 0 ] === "*" ) {
- dataTypes.shift();
- if ( ct === undefined ) {
- ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
- }
- }
-
- // Check if we're dealing with a known content-type
- if ( ct ) {
- for ( type in contents ) {
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
- dataTypes.unshift( type );
- break;
- }
- }
- }
-
- // Check to see if we have a response for the expected dataType
- if ( dataTypes[ 0 ] in responses ) {
- finalDataType = dataTypes[ 0 ];
- } else {
-
- // Try convertible dataTypes
- for ( type in responses ) {
- if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
- finalDataType = type;
- break;
- }
- if ( !firstDataType ) {
- firstDataType = type;
- }
- }
-
- // Or just use first one
- finalDataType = finalDataType || firstDataType;
- }
-
- // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if ( finalDataType ) {
- if ( finalDataType !== dataTypes[ 0 ] ) {
- dataTypes.unshift( finalDataType );
- }
- return responses[ finalDataType ];
- }
- }
-
- /* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
- function ajaxConvert( s, response, jqXHR, isSuccess ) {
- var conv2, current, conv, tmp, prev,
- converters = {},
-
- // Work with a copy of dataTypes in case we need to modify it for conversion
- dataTypes = s.dataTypes.slice();
-
- // Create converters map with lowercased keys
- if ( dataTypes[ 1 ] ) {
- for ( conv in s.converters ) {
- converters[ conv.toLowerCase() ] = s.converters[ conv ];
- }
- }
-
- current = dataTypes.shift();
-
- // Convert to each sequential dataType
- while ( current ) {
-
- if ( s.responseFields[ current ] ) {
- jqXHR[ s.responseFields[ current ] ] = response;
- }
-
- // Apply the dataFilter if provided
- if ( !prev && isSuccess && s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
-
- prev = current;
- current = dataTypes.shift();
-
- if ( current ) {
-
- // There's only work to do if current dataType is non-auto
- if ( current === "*" ) {
-
- current = prev;
-
- // Convert response if prev dataType is non-auto and differs from current
- } else if ( prev !== "*" && prev !== current ) {
-
- // Seek a direct converter
- conv = converters[ prev + " " + current ] || converters[ "* " + current ];
-
- // If none found, seek a pair
- if ( !conv ) {
- for ( conv2 in converters ) {
-
- // If conv2 outputs current
- tmp = conv2.split( " " );
- if ( tmp[ 1 ] === current ) {
-
- // If prev can be converted to accepted input
- conv = converters[ prev + " " + tmp[ 0 ] ] ||
- converters[ "* " + tmp[ 0 ] ];
- if ( conv ) {
-
- // Condense equivalence converters
- if ( conv === true ) {
- conv = converters[ conv2 ];
-
- // Otherwise, insert the intermediate dataType
- } else if ( converters[ conv2 ] !== true ) {
- current = tmp[ 0 ];
- dataTypes.unshift( tmp[ 1 ] );
- }
- break;
- }
- }
- }
- }
-
- // Apply converter (if not an equivalence)
- if ( conv !== true ) {
-
- // Unless errors are allowed to bubble, catch and return them
- if ( conv && s.throws ) {
- response = conv( response );
- } else {
- try {
- response = conv( response );
- } catch ( e ) {
- return {
- state: "parsererror",
- error: conv ? e : "No conversion from " + prev + " to " + current
- };
- }
- }
- }
- }
- }
- }
-
- return { state: "success", data: response };
- }
-
- jQuery.extend( {
-
- // Counter for holding the number of active queries
- active: 0,
-
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {},
-
- ajaxSettings: {
- url: location.href,
- type: "GET",
- isLocal: rlocalProtocol.test( location.protocol ),
- global: true,
- processData: true,
- async: true,
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
- /*
- timeout: 0,
- data: null,
- dataType: null,
- username: null,
- password: null,
- cache: null,
- throws: false,
- traditional: false,
- headers: {},
- */
-
- accepts: {
- "*": allTypes,
- text: "text/plain",
- html: "text/html",
- xml: "application/xml, text/xml",
- json: "application/json, text/javascript"
- },
-
- contents: {
- xml: /\bxml\b/,
- html: /\bhtml/,
- json: /\bjson\b/
- },
-
- responseFields: {
- xml: "responseXML",
- text: "responseText",
- json: "responseJSON"
- },
-
- // Data converters
- // Keys separate source (or catchall "*") and destination types with a single space
- converters: {
-
- // Convert anything to text
- "* text": String,
-
- // Text to html (true = no transformation)
- "text html": true,
-
- // Evaluate text as a json expression
- "text json": jQuery.parseJSON,
-
- // Parse text as xml
- "text xml": jQuery.parseXML
- },
-
- // For options that shouldn't be deep extended:
- // you can add your own custom options here if
- // and when you create one that shouldn't be
- // deep extended (see ajaxExtend)
- flatOptions: {
- url: true,
- context: true
- }
- },
-
- // Creates a full fledged settings object into target
- // with both ajaxSettings and settings fields.
- // If target is omitted, writes into ajaxSettings.
- ajaxSetup: function( target, settings ) {
- return settings ?
-
- // Building a settings object
- ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
-
- // Extending ajaxSettings
- ajaxExtend( jQuery.ajaxSettings, target );
- },
-
- ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
- ajaxTransport: addToPrefiltersOrTransports( transports ),
-
- // Main method
- ajax: function( url, options ) {
-
- // If url is an object, simulate pre-1.5 signature
- if ( typeof url === "object" ) {
- options = url;
- url = undefined;
- }
-
- // Force options to be an object
- options = options || {};
-
- var transport,
-
- // URL without anti-cache param
- cacheURL,
-
- // Response headers
- responseHeadersString,
- responseHeaders,
-
- // timeout handle
- timeoutTimer,
-
- // Url cleanup var
- urlAnchor,
-
- // To know if global events are to be dispatched
- fireGlobals,
-
- // Loop variable
- i,
-
- // Create the final options object
- s = jQuery.ajaxSetup( {}, options ),
-
- // Callbacks context
- callbackContext = s.context || s,
-
- // Context for global events is callbackContext if it is a DOM node or jQuery collection
- globalEventContext = s.context &&
- ( callbackContext.nodeType || callbackContext.jquery ) ?
- jQuery( callbackContext ) :
- jQuery.event,
-
- // Deferreds
- deferred = jQuery.Deferred(),
- completeDeferred = jQuery.Callbacks( "once memory" ),
-
- // Status-dependent callbacks
- statusCode = s.statusCode || {},
-
- // Headers (they are sent all at once)
- requestHeaders = {},
- requestHeadersNames = {},
-
- // The jqXHR state
- state = 0,
-
- // Default abort message
- strAbort = "canceled",
-
- // Fake xhr
- jqXHR = {
- readyState: 0,
-
- // Builds headers hashtable if needed
- getResponseHeader: function( key ) {
- var match;
- if ( state === 2 ) {
- if ( !responseHeaders ) {
- responseHeaders = {};
- while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
- responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
- }
- }
- match = responseHeaders[ key.toLowerCase() ];
- }
- return match == null ? null : match;
- },
-
- // Raw string
- getAllResponseHeaders: function() {
- return state === 2 ? responseHeadersString : null;
- },
-
- // Caches the header
- setRequestHeader: function( name, value ) {
- var lname = name.toLowerCase();
- if ( !state ) {
- name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
- requestHeaders[ name ] = value;
- }
- return this;
- },
-
- // Overrides response content-type header
- overrideMimeType: function( type ) {
- if ( !state ) {
- s.mimeType = type;
- }
- return this;
- },
-
- // Status-dependent callbacks
- statusCode: function( map ) {
- var code;
- if ( map ) {
- if ( state < 2 ) {
- for ( code in map ) {
-
- // Lazy-add the new callback in a way that preserves old ones
- statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
- }
- } else {
-
- // Execute the appropriate callbacks
- jqXHR.always( map[ jqXHR.status ] );
- }
- }
- return this;
- },
-
- // Cancel the request
- abort: function( statusText ) {
- var finalText = statusText || strAbort;
- if ( transport ) {
- transport.abort( finalText );
- }
- done( 0, finalText );
- return this;
- }
- };
-
- // Attach deferreds
- deferred.promise( jqXHR ).complete = completeDeferred.add;
- jqXHR.success = jqXHR.done;
- jqXHR.error = jqXHR.fail;
-
- // Remove hash character (#7531: and string promotion)
- // Add protocol if not provided (prefilters might expect it)
- // Handle falsy url in the settings object (#10093: consistency with old signature)
- // We also use the url parameter if available
- s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
- .replace( rprotocol, location.protocol + "//" );
-
- // Alias method option to type as per ticket #12004
- s.type = options.method || options.type || s.method || s.type;
-
- // Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
-
- // A cross-domain request is in order when the origin doesn't match the current origin.
- if ( s.crossDomain == null ) {
- urlAnchor = document.createElement( "a" );
-
- // Support: IE8-11+
- // IE throws exception if url is malformed, e.g. http://example.com:80x/
- try {
- urlAnchor.href = s.url;
-
- // Support: IE8-11+
- // Anchor's host property isn't correctly set when s.url is relative
- urlAnchor.href = urlAnchor.href;
- s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
- urlAnchor.protocol + "//" + urlAnchor.host;
- } catch ( e ) {
-
- // If there is an error parsing the URL, assume it is crossDomain,
- // it can be rejected by the transport if it is invalid
- s.crossDomain = true;
- }
- }
-
- // Convert data if not already a string
- if ( s.data && s.processData && typeof s.data !== "string" ) {
- s.data = jQuery.param( s.data, s.traditional );
- }
-
- // Apply prefilters
- inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
- // If request was aborted inside a prefilter, stop there
- if ( state === 2 ) {
- return jqXHR;
- }
-
- // We can fire global events as of now if asked to
- // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
- fireGlobals = jQuery.event && s.global;
-
- // Watch for a new set of requests
- if ( fireGlobals && jQuery.active++ === 0 ) {
- jQuery.event.trigger( "ajaxStart" );
- }
-
- // Uppercase the type
- s.type = s.type.toUpperCase();
-
- // Determine if request has content
- s.hasContent = !rnoContent.test( s.type );
-
- // Save the URL in case we're toying with the If-Modified-Since
- // and/or If-None-Match header later on
- cacheURL = s.url;
-
- // More options handling for requests with no content
- if ( !s.hasContent ) {
-
- // If data is available, append data to url
- if ( s.data ) {
- cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
-
- // #9682: remove data so that it's not used in an eventual retry
- delete s.data;
- }
-
- // Add anti-cache in url if needed
- if ( s.cache === false ) {
- s.url = rts.test( cacheURL ) ?
-
- // If there is already a '_' parameter, set its value
- cacheURL.replace( rts, "$1_=" + nonce++ ) :
-
- // Otherwise add one to the end
- cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
- }
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- if ( jQuery.lastModified[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
- }
- if ( jQuery.etag[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
- }
- }
-
- // Set the correct header, if data is being sent
- if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
- jqXHR.setRequestHeader( "Content-Type", s.contentType );
- }
-
- // Set the Accepts header for the server, depending on the dataType
- jqXHR.setRequestHeader(
- "Accept",
- s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
- s.accepts[ s.dataTypes[ 0 ] ] +
- ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
- s.accepts[ "*" ]
- );
-
- // Check for headers option
- for ( i in s.headers ) {
- jqXHR.setRequestHeader( i, s.headers[ i ] );
- }
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend &&
- ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
-
- // Abort if not done already and return
- return jqXHR.abort();
- }
-
- // Aborting is no longer a cancellation
- strAbort = "abort";
-
- // Install callbacks on deferreds
- for ( i in { success: 1, error: 1, complete: 1 } ) {
- jqXHR[ i ]( s[ i ] );
- }
-
- // Get transport
- transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
- // If no transport, we auto-abort
- if ( !transport ) {
- done( -1, "No Transport" );
- } else {
- jqXHR.readyState = 1;
-
- // Send global event
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
- }
-
- // If request was aborted inside ajaxSend, stop there
- if ( state === 2 ) {
- return jqXHR;
- }
-
- // Timeout
- if ( s.async && s.timeout > 0 ) {
- timeoutTimer = window.setTimeout( function() {
- jqXHR.abort( "timeout" );
- }, s.timeout );
- }
-
- try {
- state = 1;
- transport.send( requestHeaders, done );
- } catch ( e ) {
-
- // Propagate exception as error if not done
- if ( state < 2 ) {
- done( -1, e );
-
- // Simply rethrow otherwise
- } else {
- throw e;
- }
- }
- }
-
- // Callback for when everything is done
- function done( status, nativeStatusText, responses, headers ) {
- var isSuccess, success, error, response, modified,
- statusText = nativeStatusText;
-
- // Called once
- if ( state === 2 ) {
- return;
- }
-
- // State is "done" now
- state = 2;
-
- // Clear timeout if it exists
- if ( timeoutTimer ) {
- window.clearTimeout( timeoutTimer );
- }
-
- // Dereference transport for early garbage collection
- // (no matter how long the jqXHR object will be used)
- transport = undefined;
-
- // Cache response headers
- responseHeadersString = headers || "";
-
- // Set readyState
- jqXHR.readyState = status > 0 ? 4 : 0;
-
- // Determine if successful
- isSuccess = status >= 200 && status < 300 || status === 304;
-
- // Get response data
- if ( responses ) {
- response = ajaxHandleResponses( s, jqXHR, responses );
- }
-
- // Convert no matter what (that way responseXXX fields are always set)
- response = ajaxConvert( s, response, jqXHR, isSuccess );
-
- // If successful, handle type chaining
- if ( isSuccess ) {
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- modified = jqXHR.getResponseHeader( "Last-Modified" );
- if ( modified ) {
- jQuery.lastModified[ cacheURL ] = modified;
- }
- modified = jqXHR.getResponseHeader( "etag" );
- if ( modified ) {
- jQuery.etag[ cacheURL ] = modified;
- }
- }
-
- // if no content
- if ( status === 204 || s.type === "HEAD" ) {
- statusText = "nocontent";
-
- // if not modified
- } else if ( status === 304 ) {
- statusText = "notmodified";
-
- // If we have data, let's convert it
- } else {
- statusText = response.state;
- success = response.data;
- error = response.error;
- isSuccess = !error;
- }
- } else {
-
- // Extract error from statusText and normalize for non-aborts
- error = statusText;
- if ( status || !statusText ) {
- statusText = "error";
- if ( status < 0 ) {
- status = 0;
- }
- }
- }
-
- // Set data for the fake xhr object
- jqXHR.status = status;
- jqXHR.statusText = ( nativeStatusText || statusText ) + "";
-
- // Success/Error
- if ( isSuccess ) {
- deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
- } else {
- deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
- }
-
- // Status-dependent callbacks
- jqXHR.statusCode( statusCode );
- statusCode = undefined;
-
- if ( fireGlobals ) {
- globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
- [ jqXHR, s, isSuccess ? success : error ] );
- }
-
- // Complete
- completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
-
- // Handle the global AJAX counter
- if ( !( --jQuery.active ) ) {
- jQuery.event.trigger( "ajaxStop" );
- }
- }
- }
-
- return jqXHR;
- },
-
- getJSON: function( url, data, callback ) {
- return jQuery.get( url, data, callback, "json" );
- },
-
- getScript: function( url, callback ) {
- return jQuery.get( url, undefined, callback, "script" );
- }
- } );
-
- jQuery.each( [ "get", "post" ], function( i, method ) {
- jQuery[ method ] = function( url, data, callback, type ) {
-
- // Shift arguments if data argument was omitted
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = undefined;
- }
-
- // The url can be an options object (which then must have .url)
- return jQuery.ajax( jQuery.extend( {
- url: url,
- type: method,
- dataType: type,
- data: data,
- success: callback
- }, jQuery.isPlainObject( url ) && url ) );
- };
- } );
-
-
- jQuery._evalUrl = function( url ) {
- return jQuery.ajax( {
- url: url,
-
- // Make this explicit, since user can override this through ajaxSetup (#11264)
- type: "GET",
- dataType: "script",
- async: false,
- global: false,
- "throws": true
- } );
- };
-
-
- jQuery.fn.extend( {
- wrapAll: function( html ) {
- var wrap;
-
- if ( jQuery.isFunction( html ) ) {
- return this.each( function( i ) {
- jQuery( this ).wrapAll( html.call( this, i ) );
- } );
- }
-
- if ( this[ 0 ] ) {
-
- // The elements to wrap the target around
- wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
-
- if ( this[ 0 ].parentNode ) {
- wrap.insertBefore( this[ 0 ] );
- }
-
- wrap.map( function() {
- var elem = this;
-
- while ( elem.firstElementChild ) {
- elem = elem.firstElementChild;
- }
-
- return elem;
- } ).append( this );
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each( function( i ) {
- jQuery( this ).wrapInner( html.call( this, i ) );
- } );
- }
-
- return this.each( function() {
- var self = jQuery( this ),
- contents = self.contents();
-
- if ( contents.length ) {
- contents.wrapAll( html );
-
- } else {
- self.append( html );
- }
- } );
- },
-
- wrap: function( html ) {
- var isFunction = jQuery.isFunction( html );
-
- return this.each( function( i ) {
- jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
- } );
- },
-
- unwrap: function() {
- return this.parent().each( function() {
- if ( !jQuery.nodeName( this, "body" ) ) {
- jQuery( this ).replaceWith( this.childNodes );
- }
- } ).end();
- }
- } );
-
-
- jQuery.expr.filters.hidden = function( elem ) {
- return !jQuery.expr.filters.visible( elem );
- };
- jQuery.expr.filters.visible = function( elem ) {
-
- // Support: Opera <= 12.12
- // Opera reports offsetWidths and offsetHeights less than zero on some elements
- // Use OR instead of AND as the element is not visible if either is true
- // See tickets #10406 and #13132
- return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
- };
-
-
-
-
- var r20 = /%20/g,
- rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
- rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
- function buildParams( prefix, obj, traditional, add ) {
- var name;
-
- if ( jQuery.isArray( obj ) ) {
-
- // Serialize array item.
- jQuery.each( obj, function( i, v ) {
- if ( traditional || rbracket.test( prefix ) ) {
-
- // Treat each array item as a scalar.
- add( prefix, v );
-
- } else {
-
- // Item is non-scalar (array or object), encode its numeric index.
- buildParams(
- prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
- v,
- traditional,
- add
- );
- }
- } );
-
- } else if ( !traditional && jQuery.type( obj ) === "object" ) {
-
- // Serialize object item.
- for ( name in obj ) {
- buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
- }
-
- } else {
-
- // Serialize scalar item.
- add( prefix, obj );
- }
- }
-
- // Serialize an array of form elements or a set of
- // key/values into a query string
- jQuery.param = function( a, traditional ) {
- var prefix,
- s = [],
- add = function( key, value ) {
-
- // If value is a function, invoke it and return its value
- value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
- s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
- };
-
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
- }
-
- // If an array was passed in, assume that it is an array of form elements.
- if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-
- // Serialize the form elements
- jQuery.each( a, function() {
- add( this.name, this.value );
- } );
-
- } else {
-
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for ( prefix in a ) {
- buildParams( prefix, a[ prefix ], traditional, add );
- }
- }
-
- // Return the resulting serialization
- return s.join( "&" ).replace( r20, "+" );
- };
-
- jQuery.fn.extend( {
- serialize: function() {
- return jQuery.param( this.serializeArray() );
- },
- serializeArray: function() {
- return this.map( function() {
-
- // Can add propHook for "elements" to filter or add form elements
- var elements = jQuery.prop( this, "elements" );
- return elements ? jQuery.makeArray( elements ) : this;
- } )
- .filter( function() {
- var type = this.type;
-
- // Use .is( ":disabled" ) so that fieldset[disabled] works
- return this.name && !jQuery( this ).is( ":disabled" ) &&
- rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
- ( this.checked || !rcheckableType.test( type ) );
- } )
- .map( function( i, elem ) {
- var val = jQuery( this ).val();
-
- return val == null ?
- null :
- jQuery.isArray( val ) ?
- jQuery.map( val, function( val ) {
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- } ) :
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- } ).get();
- }
- } );
-
-
- jQuery.ajaxSettings.xhr = function() {
- try {
- return new window.XMLHttpRequest();
- } catch ( e ) {}
- };
-
- var xhrSuccessStatus = {
-
- // File protocol always yields status code 0, assume 200
- 0: 200,
-
- // Support: IE9
- // #1450: sometimes IE returns 1223 when it should be 204
- 1223: 204
- },
- xhrSupported = jQuery.ajaxSettings.xhr();
-
- support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
- support.ajax = xhrSupported = !!xhrSupported;
-
- jQuery.ajaxTransport( function( options ) {
- var callback, errorCallback;
-
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( support.cors || xhrSupported && !options.crossDomain ) {
- return {
- send: function( headers, complete ) {
- var i,
- xhr = options.xhr();
-
- xhr.open(
- options.type,
- options.url,
- options.async,
- options.username,
- options.password
- );
-
- // Apply custom fields if provided
- if ( options.xhrFields ) {
- for ( i in options.xhrFields ) {
- xhr[ i ] = options.xhrFields[ i ];
- }
- }
-
- // Override mime type if needed
- if ( options.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( options.mimeType );
- }
-
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
- headers[ "X-Requested-With" ] = "XMLHttpRequest";
- }
-
- // Set headers
- for ( i in headers ) {
- xhr.setRequestHeader( i, headers[ i ] );
- }
-
- // Callback
- callback = function( type ) {
- return function() {
- if ( callback ) {
- callback = errorCallback = xhr.onload =
- xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
-
- if ( type === "abort" ) {
- xhr.abort();
- } else if ( type === "error" ) {
-
- // Support: IE9
- // On a manual native abort, IE9 throws
- // errors on any property access that is not readyState
- if ( typeof xhr.status !== "number" ) {
- complete( 0, "error" );
- } else {
- complete(
-
- // File: protocol always yields status 0; see #8605, #14207
- xhr.status,
- xhr.statusText
- );
- }
- } else {
- complete(
- xhrSuccessStatus[ xhr.status ] || xhr.status,
- xhr.statusText,
-
- // Support: IE9 only
- // IE9 has no XHR2 but throws on binary (trac-11426)
- // For XHR2 non-text, let the caller handle it (gh-2498)
- ( xhr.responseType || "text" ) !== "text" ||
- typeof xhr.responseText !== "string" ?
- { binary: xhr.response } :
- { text: xhr.responseText },
- xhr.getAllResponseHeaders()
- );
- }
- }
- };
- };
-
- // Listen to events
- xhr.onload = callback();
- errorCallback = xhr.onerror = callback( "error" );
-
- // Support: IE9
- // Use onreadystatechange to replace onabort
- // to handle uncaught aborts
- if ( xhr.onabort !== undefined ) {
- xhr.onabort = errorCallback;
- } else {
- xhr.onreadystatechange = function() {
-
- // Check readyState before timeout as it changes
- if ( xhr.readyState === 4 ) {
-
- // Allow onerror to be called first,
- // but that will not handle a native abort
- // Also, save errorCallback to a variable
- // as xhr.onerror cannot be accessed
- window.setTimeout( function() {
- if ( callback ) {
- errorCallback();
- }
- } );
- }
- };
- }
-
- // Create the abort callback
- callback = callback( "abort" );
-
- try {
-
- // Do send the request (this may raise an exception)
- xhr.send( options.hasContent && options.data || null );
- } catch ( e ) {
-
- // #14683: Only rethrow if this hasn't been notified as an error yet
- if ( callback ) {
- throw e;
- }
- }
- },
-
- abort: function() {
- if ( callback ) {
- callback();
- }
- }
- };
- }
- } );
-
-
-
-
- // Install script dataType
- jQuery.ajaxSetup( {
- accepts: {
- script: "text/javascript, application/javascript, " +
- "application/ecmascript, application/x-ecmascript"
- },
- contents: {
- script: /\b(?:java|ecma)script\b/
- },
- converters: {
- "text script": function( text ) {
- jQuery.globalEval( text );
- return text;
- }
- }
- } );
-
- // Handle cache's special case and crossDomain
- jQuery.ajaxPrefilter( "script", function( s ) {
- if ( s.cache === undefined ) {
- s.cache = false;
- }
- if ( s.crossDomain ) {
- s.type = "GET";
- }
- } );
-
- // Bind script tag hack transport
- jQuery.ajaxTransport( "script", function( s ) {
-
- // This transport only deals with cross domain requests
- if ( s.crossDomain ) {
- var script, callback;
- return {
- send: function( _, complete ) {
- script = jQuery( "<script>" ).prop( {
- charset: s.scriptCharset,
- src: s.url
- } ).on(
- "load error",
- callback = function( evt ) {
- script.remove();
- callback = null;
- if ( evt ) {
- complete( evt.type === "error" ? 404 : 200, evt.type );
- }
- }
- );
-
- // Use native DOM manipulation to avoid our domManip AJAX trickery
- document.head.appendChild( script[ 0 ] );
- },
- abort: function() {
- if ( callback ) {
- callback();
- }
- }
- };
- }
- } );
-
-
-
-
- var oldCallbacks = [],
- rjsonp = /(=)\?(?=&|$)|\?\?/;
-
- // Default jsonp settings
- jQuery.ajaxSetup( {
- jsonp: "callback",
- jsonpCallback: function() {
- var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
- this[ callback ] = true;
- return callback;
- }
- } );
-
- // Detect, normalize options and install callbacks for jsonp requests
- jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
- var callbackName, overwritten, responseContainer,
- jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
- "url" :
- typeof s.data === "string" &&
- ( s.contentType || "" )
- .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
- rjsonp.test( s.data ) && "data"
- );
-
- // Handle iff the expected data type is "jsonp" or we have a parameter to set
- if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
- // Get callback name, remembering preexisting value associated with it
- callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
- s.jsonpCallback() :
- s.jsonpCallback;
-
- // Insert callback into url or form data
- if ( jsonProp ) {
- s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
- } else if ( s.jsonp !== false ) {
- s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
- }
-
- // Use data converter to retrieve json after script execution
- s.converters[ "script json" ] = function() {
- if ( !responseContainer ) {
- jQuery.error( callbackName + " was not called" );
- }
- return responseContainer[ 0 ];
- };
-
- // Force json dataType
- s.dataTypes[ 0 ] = "json";
-
- // Install callback
- overwritten = window[ callbackName ];
- window[ callbackName ] = function() {
- responseContainer = arguments;
- };
-
- // Clean-up function (fires after converters)
- jqXHR.always( function() {
-
- // If previous value didn't exist - remove it
- if ( overwritten === undefined ) {
- jQuery( window ).removeProp( callbackName );
-
- // Otherwise restore preexisting value
- } else {
- window[ callbackName ] = overwritten;
- }
-
- // Save back as free
- if ( s[ callbackName ] ) {
-
- // Make sure that re-using the options doesn't screw things around
- s.jsonpCallback = originalSettings.jsonpCallback;
-
- // Save the callback name for future use
- oldCallbacks.push( callbackName );
- }
-
- // Call if it was a function and we have a response
- if ( responseContainer && jQuery.isFunction( overwritten ) ) {
- overwritten( responseContainer[ 0 ] );
- }
-
- responseContainer = overwritten = undefined;
- } );
-
- // Delegate to script
- return "script";
- }
- } );
-
-
-
-
- // Argument "data" should be string of html
- // context (optional): If specified, the fragment will be created in this context,
- // defaults to document
- // keepScripts (optional): If true, will include scripts passed in the html string
- jQuery.parseHTML = function( data, context, keepScripts ) {
- if ( !data || typeof data !== "string" ) {
- return null;
- }
- if ( typeof context === "boolean" ) {
- keepScripts = context;
- context = false;
- }
- context = context || document;
-
- var parsed = rsingleTag.exec( data ),
- scripts = !keepScripts && [];
-
- // Single tag
- if ( parsed ) {
- return [ context.createElement( parsed[ 1 ] ) ];
- }
-
- parsed = buildFragment( [ data ], context, scripts );
-
- if ( scripts && scripts.length ) {
- jQuery( scripts ).remove();
- }
-
- return jQuery.merge( [], parsed.childNodes );
- };
-
-
- // Keep a copy of the old load method
- var _load = jQuery.fn.load;
-
- /**
- * Load a url into a page
- */
- jQuery.fn.load = function( url, params, callback ) {
- if ( typeof url !== "string" && _load ) {
- return _load.apply( this, arguments );
- }
-
- var selector, type, response,
- self = this,
- off = url.indexOf( " " );
-
- if ( off > -1 ) {
- selector = jQuery.trim( url.slice( off ) );
- url = url.slice( 0, off );
- }
-
- // If it's a function
- if ( jQuery.isFunction( params ) ) {
-
- // We assume that it's the callback
- callback = params;
- params = undefined;
-
- // Otherwise, build a param string
- } else if ( params && typeof params === "object" ) {
- type = "POST";
- }
-
- // If we have elements to modify, make the request
- if ( self.length > 0 ) {
- jQuery.ajax( {
- url: url,
-
- // If "type" variable is undefined, then "GET" method will be used.
- // Make value of this field explicit since
- // user can override it through ajaxSetup method
- type: type || "GET",
- dataType: "html",
- data: params
- } ).done( function( responseText ) {
-
- // Save response for use in complete callback
- response = arguments;
-
- self.html( selector ?
-
- // If a selector was specified, locate the right elements in a dummy div
- // Exclude scripts to avoid IE 'Permission Denied' errors
- jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
- // Otherwise use the full result
- responseText );
-
- // If the request succeeds, this function gets "data", "status", "jqXHR"
- // but they are ignored because response was set above.
- // If it fails, this function gets "jqXHR", "status", "error"
- } ).always( callback && function( jqXHR, status ) {
- self.each( function() {
- callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
- } );
- } );
- }
-
- return this;
- };
-
-
-
-
- // Attach a bunch of functions for handling common AJAX events
- jQuery.each( [
- "ajaxStart",
- "ajaxStop",
- "ajaxComplete",
- "ajaxError",
- "ajaxSuccess",
- "ajaxSend"
- ], function( i, type ) {
- jQuery.fn[ type ] = function( fn ) {
- return this.on( type, fn );
- };
- } );
-
-
-
-
- jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep( jQuery.timers, function( fn ) {
- return elem === fn.elem;
- } ).length;
- };
-
-
-
-
- /**
- * Gets a window from an element
- */
- function getWindow( elem ) {
- return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
- }
-
- jQuery.offset = {
- setOffset: function( elem, options, i ) {
- var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
- position = jQuery.css( elem, "position" ),
- curElem = jQuery( elem ),
- props = {};
-
- // Set position first, in-case top/left are set even on static elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- curOffset = curElem.offset();
- curCSSTop = jQuery.css( elem, "top" );
- curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position === "fixed" ) &&
- ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
-
- // Need to be able to calculate position if either
- // top or left is auto and position is either absolute or fixed
- if ( calculatePosition ) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
-
- } else {
- curTop = parseFloat( curCSSTop ) || 0;
- curLeft = parseFloat( curCSSLeft ) || 0;
- }
-
- if ( jQuery.isFunction( options ) ) {
-
- // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
- options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
- }
-
- if ( options.top != null ) {
- props.top = ( options.top - curOffset.top ) + curTop;
- }
- if ( options.left != null ) {
- props.left = ( options.left - curOffset.left ) + curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
-
- } else {
- curElem.css( props );
- }
- }
- };
-
- jQuery.fn.extend( {
- offset: function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each( function( i ) {
- jQuery.offset.setOffset( this, options, i );
- } );
- }
-
- var docElem, win,
- elem = this[ 0 ],
- box = { top: 0, left: 0 },
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return;
- }
-
- docElem = doc.documentElement;
-
- // Make sure it's not a disconnected DOM node
- if ( !jQuery.contains( docElem, elem ) ) {
- return box;
- }
-
- box = elem.getBoundingClientRect();
- win = getWindow( doc );
- return {
- top: box.top + win.pageYOffset - docElem.clientTop,
- left: box.left + win.pageXOffset - docElem.clientLeft
- };
- },
-
- position: function() {
- if ( !this[ 0 ] ) {
- return;
- }
-
- var offsetParent, offset,
- elem = this[ 0 ],
- parentOffset = { top: 0, left: 0 };
-
- // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
- // because it is its only offset parent
- if ( jQuery.css( elem, "position" ) === "fixed" ) {
-
- // Assume getBoundingClientRect is there when computed position is fixed
- offset = elem.getBoundingClientRect();
-
- } else {
-
- // Get *real* offsetParent
- offsetParent = this.offsetParent();
-
- // Get correct offsets
- offset = this.offset();
- if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
- parentOffset = offsetParent.offset();
- }
-
- // Add offsetParent borders
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
- parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
- }
-
- // Subtract parent offsets and element margins
- return {
- top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
- left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
- };
- },
-
- // This method will return documentElement in the following cases:
- // 1) For the element inside the iframe without offsetParent, this method will return
- // documentElement of the parent window
- // 2) For the hidden or detached element
- // 3) For body or html element, i.e. in case of the html node - it will return itself
- //
- // but those exceptions were never presented as a real life use-cases
- // and might be considered as more preferable results.
- //
- // This logic, however, is not guaranteed and can change at any point in the future
- offsetParent: function() {
- return this.map( function() {
- var offsetParent = this.offsetParent;
-
- while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
- offsetParent = offsetParent.offsetParent;
- }
-
- return offsetParent || documentElement;
- } );
- }
- } );
-
- // Create scrollLeft and scrollTop methods
- jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
- var top = "pageYOffset" === prop;
-
- jQuery.fn[ method ] = function( val ) {
- return access( this, function( elem, method, val ) {
- var win = getWindow( elem );
-
- if ( val === undefined ) {
- return win ? win[ prop ] : elem[ method ];
- }
-
- if ( win ) {
- win.scrollTo(
- !top ? val : win.pageXOffset,
- top ? val : win.pageYOffset
- );
-
- } else {
- elem[ method ] = val;
- }
- }, method, val, arguments.length );
- };
- } );
-
- // Support: Safari<7-8+, Chrome<37-44+
- // Add the top/left cssHooks using jQuery.fn.position
- // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
- // Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
- // getComputedStyle returns percent when specified for top/left/bottom/right;
- // rather than make the css module depend on the offset module, just check for it here
- jQuery.each( [ "top", "left" ], function( i, prop ) {
- jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
- function( elem, computed ) {
- if ( computed ) {
- computed = curCSS( elem, prop );
-
- // If curCSS returns percentage, fallback to offset
- return rnumnonpx.test( computed ) ?
- jQuery( elem ).position()[ prop ] + "px" :
- computed;
- }
- }
- );
- } );
-
-
- // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
- jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
- jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
- function( defaultExtra, funcName ) {
-
- // Margin is only for outerHeight, outerWidth
- jQuery.fn[ funcName ] = function( margin, value ) {
- var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
- extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
- return access( this, function( elem, type, value ) {
- var doc;
-
- if ( jQuery.isWindow( elem ) ) {
-
- // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
- // isn't a whole lot we can do. See pull request at this URL for discussion:
- // https://github.com/jquery/jquery/pull/764
- return elem.document.documentElement[ "client" + name ];
- }
-
- // Get document width or height
- if ( elem.nodeType === 9 ) {
- doc = elem.documentElement;
-
- // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
- // whichever is greatest
- return Math.max(
- elem.body[ "scroll" + name ], doc[ "scroll" + name ],
- elem.body[ "offset" + name ], doc[ "offset" + name ],
- doc[ "client" + name ]
- );
- }
-
- return value === undefined ?
-
- // Get width or height on the element, requesting but not forcing parseFloat
- jQuery.css( elem, type, extra ) :
-
- // Set width or height on the element
- jQuery.style( elem, type, value, extra );
- }, type, chainable ? margin : undefined, chainable, null );
- };
- } );
- } );
-
-
- jQuery.fn.extend( {
-
- bind: function( types, data, fn ) {
- return this.on( types, null, data, fn );
- },
- unbind: function( types, fn ) {
- return this.off( types, null, fn );
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.on( types, selector, data, fn );
- },
- undelegate: function( selector, types, fn ) {
-
- // ( namespace ) or ( selector, types [, fn] )
- return arguments.length === 1 ?
- this.off( selector, "**" ) :
- this.off( types, selector || "**", fn );
- },
- size: function() {
- return this.length;
- }
- } );
-
- jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
- // Register as a named AMD module, since jQuery can be concatenated with other
- // files that may use define, but not via a proper concatenation script that
- // understands anonymous AMD modules. A named AMD is safest and most robust
- // way to register. Lowercase jquery is used because AMD module names are
- // derived from file names, and jQuery is normally delivered in a lowercase
- // file name. Do this after creating the global so that if an AMD module wants
- // to call noConflict to hide this version of jQuery, it will work.
-
- // Note that for maximum portability, libraries that are not jQuery should
- // declare themselves as anonymous modules, and avoid setting a global if an
- // AMD loader is present. jQuery is a special case. For more information, see
- // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
- if ( true ) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
- return jQuery;
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- }
-
-
-
- var
-
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$;
-
- jQuery.noConflict = function( deep ) {
- if ( window.$ === jQuery ) {
- window.$ = _$;
- }
-
- if ( deep && window.jQuery === jQuery ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
- };
-
- // Expose jQuery and $ identifiers, even in AMD
- // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
- // and CommonJS for browser emulators (#13566)
- if ( !noGlobal ) {
- window.jQuery = window.$ = jQuery;
- }
-
- return jQuery;
- }));
-
-
-/***/ },
-/* 21 */
-/***/ function(module, exports, __webpack_require__) {
-
- /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["Vue"] = __webpack_require__(22);
- /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 22 */
-/***/ function(module, exports, __webpack_require__) {
-
- /* WEBPACK VAR INJECTION */(function(global, process) {/*!
- * Vue.js v1.0.24
- * (c) 2016 Evan You
- * Released under the MIT License.
- */
- 'use strict';
-
- function set(obj, key, val) {
- if (hasOwn(obj, key)) {
- obj[key] = val;
- return;
- }
- if (obj._isVue) {
- set(obj._data, key, val);
- return;
- }
- var ob = obj.__ob__;
- if (!ob) {
- obj[key] = val;
- return;
- }
- ob.convert(key, val);
- ob.dep.notify();
- if (ob.vms) {
- var i = ob.vms.length;
- while (i--) {
- var vm = ob.vms[i];
- vm._proxy(key);
- vm._digest();
- }
- }
- return val;
- }
-
- /**
- * Delete a property and trigger change if necessary.
- *
- * @param {Object} obj
- * @param {String} key
- */
-
- function del(obj, key) {
- if (!hasOwn(obj, key)) {
- return;
- }
- delete obj[key];
- var ob = obj.__ob__;
- if (!ob) {
- if (obj._isVue) {
- delete obj._data[key];
- obj._digest();
- }
- return;
- }
- ob.dep.notify();
- if (ob.vms) {
- var i = ob.vms.length;
- while (i--) {
- var vm = ob.vms[i];
- vm._unproxy(key);
- vm._digest();
- }
- }
- }
-
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- /**
- * Check whether the object has the property.
- *
- * @param {Object} obj
- * @param {String} key
- * @return {Boolean}
- */
-
- function hasOwn(obj, key) {
- return hasOwnProperty.call(obj, key);
- }
-
- /**
- * Check if an expression is a literal value.
- *
- * @param {String} exp
- * @return {Boolean}
- */
-
- var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;
-
- function isLiteral(exp) {
- return literalValueRE.test(exp);
- }
-
- /**
- * Check if a string starts with $ or _
- *
- * @param {String} str
- * @return {Boolean}
- */
-
- function isReserved(str) {
- var c = (str + '').charCodeAt(0);
- return c === 0x24 || c === 0x5F;
- }
-
- /**
- * Guard text output, make sure undefined outputs
- * empty string
- *
- * @param {*} value
- * @return {String}
- */
-
- function _toString(value) {
- return value == null ? '' : value.toString();
- }
-
- /**
- * Check and convert possible numeric strings to numbers
- * before setting back to data
- *
- * @param {*} value
- * @return {*|Number}
- */
-
- function toNumber(value) {
- if (typeof value !== 'string') {
- return value;
- } else {
- var parsed = Number(value);
- return isNaN(parsed) ? value : parsed;
- }
- }
-
- /**
- * Convert string boolean literals into real booleans.
- *
- * @param {*} value
- * @return {*|Boolean}
- */
-
- function toBoolean(value) {
- return value === 'true' ? true : value === 'false' ? false : value;
- }
-
- /**
- * Strip quotes from a string
- *
- * @param {String} str
- * @return {String | false}
- */
-
- function stripQuotes(str) {
- var a = str.charCodeAt(0);
- var b = str.charCodeAt(str.length - 1);
- return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
- }
-
- /**
- * Camelize a hyphen-delmited string.
- *
- * @param {String} str
- * @return {String}
- */
-
- var camelizeRE = /-(\w)/g;
-
- function camelize(str) {
- return str.replace(camelizeRE, toUpper);
- }
-
- function toUpper(_, c) {
- return c ? c.toUpperCase() : '';
- }
-
- /**
- * Hyphenate a camelCase string.
- *
- * @param {String} str
- * @return {String}
- */
-
- var hyphenateRE = /([a-z\d])([A-Z])/g;
-
- function hyphenate(str) {
- return str.replace(hyphenateRE, '$1-$2').toLowerCase();
- }
-
- /**
- * Converts hyphen/underscore/slash delimitered names into
- * camelized classNames.
- *
- * e.g. my-component => MyComponent
- * some_else => SomeElse
- * some/comp => SomeComp
- *
- * @param {String} str
- * @return {String}
- */
-
- var classifyRE = /(?:^|[-_\/])(\w)/g;
-
- function classify(str) {
- return str.replace(classifyRE, toUpper);
- }
-
- /**
- * Simple bind, faster than native
- *
- * @param {Function} fn
- * @param {Object} ctx
- * @return {Function}
- */
-
- function bind(fn, ctx) {
- return function (a) {
- var l = arguments.length;
- return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
- };
- }
-
- /**
- * Convert an Array-like object to a real Array.
- *
- * @param {Array-like} list
- * @param {Number} [start] - start index
- * @return {Array}
- */
-
- function toArray(list, start) {
- start = start || 0;
- var i = list.length - start;
- var ret = new Array(i);
- while (i--) {
- ret[i] = list[i + start];
- }
- return ret;
- }
-
- /**
- * Mix properties into target object.
- *
- * @param {Object} to
- * @param {Object} from
- */
-
- function extend(to, from) {
- var keys = Object.keys(from);
- var i = keys.length;
- while (i--) {
- to[keys[i]] = from[keys[i]];
- }
- return to;
- }
-
- /**
- * Quick object check - this is primarily used to tell
- * Objects from primitive values when we know the value
- * is a JSON-compliant type.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
- function isObject(obj) {
- return obj !== null && typeof obj === 'object';
- }
-
- /**
- * Strict object type check. Only returns true
- * for plain JavaScript objects.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
- var toString = Object.prototype.toString;
- var OBJECT_STRING = '[object Object]';
-
- function isPlainObject(obj) {
- return toString.call(obj) === OBJECT_STRING;
- }
-
- /**
- * Array type check.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
- var isArray = Array.isArray;
-
- /**
- * Define a property.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- * @param {Boolean} [enumerable]
- */
-
- function def(obj, key, val, enumerable) {
- Object.defineProperty(obj, key, {
- value: val,
- enumerable: !!enumerable,
- writable: true,
- configurable: true
- });
- }
-
- /**
- * Debounce a function so it only gets called after the
- * input stops arriving after the given wait period.
- *
- * @param {Function} func
- * @param {Number} wait
- * @return {Function} - the debounced function
- */
-
- function _debounce(func, wait) {
- var timeout, args, context, timestamp, result;
- var later = function later() {
- var last = Date.now() - timestamp;
- if (last < wait && last >= 0) {
- timeout = setTimeout(later, wait - last);
- } else {
- timeout = null;
- result = func.apply(context, args);
- if (!timeout) context = args = null;
- }
- };
- return function () {
- context = this;
- args = arguments;
- timestamp = Date.now();
- if (!timeout) {
- timeout = setTimeout(later, wait);
- }
- return result;
- };
- }
-
- /**
- * Manual indexOf because it's slightly faster than
- * native.
- *
- * @param {Array} arr
- * @param {*} obj
- */
-
- function indexOf(arr, obj) {
- var i = arr.length;
- while (i--) {
- if (arr[i] === obj) return i;
- }
- return -1;
- }
-
- /**
- * Make a cancellable version of an async callback.
- *
- * @param {Function} fn
- * @return {Function}
- */
-
- function cancellable(fn) {
- var cb = function cb() {
- if (!cb.cancelled) {
- return fn.apply(this, arguments);
- }
- };
- cb.cancel = function () {
- cb.cancelled = true;
- };
- return cb;
- }
-
- /**
- * Check if two values are loosely equal - that is,
- * if they are plain objects, do they have the same shape?
- *
- * @param {*} a
- * @param {*} b
- * @return {Boolean}
- */
-
- function looseEqual(a, b) {
- /* eslint-disable eqeqeq */
- return a == b || (isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false);
- /* eslint-enable eqeqeq */
- }
-
- var hasProto = ('__proto__' in {});
-
- // Browser environment sniffing
- var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
-
- // detect devtools
- var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
-
- // UA sniffing for working around browser-specific quirks
- var UA = inBrowser && window.navigator.userAgent.toLowerCase();
- var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
- var isAndroid = UA && UA.indexOf('android') > 0;
- var isIos = UA && /(iphone|ipad|ipod|ios)/i.test(UA);
- var isWechat = UA && UA.indexOf('micromessenger') > 0;
-
- var transitionProp = undefined;
- var transitionEndEvent = undefined;
- var animationProp = undefined;
- var animationEndEvent = undefined;
-
- // Transition property/event sniffing
- if (inBrowser && !isIE9) {
- var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
- var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
- transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
- transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
- animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
- animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
- }
-
- /**
- * Defer a task to execute it asynchronously. Ideally this
- * should be executed as a microtask, so we leverage
- * MutationObserver if it's available, and fallback to
- * setTimeout(0).
- *
- * @param {Function} cb
- * @param {Object} ctx
- */
-
- var nextTick = (function () {
- var callbacks = [];
- var pending = false;
- var timerFunc;
- function nextTickHandler() {
- pending = false;
- var copies = callbacks.slice(0);
- callbacks = [];
- for (var i = 0; i < copies.length; i++) {
- copies[i]();
- }
- }
-
- /* istanbul ignore if */
- if (typeof MutationObserver !== 'undefined' && !(isWechat && isIos)) {
- var counter = 1;
- var observer = new MutationObserver(nextTickHandler);
- var textNode = document.createTextNode(counter);
- observer.observe(textNode, {
- characterData: true
- });
- timerFunc = function () {
- counter = (counter + 1) % 2;
- textNode.data = counter;
- };
- } else {
- // webpack attempts to inject a shim for setImmediate
- // if it is used as a global, so we have to work around that to
- // avoid bundling unnecessary code.
- var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
- timerFunc = context.setImmediate || setTimeout;
- }
- return function (cb, ctx) {
- var func = ctx ? function () {
- cb.call(ctx);
- } : cb;
- callbacks.push(func);
- if (pending) return;
- pending = true;
- timerFunc(nextTickHandler, 0);
- };
- })();
-
- var _Set = undefined;
- /* istanbul ignore if */
- if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
- // use native Set when available.
- _Set = Set;
- } else {
- // a non-standard Set polyfill that only works with primitive keys.
- _Set = function () {
- this.set = Object.create(null);
- };
- _Set.prototype.has = function (key) {
- return this.set[key] !== undefined;
- };
- _Set.prototype.add = function (key) {
- this.set[key] = 1;
- };
- _Set.prototype.clear = function () {
- this.set = Object.create(null);
- };
- }
-
- function Cache(limit) {
- this.size = 0;
- this.limit = limit;
- this.head = this.tail = undefined;
- this._keymap = Object.create(null);
- }
-
- var p = Cache.prototype;
-
- /**
- * Put <value> into the cache associated with <key>.
- * Returns the entry which was removed to make room for
- * the new entry. Otherwise undefined is returned.
- * (i.e. if there was enough room already).
- *
- * @param {String} key
- * @param {*} value
- * @return {Entry|undefined}
- */
-
- p.put = function (key, value) {
- var removed;
- if (this.size === this.limit) {
- removed = this.shift();
- }
-
- var entry = this.get(key, true);
- if (!entry) {
- entry = {
- key: key
- };
- this._keymap[key] = entry;
- if (this.tail) {
- this.tail.newer = entry;
- entry.older = this.tail;
- } else {
- this.head = entry;
- }
- this.tail = entry;
- this.size++;
- }
- entry.value = value;
-
- return removed;
- };
-
- /**
- * Purge the least recently used (oldest) entry from the
- * cache. Returns the removed entry or undefined if the
- * cache was empty.
- */
-
- p.shift = function () {
- var entry = this.head;
- if (entry) {
- this.head = this.head.newer;
- this.head.older = undefined;
- entry.newer = entry.older = undefined;
- this._keymap[entry.key] = undefined;
- this.size--;
- }
- return entry;
- };
-
- /**
- * Get and register recent use of <key>. Returns the value
- * associated with <key> or undefined if not in cache.
- *
- * @param {String} key
- * @param {Boolean} returnEntry
- * @return {Entry|*}
- */
-
- p.get = function (key, returnEntry) {
- var entry = this._keymap[key];
- if (entry === undefined) return;
- if (entry === this.tail) {
- return returnEntry ? entry : entry.value;
- }
- // HEAD--------------TAIL
- // <.older .newer>
- // <--- add direction --
- // A B C <D> E
- if (entry.newer) {
- if (entry === this.head) {
- this.head = entry.newer;
- }
- entry.newer.older = entry.older; // C <-- E.
- }
- if (entry.older) {
- entry.older.newer = entry.newer; // C. --> E
- }
- entry.newer = undefined; // D --x
- entry.older = this.tail; // D. --> E
- if (this.tail) {
- this.tail.newer = entry; // E. <-- D
- }
- this.tail = entry;
- return returnEntry ? entry : entry.value;
- };
-
- var cache$1 = new Cache(1000);
- var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
- var reservedArgRE = /^in$|^-?\d+/;
-
- /**
- * Parser state
- */
-
- var str;
- var dir;
- var c;
- var prev;
- var i;
- var l;
- var lastFilterIndex;
- var inSingle;
- var inDouble;
- var curly;
- var square;
- var paren;
- /**
- * Push a filter to the current directive object
- */
-
- function pushFilter() {
- var exp = str.slice(lastFilterIndex, i).trim();
- var filter;
- if (exp) {
- filter = {};
- var tokens = exp.match(filterTokenRE);
- filter.name = tokens[0];
- if (tokens.length > 1) {
- filter.args = tokens.slice(1).map(processFilterArg);
- }
- }
- if (filter) {
- (dir.filters = dir.filters || []).push(filter);
- }
- lastFilterIndex = i + 1;
- }
-
- /**
- * Check if an argument is dynamic and strip quotes.
- *
- * @param {String} arg
- * @return {Object}
- */
-
- function processFilterArg(arg) {
- if (reservedArgRE.test(arg)) {
- return {
- value: toNumber(arg),
- dynamic: false
- };
- } else {
- var stripped = stripQuotes(arg);
- var dynamic = stripped === arg;
- return {
- value: dynamic ? arg : stripped,
- dynamic: dynamic
- };
- }
- }
-
- /**
- * Parse a directive value and extract the expression
- * and its filters into a descriptor.
- *
- * Example:
- *
- * "a + 1 | uppercase" will yield:
- * {
- * expression: 'a + 1',
- * filters: [
- * { name: 'uppercase', args: null }
- * ]
- * }
- *
- * @param {String} s
- * @return {Object}
- */
-
- function parseDirective(s) {
- var hit = cache$1.get(s);
- if (hit) {
- return hit;
- }
-
- // reset parser state
- str = s;
- inSingle = inDouble = false;
- curly = square = paren = 0;
- lastFilterIndex = 0;
- dir = {};
-
- for (i = 0, l = str.length; i < l; i++) {
- prev = c;
- c = str.charCodeAt(i);
- if (inSingle) {
- // check single quote
- if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
- } else if (inDouble) {
- // check double quote
- if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
- } else if (c === 0x7C && // pipe
- str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
- if (dir.expression == null) {
- // first filter, end of expression
- lastFilterIndex = i + 1;
- dir.expression = str.slice(0, i).trim();
- } else {
- // already has filter
- pushFilter();
- }
- } else {
- switch (c) {
- case 0x22:
- inDouble = true;break; // "
- case 0x27:
- inSingle = true;break; // '
- case 0x28:
- paren++;break; // (
- case 0x29:
- paren--;break; // )
- case 0x5B:
- square++;break; // [
- case 0x5D:
- square--;break; // ]
- case 0x7B:
- curly++;break; // {
- case 0x7D:
- curly--;break; // }
- }
- }
- }
-
- if (dir.expression == null) {
- dir.expression = str.slice(0, i).trim();
- } else if (lastFilterIndex !== 0) {
- pushFilter();
- }
-
- cache$1.put(s, dir);
- return dir;
- }
-
- var directive = Object.freeze({
- parseDirective: parseDirective
- });
-
- var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
- var cache = undefined;
- var tagRE = undefined;
- var htmlRE = undefined;
- /**
- * Escape a string so it can be used in a RegExp
- * constructor.
- *
- * @param {String} str
- */
-
- function escapeRegex(str) {
- return str.replace(regexEscapeRE, '\\$&');
- }
-
- function compileRegex() {
- var open = escapeRegex(config.delimiters[0]);
- var close = escapeRegex(config.delimiters[1]);
- var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
- var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
- tagRE = new RegExp(unsafeOpen + '((?:.|\\n)+?)' + unsafeClose + '|' + open + '((?:.|\\n)+?)' + close, 'g');
- htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
- // reset cache
- cache = new Cache(1000);
- }
-
- /**
- * Parse a template text string into an array of tokens.
- *
- * @param {String} text
- * @return {Array<Object> | null}
- * - {String} type
- * - {String} value
- * - {Boolean} [html]
- * - {Boolean} [oneTime]
- */
-
- function parseText(text) {
- if (!cache) {
- compileRegex();
- }
- var hit = cache.get(text);
- if (hit) {
- return hit;
- }
- if (!tagRE.test(text)) {
- return null;
- }
- var tokens = [];
- var lastIndex = tagRE.lastIndex = 0;
- var match, index, html, value, first, oneTime;
- /* eslint-disable no-cond-assign */
- while (match = tagRE.exec(text)) {
- /* eslint-enable no-cond-assign */
- index = match.index;
- // push text token
- if (index > lastIndex) {
- tokens.push({
- value: text.slice(lastIndex, index)
- });
- }
- // tag token
- html = htmlRE.test(match[0]);
- value = html ? match[1] : match[2];
- first = value.charCodeAt(0);
- oneTime = first === 42; // *
- value = oneTime ? value.slice(1) : value;
- tokens.push({
- tag: true,
- value: value.trim(),
- html: html,
- oneTime: oneTime
- });
- lastIndex = index + match[0].length;
- }
- if (lastIndex < text.length) {
- tokens.push({
- value: text.slice(lastIndex)
- });
- }
- cache.put(text, tokens);
- return tokens;
- }
-
- /**
- * Format a list of tokens into an expression.
- * e.g. tokens parsed from 'a {{b}} c' can be serialized
- * into one single expression as '"a " + b + " c"'.
- *
- * @param {Array} tokens
- * @param {Vue} [vm]
- * @return {String}
- */
-
- function tokensToExp(tokens, vm) {
- if (tokens.length > 1) {
- return tokens.map(function (token) {
- return formatToken(token, vm);
- }).join('+');
- } else {
- return formatToken(tokens[0], vm, true);
- }
- }
-
- /**
- * Format a single token.
- *
- * @param {Object} token
- * @param {Vue} [vm]
- * @param {Boolean} [single]
- * @return {String}
- */
-
- function formatToken(token, vm, single) {
- return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
- }
-
- /**
- * For an attribute with multiple interpolation tags,
- * e.g. attr="some-{{thing | filter}}", in order to combine
- * the whole thing into a single watchable expression, we
- * have to inline those filters. This function does exactly
- * that. This is a bit hacky but it avoids heavy changes
- * to directive parser and watcher mechanism.
- *
- * @param {String} exp
- * @param {Boolean} single
- * @return {String}
- */
-
- var filterRE = /[^|]\|[^|]/;
- function inlineFilters(exp, single) {
- if (!filterRE.test(exp)) {
- return single ? exp : '(' + exp + ')';
- } else {
- var dir = parseDirective(exp);
- if (!dir.filters) {
- return '(' + exp + ')';
- } else {
- return 'this._applyFilters(' + dir.expression + // value
- ',null,' + // oldValue (null for read)
- JSON.stringify(dir.filters) + // filter descriptors
- ',false)'; // write?
- }
- }
- }
-
- var text = Object.freeze({
- compileRegex: compileRegex,
- parseText: parseText,
- tokensToExp: tokensToExp
- });
-
- var delimiters = ['{{', '}}'];
- var unsafeDelimiters = ['{{{', '}}}'];
-
- var config = Object.defineProperties({
-
- /**
- * Whether to print debug messages.
- * Also enables stack trace for warnings.
- *
- * @type {Boolean}
- */
-
- debug: false,
-
- /**
- * Whether to suppress warnings.
- *
- * @type {Boolean}
- */
-
- silent: false,
-
- /**
- * Whether to use async rendering.
- */
-
- async: true,
-
- /**
- * Whether to warn against errors caught when evaluating
- * expressions.
- */
-
- warnExpressionErrors: true,
-
- /**
- * Whether to allow devtools inspection.
- * Disabled by default in production builds.
- */
-
- devtools: process.env.NODE_ENV !== 'production',
-
- /**
- * Internal flag to indicate the delimiters have been
- * changed.
- *
- * @type {Boolean}
- */
-
- _delimitersChanged: true,
-
- /**
- * List of asset types that a component can own.
- *
- * @type {Array}
- */
-
- _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
-
- /**
- * prop binding modes
- */
-
- _propBindingModes: {
- ONE_WAY: 0,
- TWO_WAY: 1,
- ONE_TIME: 2
- },
-
- /**
- * Max circular updates allowed in a batcher flush cycle.
- */
-
- _maxUpdateCount: 100
-
- }, {
- delimiters: { /**
- * Interpolation delimiters. Changing these would trigger
- * the text parser to re-compile the regular expressions.
- *
- * @type {Array<String>}
- */
-
- get: function get() {
- return delimiters;
- },
- set: function set(val) {
- delimiters = val;
- compileRegex();
- },
- configurable: true,
- enumerable: true
- },
- unsafeDelimiters: {
- get: function get() {
- return unsafeDelimiters;
- },
- set: function set(val) {
- unsafeDelimiters = val;
- compileRegex();
- },
- configurable: true,
- enumerable: true
- }
- });
-
- var warn = undefined;
- var formatComponentName = undefined;
-
- if (process.env.NODE_ENV !== 'production') {
- (function () {
- var hasConsole = typeof console !== 'undefined';
-
- warn = function (msg, vm) {
- if (hasConsole && !config.silent) {
- console.error('[Vue warn]: ' + msg + (vm ? formatComponentName(vm) : ''));
- }
- };
-
- formatComponentName = function (vm) {
- var name = vm._isVue ? vm.$options.name : vm.name;
- return name ? ' (found in component: <' + hyphenate(name) + '>)' : '';
- };
- })();
- }
-
- /**
- * Append with transition.
- *
- * @param {Element} el
- * @param {Element} target
- * @param {Vue} vm
- * @param {Function} [cb]
- */
-
- function appendWithTransition(el, target, vm, cb) {
- applyTransition(el, 1, function () {
- target.appendChild(el);
- }, vm, cb);
- }
-
- /**
- * InsertBefore with transition.
- *
- * @param {Element} el
- * @param {Element} target
- * @param {Vue} vm
- * @param {Function} [cb]
- */
-
- function beforeWithTransition(el, target, vm, cb) {
- applyTransition(el, 1, function () {
- before(el, target);
- }, vm, cb);
- }
-
- /**
- * Remove with transition.
- *
- * @param {Element} el
- * @param {Vue} vm
- * @param {Function} [cb]
- */
-
- function removeWithTransition(el, vm, cb) {
- applyTransition(el, -1, function () {
- remove(el);
- }, vm, cb);
- }
-
- /**
- * Apply transitions with an operation callback.
- *
- * @param {Element} el
- * @param {Number} direction
- * 1: enter
- * -1: leave
- * @param {Function} op - the actual DOM operation
- * @param {Vue} vm
- * @param {Function} [cb]
- */
-
- function applyTransition(el, direction, op, vm, cb) {
- var transition = el.__v_trans;
- if (!transition ||
- // skip if there are no js hooks and CSS transition is
- // not supported
- !transition.hooks && !transitionEndEvent ||
- // skip transitions for initial compile
- !vm._isCompiled ||
- // if the vm is being manipulated by a parent directive
- // during the parent's compilation phase, skip the
- // animation.
- vm.$parent && !vm.$parent._isCompiled) {
- op();
- if (cb) cb();
- return;
- }
- var action = direction > 0 ? 'enter' : 'leave';
- transition[action](op, cb);
- }
-
- var transition = Object.freeze({
- appendWithTransition: appendWithTransition,
- beforeWithTransition: beforeWithTransition,
- removeWithTransition: removeWithTransition,
- applyTransition: applyTransition
- });
-
- /**
- * Query an element selector if it's not an element already.
- *
- * @param {String|Element} el
- * @return {Element}
- */
-
- function query(el) {
- if (typeof el === 'string') {
- var selector = el;
- el = document.querySelector(el);
- if (!el) {
- process.env.NODE_ENV !== 'production' && warn('Cannot find element: ' + selector);
- }
- }
- return el;
- }
-
- /**
- * Check if a node is in the document.
- * Note: document.documentElement.contains should work here
- * but always returns false for comment nodes in phantomjs,
- * making unit tests difficult. This is fixed by doing the
- * contains() check on the node's parentNode instead of
- * the node itself.
- *
- * @param {Node} node
- * @return {Boolean}
- */
-
- function inDoc(node) {
- if (!node) return false;
- var doc = node.ownerDocument.documentElement;
- var parent = node.parentNode;
- return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
- }
-
- /**
- * Get and remove an attribute from a node.
- *
- * @param {Node} node
- * @param {String} _attr
- */
-
- function getAttr(node, _attr) {
- var val = node.getAttribute(_attr);
- if (val !== null) {
- node.removeAttribute(_attr);
- }
- return val;
- }
-
- /**
- * Get an attribute with colon or v-bind: prefix.
- *
- * @param {Node} node
- * @param {String} name
- * @return {String|null}
- */
-
- function getBindAttr(node, name) {
- var val = getAttr(node, ':' + name);
- if (val === null) {
- val = getAttr(node, 'v-bind:' + name);
- }
- return val;
- }
-
- /**
- * Check the presence of a bind attribute.
- *
- * @param {Node} node
- * @param {String} name
- * @return {Boolean}
- */
-
- function hasBindAttr(node, name) {
- return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
- }
-
- /**
- * Insert el before target
- *
- * @param {Element} el
- * @param {Element} target
- */
-
- function before(el, target) {
- target.parentNode.insertBefore(el, target);
- }
-
- /**
- * Insert el after target
- *
- * @param {Element} el
- * @param {Element} target
- */
-
- function after(el, target) {
- if (target.nextSibling) {
- before(el, target.nextSibling);
- } else {
- target.parentNode.appendChild(el);
- }
- }
-
- /**
- * Remove el from DOM
- *
- * @param {Element} el
- */
-
- function remove(el) {
- el.parentNode.removeChild(el);
- }
-
- /**
- * Prepend el to target
- *
- * @param {Element} el
- * @param {Element} target
- */
-
- function prepend(el, target) {
- if (target.firstChild) {
- before(el, target.firstChild);
- } else {
- target.appendChild(el);
- }
- }
-
- /**
- * Replace target with el
- *
- * @param {Element} target
- * @param {Element} el
- */
-
- function replace(target, el) {
- var parent = target.parentNode;
- if (parent) {
- parent.replaceChild(el, target);
- }
- }
-
- /**
- * Add event listener shorthand.
- *
- * @param {Element} el
- * @param {String} event
- * @param {Function} cb
- * @param {Boolean} [useCapture]
- */
-
- function on(el, event, cb, useCapture) {
- el.addEventListener(event, cb, useCapture);
- }
-
- /**
- * Remove event listener shorthand.
- *
- * @param {Element} el
- * @param {String} event
- * @param {Function} cb
- */
-
- function off(el, event, cb) {
- el.removeEventListener(event, cb);
- }
-
- /**
- * For IE9 compat: when both class and :class are present
- * getAttribute('class') returns wrong value...
- *
- * @param {Element} el
- * @return {String}
- */
-
- function getClass(el) {
- var classname = el.className;
- if (typeof classname === 'object') {
- classname = classname.baseVal || '';
- }
- return classname;
- }
-
- /**
- * In IE9, setAttribute('class') will result in empty class
- * if the element also has the :class attribute; However in
- * PhantomJS, setting `className` does not work on SVG elements...
- * So we have to do a conditional check here.
- *
- * @param {Element} el
- * @param {String} cls
- */
-
- function setClass(el, cls) {
- /* istanbul ignore if */
- if (isIE9 && !/svg$/.test(el.namespaceURI)) {
- el.className = cls;
- } else {
- el.setAttribute('class', cls);
- }
- }
-
- /**
- * Add class with compatibility for IE & SVG
- *
- * @param {Element} el
- * @param {String} cls
- */
-
- function addClass(el, cls) {
- if (el.classList) {
- el.classList.add(cls);
- } else {
- var cur = ' ' + getClass(el) + ' ';
- if (cur.indexOf(' ' + cls + ' ') < 0) {
- setClass(el, (cur + cls).trim());
- }
- }
- }
-
- /**
- * Remove class with compatibility for IE & SVG
- *
- * @param {Element} el
- * @param {String} cls
- */
-
- function removeClass(el, cls) {
- if (el.classList) {
- el.classList.remove(cls);
- } else {
- var cur = ' ' + getClass(el) + ' ';
- var tar = ' ' + cls + ' ';
- while (cur.indexOf(tar) >= 0) {
- cur = cur.replace(tar, ' ');
- }
- setClass(el, cur.trim());
- }
- if (!el.className) {
- el.removeAttribute('class');
- }
- }
-
- /**
- * Extract raw content inside an element into a temporary
- * container div
- *
- * @param {Element} el
- * @param {Boolean} asFragment
- * @return {Element|DocumentFragment}
- */
-
- function extractContent(el, asFragment) {
- var child;
- var rawContent;
- /* istanbul ignore if */
- if (isTemplate(el) && isFragment(el.content)) {
- el = el.content;
- }
- if (el.hasChildNodes()) {
- trimNode(el);
- rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
- /* eslint-disable no-cond-assign */
- while (child = el.firstChild) {
- /* eslint-enable no-cond-assign */
- rawContent.appendChild(child);
- }
- }
- return rawContent;
- }
-
- /**
- * Trim possible empty head/tail text and comment
- * nodes inside a parent.
- *
- * @param {Node} node
- */
-
- function trimNode(node) {
- var child;
- /* eslint-disable no-sequences */
- while ((child = node.firstChild, isTrimmable(child))) {
- node.removeChild(child);
- }
- while ((child = node.lastChild, isTrimmable(child))) {
- node.removeChild(child);
- }
- /* eslint-enable no-sequences */
- }
-
- function isTrimmable(node) {
- return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
- }
-
- /**
- * Check if an element is a template tag.
- * Note if the template appears inside an SVG its tagName
- * will be in lowercase.
- *
- * @param {Element} el
- */
-
- function isTemplate(el) {
- return el.tagName && el.tagName.toLowerCase() === 'template';
- }
-
- /**
- * Create an "anchor" for performing dom insertion/removals.
- * This is used in a number of scenarios:
- * - fragment instance
- * - v-html
- * - v-if
- * - v-for
- * - component
- *
- * @param {String} content
- * @param {Boolean} persist - IE trashes empty textNodes on
- * cloneNode(true), so in certain
- * cases the anchor needs to be
- * non-empty to be persisted in
- * templates.
- * @return {Comment|Text}
- */
-
- function createAnchor(content, persist) {
- var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
- anchor.__v_anchor = true;
- return anchor;
- }
-
- /**
- * Find a component ref attribute that starts with $.
- *
- * @param {Element} node
- * @return {String|undefined}
- */
-
- var refRE = /^v-ref:/;
-
- function findRef(node) {
- if (node.hasAttributes()) {
- var attrs = node.attributes;
- for (var i = 0, l = attrs.length; i < l; i++) {
- var name = attrs[i].name;
- if (refRE.test(name)) {
- return camelize(name.replace(refRE, ''));
- }
- }
- }
- }
-
- /**
- * Map a function to a range of nodes .
- *
- * @param {Node} node
- * @param {Node} end
- * @param {Function} op
- */
-
- function mapNodeRange(node, end, op) {
- var next;
- while (node !== end) {
- next = node.nextSibling;
- op(node);
- node = next;
- }
- op(end);
- }
-
- /**
- * Remove a range of nodes with transition, store
- * the nodes in a fragment with correct ordering,
- * and call callback when done.
- *
- * @param {Node} start
- * @param {Node} end
- * @param {Vue} vm
- * @param {DocumentFragment} frag
- * @param {Function} cb
- */
-
- function removeNodeRange(start, end, vm, frag, cb) {
- var done = false;
- var removed = 0;
- var nodes = [];
- mapNodeRange(start, end, function (node) {
- if (node === end) done = true;
- nodes.push(node);
- removeWithTransition(node, vm, onRemoved);
- });
- function onRemoved() {
- removed++;
- if (done && removed >= nodes.length) {
- for (var i = 0; i < nodes.length; i++) {
- frag.appendChild(nodes[i]);
- }
- cb && cb();
- }
- }
- }
-
- /**
- * Check if a node is a DocumentFragment.
- *
- * @param {Node} node
- * @return {Boolean}
- */
-
- function isFragment(node) {
- return node && node.nodeType === 11;
- }
-
- /**
- * Get outerHTML of elements, taking care
- * of SVG elements in IE as well.
- *
- * @param {Element} el
- * @return {String}
- */
-
- function getOuterHTML(el) {
- if (el.outerHTML) {
- return el.outerHTML;
- } else {
- var container = document.createElement('div');
- container.appendChild(el.cloneNode(true));
- return container.innerHTML;
- }
- }
-
- var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i;
- var reservedTagRE = /^(slot|partial|component)$/i;
-
- var isUnknownElement = undefined;
- if (process.env.NODE_ENV !== 'production') {
- isUnknownElement = function (el, tag) {
- if (tag.indexOf('-') > -1) {
- // http://stackoverflow.com/a/28210364/1070244
- return el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement;
- } else {
- return (/HTMLUnknownElement/.test(el.toString()) &&
- // Chrome returns unknown for several HTML5 elements.
- // https://code.google.com/p/chromium/issues/detail?id=540526
- !/^(data|time|rtc|rb)$/.test(tag)
- );
- }
- };
- }
-
- /**
- * Check if an element is a component, if yes return its
- * component id.
- *
- * @param {Element} el
- * @param {Object} options
- * @return {Object|undefined}
- */
-
- function checkComponentAttr(el, options) {
- var tag = el.tagName.toLowerCase();
- var hasAttrs = el.hasAttributes();
- if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
- if (resolveAsset(options, 'components', tag)) {
- return { id: tag };
- } else {
- var is = hasAttrs && getIsBinding(el, options);
- if (is) {
- return is;
- } else if (process.env.NODE_ENV !== 'production') {
- var expectedTag = options._componentNameMap && options._componentNameMap[tag];
- if (expectedTag) {
- warn('Unknown custom element: <' + tag + '> - ' + 'did you mean <' + expectedTag + '>? ' + 'HTML is case-insensitive, remember to use kebab-case in templates.');
- } else if (isUnknownElement(el, tag)) {
- warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
- }
- }
- }
- } else if (hasAttrs) {
- return getIsBinding(el, options);
- }
- }
-
- /**
- * Get "is" binding from an element.
- *
- * @param {Element} el
- * @param {Object} options
- * @return {Object|undefined}
- */
-
- function getIsBinding(el, options) {
- // dynamic syntax
- var exp = el.getAttribute('is');
- if (exp != null) {
- if (resolveAsset(options, 'components', exp)) {
- el.removeAttribute('is');
- return { id: exp };
- }
- } else {
- exp = getBindAttr(el, 'is');
- if (exp != null) {
- return { id: exp, dynamic: true };
- }
- }
- }
-
- /**
- * Option overwriting strategies are functions that handle
- * how to merge a parent option value and a child option
- * value into the final value.
- *
- * All strategy functions follow the same signature:
- *
- * @param {*} parentVal
- * @param {*} childVal
- * @param {Vue} [vm]
- */
-
- var strats = config.optionMergeStrategies = Object.create(null);
-
- /**
- * Helper that recursively merges two data objects together.
- */
-
- function mergeData(to, from) {
- var key, toVal, fromVal;
- for (key in from) {
- toVal = to[key];
- fromVal = from[key];
- if (!hasOwn(to, key)) {
- set(to, key, fromVal);
- } else if (isObject(toVal) && isObject(fromVal)) {
- mergeData(toVal, fromVal);
- }
- }
- return to;
- }
-
- /**
- * Data
- */
-
- strats.data = function (parentVal, childVal, vm) {
- if (!vm) {
- // in a Vue.extend merge, both should be functions
- if (!childVal) {
- return parentVal;
- }
- if (typeof childVal !== 'function') {
- process.env.NODE_ENV !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
- return parentVal;
- }
- if (!parentVal) {
- return childVal;
- }
- // when parentVal & childVal are both present,
- // we need to return a function that returns the
- // merged result of both functions... no need to
- // check if parentVal is a function here because
- // it has to be a function to pass previous merges.
- return function mergedDataFn() {
- return mergeData(childVal.call(this), parentVal.call(this));
- };
- } else if (parentVal || childVal) {
- return function mergedInstanceDataFn() {
- // instance merge
- var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal;
- var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined;
- if (instanceData) {
- return mergeData(instanceData, defaultData);
- } else {
- return defaultData;
- }
- };
- }
- };
-
- /**
- * El
- */
-
- strats.el = function (parentVal, childVal, vm) {
- if (!vm && childVal && typeof childVal !== 'function') {
- process.env.NODE_ENV !== 'production' && warn('The "el" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
- return;
- }
- var ret = childVal || parentVal;
- // invoke the element factory if this is instance merge
- return vm && typeof ret === 'function' ? ret.call(vm) : ret;
- };
-
- /**
- * Hooks and param attributes are merged as arrays.
- */
-
- strats.init = strats.created = strats.ready = strats.attached = strats.detached = strats.beforeCompile = strats.compiled = strats.beforeDestroy = strats.destroyed = strats.activate = function (parentVal, childVal) {
- return childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
- };
-
- /**
- * Assets
- *
- * When a vm is present (instance creation), we need to do
- * a three-way merge between constructor options, instance
- * options and parent options.
- */
-
- function mergeAssets(parentVal, childVal) {
- var res = Object.create(parentVal || null);
- return childVal ? extend(res, guardArrayAssets(childVal)) : res;
- }
-
- config._assetTypes.forEach(function (type) {
- strats[type + 's'] = mergeAssets;
- });
-
- /**
- * Events & Watchers.
- *
- * Events & watchers hashes should not overwrite one
- * another, so we merge them as arrays.
- */
-
- strats.watch = strats.events = function (parentVal, childVal) {
- if (!childVal) return parentVal;
- if (!parentVal) return childVal;
- var ret = {};
- extend(ret, parentVal);
- for (var key in childVal) {
- var parent = ret[key];
- var child = childVal[key];
- if (parent && !isArray(parent)) {
- parent = [parent];
- }
- ret[key] = parent ? parent.concat(child) : [child];
- }
- return ret;
- };
-
- /**
- * Other object hashes.
- */
-
- strats.props = strats.methods = strats.computed = function (parentVal, childVal) {
- if (!childVal) return parentVal;
- if (!parentVal) return childVal;
- var ret = Object.create(null);
- extend(ret, parentVal);
- extend(ret, childVal);
- return ret;
- };
-
- /**
- * Default strategy.
- */
-
- var defaultStrat = function defaultStrat(parentVal, childVal) {
- return childVal === undefined ? parentVal : childVal;
- };
-
- /**
- * Make sure component options get converted to actual
- * constructors.
- *
- * @param {Object} options
- */
-
- function guardComponents(options) {
- if (options.components) {
- var components = options.components = guardArrayAssets(options.components);
- var ids = Object.keys(components);
- var def;
- if (process.env.NODE_ENV !== 'production') {
- var map = options._componentNameMap = {};
- }
- for (var i = 0, l = ids.length; i < l; i++) {
- var key = ids[i];
- if (commonTagRE.test(key) || reservedTagRE.test(key)) {
- process.env.NODE_ENV !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
- continue;
- }
- // record a all lowercase <-> kebab-case mapping for
- // possible custom element case error warning
- if (process.env.NODE_ENV !== 'production') {
- map[key.replace(/-/g, '').toLowerCase()] = hyphenate(key);
- }
- def = components[key];
- if (isPlainObject(def)) {
- components[key] = Vue.extend(def);
- }
- }
- }
- }
-
- /**
- * Ensure all props option syntax are normalized into the
- * Object-based format.
- *
- * @param {Object} options
- */
-
- function guardProps(options) {
- var props = options.props;
- var i, val;
- if (isArray(props)) {
- options.props = {};
- i = props.length;
- while (i--) {
- val = props[i];
- if (typeof val === 'string') {
- options.props[val] = null;
- } else if (val.name) {
- options.props[val.name] = val;
- }
- }
- } else if (isPlainObject(props)) {
- var keys = Object.keys(props);
- i = keys.length;
- while (i--) {
- val = props[keys[i]];
- if (typeof val === 'function') {
- props[keys[i]] = { type: val };
- }
- }
- }
- }
-
- /**
- * Guard an Array-format assets option and converted it
- * into the key-value Object format.
- *
- * @param {Object|Array} assets
- * @return {Object}
- */
-
- function guardArrayAssets(assets) {
- if (isArray(assets)) {
- var res = {};
- var i = assets.length;
- var asset;
- while (i--) {
- asset = assets[i];
- var id = typeof asset === 'function' ? asset.options && asset.options.name || asset.id : asset.name || asset.id;
- if (!id) {
- process.env.NODE_ENV !== 'production' && warn('Array-syntax assets must provide a "name" or "id" field.');
- } else {
- res[id] = asset;
- }
- }
- return res;
- }
- return assets;
- }
-
- /**
- * Merge two option objects into a new one.
- * Core utility used in both instantiation and inheritance.
- *
- * @param {Object} parent
- * @param {Object} child
- * @param {Vue} [vm] - if vm is present, indicates this is
- * an instantiation merge.
- */
-
- function mergeOptions(parent, child, vm) {
- guardComponents(child);
- guardProps(child);
- if (process.env.NODE_ENV !== 'production') {
- if (child.propsData && !vm) {
- warn('propsData can only be used as an instantiation option.');
- }
- }
- var options = {};
- var key;
- if (child['extends']) {
- parent = typeof child['extends'] === 'function' ? mergeOptions(parent, child['extends'].options, vm) : mergeOptions(parent, child['extends'], vm);
- }
- if (child.mixins) {
- for (var i = 0, l = child.mixins.length; i < l; i++) {
- parent = mergeOptions(parent, child.mixins[i], vm);
- }
- }
- for (key in parent) {
- mergeField(key);
- }
- for (key in child) {
- if (!hasOwn(parent, key)) {
- mergeField(key);
- }
- }
- function mergeField(key) {
- var strat = strats[key] || defaultStrat;
- options[key] = strat(parent[key], child[key], vm, key);
- }
- return options;
- }
-
- /**
- * Resolve an asset.
- * This function is used because child instances need access
- * to assets defined in its ancestor chain.
- *
- * @param {Object} options
- * @param {String} type
- * @param {String} id
- * @param {Boolean} warnMissing
- * @return {Object|Function}
- */
-
- function resolveAsset(options, type, id, warnMissing) {
- /* istanbul ignore if */
- if (typeof id !== 'string') {
- return;
- }
- var assets = options[type];
- var camelizedId;
- var res = assets[id] ||
- // camelCase ID
- assets[camelizedId = camelize(id)] ||
- // Pascal Case ID
- assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)];
- if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {
- warn('Failed to resolve ' + type.slice(0, -1) + ': ' + id, options);
- }
- return res;
- }
-
- var uid$1 = 0;
-
- /**
- * A dep is an observable that can have multiple
- * directives subscribing to it.
- *
- * @constructor
- */
- function Dep() {
- this.id = uid$1++;
- this.subs = [];
- }
-
- // the current target watcher being evaluated.
- // this is globally unique because there could be only one
- // watcher being evaluated at any time.
- Dep.target = null;
-
- /**
- * Add a directive subscriber.
- *
- * @param {Directive} sub
- */
-
- Dep.prototype.addSub = function (sub) {
- this.subs.push(sub);
- };
-
- /**
- * Remove a directive subscriber.
- *
- * @param {Directive} sub
- */
-
- Dep.prototype.removeSub = function (sub) {
- this.subs.$remove(sub);
- };
-
- /**
- * Add self as a dependency to the target watcher.
- */
-
- Dep.prototype.depend = function () {
- Dep.target.addDep(this);
- };
-
- /**
- * Notify all subscribers of a new value.
- */
-
- Dep.prototype.notify = function () {
- // stablize the subscriber list first
- var subs = toArray(this.subs);
- for (var i = 0, l = subs.length; i < l; i++) {
- subs[i].update();
- }
- };
-
- var arrayProto = Array.prototype;
- var arrayMethods = Object.create(arrayProto)
-
- /**
- * Intercept mutating methods and emit events
- */
-
- ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
- // cache original method
- var original = arrayProto[method];
- def(arrayMethods, method, function mutator() {
- // avoid leaking arguments:
- // http://jsperf.com/closure-with-arguments
- var i = arguments.length;
- var args = new Array(i);
- while (i--) {
- args[i] = arguments[i];
- }
- var result = original.apply(this, args);
- var ob = this.__ob__;
- var inserted;
- switch (method) {
- case 'push':
- inserted = args;
- break;
- case 'unshift':
- inserted = args;
- break;
- case 'splice':
- inserted = args.slice(2);
- break;
- }
- if (inserted) ob.observeArray(inserted);
- // notify change
- ob.dep.notify();
- return result;
- });
- });
-
- /**
- * Swap the element at the given index with a new value
- * and emits corresponding event.
- *
- * @param {Number} index
- * @param {*} val
- * @return {*} - replaced element
- */
-
- def(arrayProto, '$set', function $set(index, val) {
- if (index >= this.length) {
- this.length = Number(index) + 1;
- }
- return this.splice(index, 1, val)[0];
- });
-
- /**
- * Convenience method to remove the element at given index or target element reference.
- *
- * @param {*} item
- */
-
- def(arrayProto, '$remove', function $remove(item) {
- /* istanbul ignore if */
- if (!this.length) return;
- var index = indexOf(this, item);
- if (index > -1) {
- return this.splice(index, 1);
- }
- });
-
- var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
-
- /**
- * By default, when a reactive property is set, the new value is
- * also converted to become reactive. However in certain cases, e.g.
- * v-for scope alias and props, we don't want to force conversion
- * because the value may be a nested value under a frozen data structure.
- *
- * So whenever we want to set a reactive property without forcing
- * conversion on the new value, we wrap that call inside this function.
- */
-
- var shouldConvert = true;
-
- function withoutConversion(fn) {
- shouldConvert = false;
- fn();
- shouldConvert = true;
- }
-
- /**
- * Observer class that are attached to each observed
- * object. Once attached, the observer converts target
- * object's property keys into getter/setters that
- * collect dependencies and dispatches updates.
- *
- * @param {Array|Object} value
- * @constructor
- */
-
- function Observer(value) {
- this.value = value;
- this.dep = new Dep();
- def(value, '__ob__', this);
- if (isArray(value)) {
- var augment = hasProto ? protoAugment : copyAugment;
- augment(value, arrayMethods, arrayKeys);
- this.observeArray(value);
- } else {
- this.walk(value);
- }
- }
-
- // Instance methods
-
- /**
- * Walk through each property and convert them into
- * getter/setters. This method should only be called when
- * value type is Object.
- *
- * @param {Object} obj
- */
-
- Observer.prototype.walk = function (obj) {
- var keys = Object.keys(obj);
- for (var i = 0, l = keys.length; i < l; i++) {
- this.convert(keys[i], obj[keys[i]]);
- }
- };
-
- /**
- * Observe a list of Array items.
- *
- * @param {Array} items
- */
-
- Observer.prototype.observeArray = function (items) {
- for (var i = 0, l = items.length; i < l; i++) {
- observe(items[i]);
- }
- };
-
- /**
- * Convert a property into getter/setter so we can emit
- * the events when the property is accessed/changed.
- *
- * @param {String} key
- * @param {*} val
- */
-
- Observer.prototype.convert = function (key, val) {
- defineReactive(this.value, key, val);
- };
-
- /**
- * Add an owner vm, so that when $set/$delete mutations
- * happen we can notify owner vms to proxy the keys and
- * digest the watchers. This is only called when the object
- * is observed as an instance's root $data.
- *
- * @param {Vue} vm
- */
-
- Observer.prototype.addVm = function (vm) {
- (this.vms || (this.vms = [])).push(vm);
- };
-
- /**
- * Remove an owner vm. This is called when the object is
- * swapped out as an instance's $data object.
- *
- * @param {Vue} vm
- */
-
- Observer.prototype.removeVm = function (vm) {
- this.vms.$remove(vm);
- };
-
- // helpers
-
- /**
- * Augment an target Object or Array by intercepting
- * the prototype chain using __proto__
- *
- * @param {Object|Array} target
- * @param {Object} src
- */
-
- function protoAugment(target, src) {
- /* eslint-disable no-proto */
- target.__proto__ = src;
- /* eslint-enable no-proto */
- }
-
- /**
- * Augment an target Object or Array by defining
- * hidden properties.
- *
- * @param {Object|Array} target
- * @param {Object} proto
- */
-
- function copyAugment(target, src, keys) {
- for (var i = 0, l = keys.length; i < l; i++) {
- var key = keys[i];
- def(target, key, src[key]);
- }
- }
-
- /**
- * Attempt to create an observer instance for a value,
- * returns the new observer if successfully observed,
- * or the existing observer if the value already has one.
- *
- * @param {*} value
- * @param {Vue} [vm]
- * @return {Observer|undefined}
- * @static
- */
-
- function observe(value, vm) {
- if (!value || typeof value !== 'object') {
- return;
- }
- var ob;
- if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
- ob = value.__ob__;
- } else if (shouldConvert && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
- ob = new Observer(value);
- }
- if (ob && vm) {
- ob.addVm(vm);
- }
- return ob;
- }
-
- /**
- * Define a reactive property on an Object.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- */
-
- function defineReactive(obj, key, val) {
- var dep = new Dep();
-
- var property = Object.getOwnPropertyDescriptor(obj, key);
- if (property && property.configurable === false) {
- return;
- }
-
- // cater for pre-defined getter/setters
- var getter = property && property.get;
- var setter = property && property.set;
-
- var childOb = observe(val);
- Object.defineProperty(obj, key, {
- enumerable: true,
- configurable: true,
- get: function reactiveGetter() {
- var value = getter ? getter.call(obj) : val;
- if (Dep.target) {
- dep.depend();
- if (childOb) {
- childOb.dep.depend();
- }
- if (isArray(value)) {
- for (var e, i = 0, l = value.length; i < l; i++) {
- e = value[i];
- e && e.__ob__ && e.__ob__.dep.depend();
- }
- }
- }
- return value;
- },
- set: function reactiveSetter(newVal) {
- var value = getter ? getter.call(obj) : val;
- if (newVal === value) {
- return;
- }
- if (setter) {
- setter.call(obj, newVal);
- } else {
- val = newVal;
- }
- childOb = observe(newVal);
- dep.notify();
- }
- });
- }
-
-
-
- var util = Object.freeze({
- defineReactive: defineReactive,
- set: set,
- del: del,
- hasOwn: hasOwn,
- isLiteral: isLiteral,
- isReserved: isReserved,
- _toString: _toString,
- toNumber: toNumber,
- toBoolean: toBoolean,
- stripQuotes: stripQuotes,
- camelize: camelize,
- hyphenate: hyphenate,
- classify: classify,
- bind: bind,
- toArray: toArray,
- extend: extend,
- isObject: isObject,
- isPlainObject: isPlainObject,
- def: def,
- debounce: _debounce,
- indexOf: indexOf,
- cancellable: cancellable,
- looseEqual: looseEqual,
- isArray: isArray,
- hasProto: hasProto,
- inBrowser: inBrowser,
- devtools: devtools,
- isIE9: isIE9,
- isAndroid: isAndroid,
- isIos: isIos,
- isWechat: isWechat,
- get transitionProp () { return transitionProp; },
- get transitionEndEvent () { return transitionEndEvent; },
- get animationProp () { return animationProp; },
- get animationEndEvent () { return animationEndEvent; },
- nextTick: nextTick,
- get _Set () { return _Set; },
- query: query,
- inDoc: inDoc,
- getAttr: getAttr,
- getBindAttr: getBindAttr,
- hasBindAttr: hasBindAttr,
- before: before,
- after: after,
- remove: remove,
- prepend: prepend,
- replace: replace,
- on: on,
- off: off,
- setClass: setClass,
- addClass: addClass,
- removeClass: removeClass,
- extractContent: extractContent,
- trimNode: trimNode,
- isTemplate: isTemplate,
- createAnchor: createAnchor,
- findRef: findRef,
- mapNodeRange: mapNodeRange,
- removeNodeRange: removeNodeRange,
- isFragment: isFragment,
- getOuterHTML: getOuterHTML,
- mergeOptions: mergeOptions,
- resolveAsset: resolveAsset,
- checkComponentAttr: checkComponentAttr,
- commonTagRE: commonTagRE,
- reservedTagRE: reservedTagRE,
- get warn () { return warn; }
- });
-
- var uid = 0;
-
- function initMixin (Vue) {
- /**
- * The main init sequence. This is called for every
- * instance, including ones that are created from extended
- * constructors.
- *
- * @param {Object} options - this options object should be
- * the result of merging class
- * options and the options passed
- * in to the constructor.
- */
-
- Vue.prototype._init = function (options) {
- options = options || {};
-
- this.$el = null;
- this.$parent = options.parent;
- this.$root = this.$parent ? this.$parent.$root : this;
- this.$children = [];
- this.$refs = {}; // child vm references
- this.$els = {}; // element references
- this._watchers = []; // all watchers as an array
- this._directives = []; // all directives
-
- // a uid
- this._uid = uid++;
-
- // a flag to avoid this being observed
- this._isVue = true;
-
- // events bookkeeping
- this._events = {}; // registered callbacks
- this._eventsCount = {}; // for $broadcast optimization
-
- // fragment instance properties
- this._isFragment = false;
- this._fragment = // @type {DocumentFragment}
- this._fragmentStart = // @type {Text|Comment}
- this._fragmentEnd = null; // @type {Text|Comment}
-
- // lifecycle state
- this._isCompiled = this._isDestroyed = this._isReady = this._isAttached = this._isBeingDestroyed = this._vForRemoving = false;
- this._unlinkFn = null;
-
- // context:
- // if this is a transcluded component, context
- // will be the common parent vm of this instance
- // and its host.
- this._context = options._context || this.$parent;
-
- // scope:
- // if this is inside an inline v-for, the scope
- // will be the intermediate scope created for this
- // repeat fragment. this is used for linking props
- // and container directives.
- this._scope = options._scope;
-
- // fragment:
- // if this instance is compiled inside a Fragment, it
- // needs to reigster itself as a child of that fragment
- // for attach/detach to work properly.
- this._frag = options._frag;
- if (this._frag) {
- this._frag.children.push(this);
- }
-
- // push self into parent / transclusion host
- if (this.$parent) {
- this.$parent.$children.push(this);
- }
-
- // merge options.
- options = this.$options = mergeOptions(this.constructor.options, options, this);
-
- // set ref
- this._updateRef();
-
- // initialize data as empty object.
- // it will be filled up in _initData().
- this._data = {};
-
- // call init hook
- this._callHook('init');
-
- // initialize data observation and scope inheritance.
- this._initState();
-
- // setup event system and option events.
- this._initEvents();
-
- // call created hook
- this._callHook('created');
-
- // if `el` option is passed, start compilation.
- if (options.el) {
- this.$mount(options.el);
- }
- };
- }
-
- var pathCache = new Cache(1000);
-
- // actions
- var APPEND = 0;
- var PUSH = 1;
- var INC_SUB_PATH_DEPTH = 2;
- var PUSH_SUB_PATH = 3;
-
- // states
- var BEFORE_PATH = 0;
- var IN_PATH = 1;
- var BEFORE_IDENT = 2;
- var IN_IDENT = 3;
- var IN_SUB_PATH = 4;
- var IN_SINGLE_QUOTE = 5;
- var IN_DOUBLE_QUOTE = 6;
- var AFTER_PATH = 7;
- var ERROR = 8;
-
- var pathStateMachine = [];
-
- pathStateMachine[BEFORE_PATH] = {
- 'ws': [BEFORE_PATH],
- 'ident': [IN_IDENT, APPEND],
- '[': [IN_SUB_PATH],
- 'eof': [AFTER_PATH]
- };
-
- pathStateMachine[IN_PATH] = {
- 'ws': [IN_PATH],
- '.': [BEFORE_IDENT],
- '[': [IN_SUB_PATH],
- 'eof': [AFTER_PATH]
- };
-
- pathStateMachine[BEFORE_IDENT] = {
- 'ws': [BEFORE_IDENT],
- 'ident': [IN_IDENT, APPEND]
- };
-
- pathStateMachine[IN_IDENT] = {
- 'ident': [IN_IDENT, APPEND],
- '0': [IN_IDENT, APPEND],
- 'number': [IN_IDENT, APPEND],
- 'ws': [IN_PATH, PUSH],
- '.': [BEFORE_IDENT, PUSH],
- '[': [IN_SUB_PATH, PUSH],
- 'eof': [AFTER_PATH, PUSH]
- };
-
- pathStateMachine[IN_SUB_PATH] = {
- "'": [IN_SINGLE_QUOTE, APPEND],
- '"': [IN_DOUBLE_QUOTE, APPEND],
- '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
- ']': [IN_PATH, PUSH_SUB_PATH],
- 'eof': ERROR,
- 'else': [IN_SUB_PATH, APPEND]
- };
-
- pathStateMachine[IN_SINGLE_QUOTE] = {
- "'": [IN_SUB_PATH, APPEND],
- 'eof': ERROR,
- 'else': [IN_SINGLE_QUOTE, APPEND]
- };
-
- pathStateMachine[IN_DOUBLE_QUOTE] = {
- '"': [IN_SUB_PATH, APPEND],
- 'eof': ERROR,
- 'else': [IN_DOUBLE_QUOTE, APPEND]
- };
-
- /**
- * Determine the type of a character in a keypath.
- *
- * @param {Char} ch
- * @return {String} type
- */
-
- function getPathCharType(ch) {
- if (ch === undefined) {
- return 'eof';
- }
-
- var code = ch.charCodeAt(0);
-
- switch (code) {
- case 0x5B: // [
- case 0x5D: // ]
- case 0x2E: // .
- case 0x22: // "
- case 0x27: // '
- case 0x30:
- // 0
- return ch;
-
- case 0x5F: // _
- case 0x24:
- // $
- return 'ident';
-
- case 0x20: // Space
- case 0x09: // Tab
- case 0x0A: // Newline
- case 0x0D: // Return
- case 0xA0: // No-break space
- case 0xFEFF: // Byte Order Mark
- case 0x2028: // Line Separator
- case 0x2029:
- // Paragraph Separator
- return 'ws';
- }
-
- // a-z, A-Z
- if (code >= 0x61 && code <= 0x7A || code >= 0x41 && code <= 0x5A) {
- return 'ident';
- }
-
- // 1-9
- if (code >= 0x31 && code <= 0x39) {
- return 'number';
- }
-
- return 'else';
- }
-
- /**
- * Format a subPath, return its plain form if it is
- * a literal string or number. Otherwise prepend the
- * dynamic indicator (*).
- *
- * @param {String} path
- * @return {String}
- */
-
- function formatSubPath(path) {
- var trimmed = path.trim();
- // invalid leading 0
- if (path.charAt(0) === '0' && isNaN(path)) {
- return false;
- }
- return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed;
- }
-
- /**
- * Parse a string path into an array of segments
- *
- * @param {String} path
- * @return {Array|undefined}
- */
-
- function parse(path) {
- var keys = [];
- var index = -1;
- var mode = BEFORE_PATH;
- var subPathDepth = 0;
- var c, newChar, key, type, transition, action, typeMap;
-
- var actions = [];
-
- actions[PUSH] = function () {
- if (key !== undefined) {
- keys.push(key);
- key = undefined;
- }
- };
-
- actions[APPEND] = function () {
- if (key === undefined) {
- key = newChar;
- } else {
- key += newChar;
- }
- };
-
- actions[INC_SUB_PATH_DEPTH] = function () {
- actions[APPEND]();
- subPathDepth++;
- };
-
- actions[PUSH_SUB_PATH] = function () {
- if (subPathDepth > 0) {
- subPathDepth--;
- mode = IN_SUB_PATH;
- actions[APPEND]();
- } else {
- subPathDepth = 0;
- key = formatSubPath(key);
- if (key === false) {
- return false;
- } else {
- actions[PUSH]();
- }
- }
- };
-
- function maybeUnescapeQuote() {
- var nextChar = path[index + 1];
- if (mode === IN_SINGLE_QUOTE && nextChar === "'" || mode === IN_DOUBLE_QUOTE && nextChar === '"') {
- index++;
- newChar = '\\' + nextChar;
- actions[APPEND]();
- return true;
- }
- }
-
- while (mode != null) {
- index++;
- c = path[index];
-
- if (c === '\\' && maybeUnescapeQuote()) {
- continue;
- }
-
- type = getPathCharType(c);
- typeMap = pathStateMachine[mode];
- transition = typeMap[type] || typeMap['else'] || ERROR;
-
- if (transition === ERROR) {
- return; // parse error
- }
-
- mode = transition[0];
- action = actions[transition[1]];
- if (action) {
- newChar = transition[2];
- newChar = newChar === undefined ? c : newChar;
- if (action() === false) {
- return;
- }
- }
-
- if (mode === AFTER_PATH) {
- keys.raw = path;
- return keys;
- }
- }
- }
-
- /**
- * External parse that check for a cache hit first
- *
- * @param {String} path
- * @return {Array|undefined}
- */
-
- function parsePath(path) {
- var hit = pathCache.get(path);
- if (!hit) {
- hit = parse(path);
- if (hit) {
- pathCache.put(path, hit);
- }
- }
- return hit;
- }
-
- /**
- * Get from an object from a path string
- *
- * @param {Object} obj
- * @param {String} path
- */
-
- function getPath(obj, path) {
- return parseExpression(path).get(obj);
- }
-
- /**
- * Warn against setting non-existent root path on a vm.
- */
-
- var warnNonExistent;
- if (process.env.NODE_ENV !== 'production') {
- warnNonExistent = function (path, vm) {
- warn('You are setting a non-existent path "' + path.raw + '" ' + 'on a vm instance. Consider pre-initializing the property ' + 'with the "data" option for more reliable reactivity ' + 'and better performance.', vm);
- };
- }
-
- /**
- * Set on an object from a path
- *
- * @param {Object} obj
- * @param {String | Array} path
- * @param {*} val
- */
-
- function setPath(obj, path, val) {
- var original = obj;
- if (typeof path === 'string') {
- path = parse(path);
- }
- if (!path || !isObject(obj)) {
- return false;
- }
- var last, key;
- for (var i = 0, l = path.length; i < l; i++) {
- last = obj;
- key = path[i];
- if (key.charAt(0) === '*') {
- key = parseExpression(key.slice(1)).get.call(original, original);
- }
- if (i < l - 1) {
- obj = obj[key];
- if (!isObject(obj)) {
- obj = {};
- if (process.env.NODE_ENV !== 'production' && last._isVue) {
- warnNonExistent(path, last);
- }
- set(last, key, obj);
- }
- } else {
- if (isArray(obj)) {
- obj.$set(key, val);
- } else if (key in obj) {
- obj[key] = val;
- } else {
- if (process.env.NODE_ENV !== 'production' && obj._isVue) {
- warnNonExistent(path, obj);
- }
- set(obj, key, val);
- }
- }
- }
- return true;
- }
-
- var path = Object.freeze({
- parsePath: parsePath,
- getPath: getPath,
- setPath: setPath
- });
-
- var expressionCache = new Cache(1000);
-
- var allowedKeywords = 'Math,Date,this,true,false,null,undefined,Infinity,NaN,' + 'isNaN,isFinite,decodeURI,decodeURIComponent,encodeURI,' + 'encodeURIComponent,parseInt,parseFloat';
- var allowedKeywordsRE = new RegExp('^(' + allowedKeywords.replace(/,/g, '\\b|') + '\\b)');
-
- // keywords that don't make sense inside expressions
- var improperKeywords = 'break,case,class,catch,const,continue,debugger,default,' + 'delete,do,else,export,extends,finally,for,function,if,' + 'import,in,instanceof,let,return,super,switch,throw,try,' + 'var,while,with,yield,enum,await,implements,package,' + 'protected,static,interface,private,public';
- var improperKeywordsRE = new RegExp('^(' + improperKeywords.replace(/,/g, '\\b|') + '\\b)');
-
- var wsRE = /\s/g;
- var newlineRE = /\n/g;
- var saveRE = /[\{,]\s*[\w\$_]+\s*:|('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`)|new |typeof |void /g;
- var restoreRE = /"(\d+)"/g;
- var pathTestRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/;
- var identRE = /[^\w$\.](?:[A-Za-z_$][\w$]*)/g;
- var booleanLiteralRE = /^(?:true|false)$/;
-
- /**
- * Save / Rewrite / Restore
- *
- * When rewriting paths found in an expression, it is
- * possible for the same letter sequences to be found in
- * strings and Object literal property keys. Therefore we
- * remove and store these parts in a temporary array, and
- * restore them after the path rewrite.
- */
-
- var saved = [];
-
- /**
- * Save replacer
- *
- * The save regex can match two possible cases:
- * 1. An opening object literal
- * 2. A string
- * If matched as a plain string, we need to escape its
- * newlines, since the string needs to be preserved when
- * generating the function body.
- *
- * @param {String} str
- * @param {String} isString - str if matched as a string
- * @return {String} - placeholder with index
- */
-
- function save(str, isString) {
- var i = saved.length;
- saved[i] = isString ? str.replace(newlineRE, '\\n') : str;
- return '"' + i + '"';
- }
-
- /**
- * Path rewrite replacer
- *
- * @param {String} raw
- * @return {String}
- */
-
- function rewrite(raw) {
- var c = raw.charAt(0);
- var path = raw.slice(1);
- if (allowedKeywordsRE.test(path)) {
- return raw;
- } else {
- path = path.indexOf('"') > -1 ? path.replace(restoreRE, restore) : path;
- return c + 'scope.' + path;
- }
- }
-
- /**
- * Restore replacer
- *
- * @param {String} str
- * @param {String} i - matched save index
- * @return {String}
- */
-
- function restore(str, i) {
- return saved[i];
- }
-
- /**
- * Rewrite an expression, prefixing all path accessors with
- * `scope.` and generate getter/setter functions.
- *
- * @param {String} exp
- * @return {Function}
- */
-
- function compileGetter(exp) {
- if (improperKeywordsRE.test(exp)) {
- process.env.NODE_ENV !== 'production' && warn('Avoid using reserved keywords in expression: ' + exp);
- }
- // reset state
- saved.length = 0;
- // save strings and object literal keys
- var body = exp.replace(saveRE, save).replace(wsRE, '');
- // rewrite all paths
- // pad 1 space here becaue the regex matches 1 extra char
- body = (' ' + body).replace(identRE, rewrite).replace(restoreRE, restore);
- return makeGetterFn(body);
- }
-
- /**
- * Build a getter function. Requires eval.
- *
- * We isolate the try/catch so it doesn't affect the
- * optimization of the parse function when it is not called.
- *
- * @param {String} body
- * @return {Function|undefined}
- */
-
- function makeGetterFn(body) {
- try {
- /* eslint-disable no-new-func */
- return new Function('scope', 'return ' + body + ';');
- /* eslint-enable no-new-func */
- } catch (e) {
- process.env.NODE_ENV !== 'production' && warn('Invalid expression. ' + 'Generated function body: ' + body);
- }
- }
-
- /**
- * Compile a setter function for the expression.
- *
- * @param {String} exp
- * @return {Function|undefined}
- */
-
- function compileSetter(exp) {
- var path = parsePath(exp);
- if (path) {
- return function (scope, val) {
- setPath(scope, path, val);
- };
- } else {
- process.env.NODE_ENV !== 'production' && warn('Invalid setter expression: ' + exp);
- }
- }
-
- /**
- * Parse an expression into re-written getter/setters.
- *
- * @param {String} exp
- * @param {Boolean} needSet
- * @return {Function}
- */
-
- function parseExpression(exp, needSet) {
- exp = exp.trim();
- // try cache
- var hit = expressionCache.get(exp);
- if (hit) {
- if (needSet && !hit.set) {
- hit.set = compileSetter(hit.exp);
- }
- return hit;
- }
- var res = { exp: exp };
- res.get = isSimplePath(exp) && exp.indexOf('[') < 0
- // optimized super simple getter
- ? makeGetterFn('scope.' + exp)
- // dynamic getter
- : compileGetter(exp);
- if (needSet) {
- res.set = compileSetter(exp);
- }
- expressionCache.put(exp, res);
- return res;
- }
-
- /**
- * Check if an expression is a simple path.
- *
- * @param {String} exp
- * @return {Boolean}
- */
-
- function isSimplePath(exp) {
- return pathTestRE.test(exp) &&
- // don't treat true/false as paths
- !booleanLiteralRE.test(exp) &&
- // Math constants e.g. Math.PI, Math.E etc.
- exp.slice(0, 5) !== 'Math.';
- }
-
- var expression = Object.freeze({
- parseExpression: parseExpression,
- isSimplePath: isSimplePath
- });
-
- // we have two separate queues: one for directive updates
- // and one for user watcher registered via $watch().
- // we want to guarantee directive updates to be called
- // before user watchers so that when user watchers are
- // triggered, the DOM would have already been in updated
- // state.
-
- var queue = [];
- var userQueue = [];
- var has = {};
- var circular = {};
- var waiting = false;
-
- /**
- * Reset the batcher's state.
- */
-
- function resetBatcherState() {
- queue.length = 0;
- userQueue.length = 0;
- has = {};
- circular = {};
- waiting = false;
- }
-
- /**
- * Flush both queues and run the watchers.
- */
-
- function flushBatcherQueue() {
- var _again = true;
-
- _function: while (_again) {
- _again = false;
-
- runBatcherQueue(queue);
- runBatcherQueue(userQueue);
- // user watchers triggered more watchers,
- // keep flushing until it depletes
- if (queue.length) {
- _again = true;
- continue _function;
- }
- // dev tool hook
- /* istanbul ignore if */
- if (devtools && config.devtools) {
- devtools.emit('flush');
- }
- resetBatcherState();
- }
- }
-
- /**
- * Run the watchers in a single queue.
- *
- * @param {Array} queue
- */
-
- function runBatcherQueue(queue) {
- // do not cache length because more watchers might be pushed
- // as we run existing watchers
- for (var i = 0; i < queue.length; i++) {
- var watcher = queue[i];
- var id = watcher.id;
- has[id] = null;
- watcher.run();
- // in dev build, check and stop circular updates.
- if (process.env.NODE_ENV !== 'production' && has[id] != null) {
- circular[id] = (circular[id] || 0) + 1;
- if (circular[id] > config._maxUpdateCount) {
- warn('You may have an infinite update loop for watcher ' + 'with expression "' + watcher.expression + '"', watcher.vm);
- break;
- }
- }
- }
- queue.length = 0;
- }
-
- /**
- * Push a watcher into the watcher queue.
- * Jobs with duplicate IDs will be skipped unless it's
- * pushed when the queue is being flushed.
- *
- * @param {Watcher} watcher
- * properties:
- * - {Number} id
- * - {Function} run
- */
-
- function pushWatcher(watcher) {
- var id = watcher.id;
- if (has[id] == null) {
- // push watcher into appropriate queue
- var q = watcher.user ? userQueue : queue;
- has[id] = q.length;
- q.push(watcher);
- // queue the flush
- if (!waiting) {
- waiting = true;
- nextTick(flushBatcherQueue);
- }
- }
- }
-
- var uid$2 = 0;
-
- /**
- * A watcher parses an expression, collects dependencies,
- * and fires callback when the expression value changes.
- * This is used for both the $watch() api and directives.
- *
- * @param {Vue} vm
- * @param {String|Function} expOrFn
- * @param {Function} cb
- * @param {Object} options
- * - {Array} filters
- * - {Boolean} twoWay
- * - {Boolean} deep
- * - {Boolean} user
- * - {Boolean} sync
- * - {Boolean} lazy
- * - {Function} [preProcess]
- * - {Function} [postProcess]
- * @constructor
- */
- function Watcher(vm, expOrFn, cb, options) {
- // mix in options
- if (options) {
- extend(this, options);
- }
- var isFn = typeof expOrFn === 'function';
- this.vm = vm;
- vm._watchers.push(this);
- this.expression = expOrFn;
- this.cb = cb;
- this.id = ++uid$2; // uid for batching
- this.active = true;
- this.dirty = this.lazy; // for lazy watchers
- this.deps = [];
- this.newDeps = [];
- this.depIds = new _Set();
- this.newDepIds = new _Set();
- this.prevError = null; // for async error stacks
- // parse expression for getter/setter
- if (isFn) {
- this.getter = expOrFn;
- this.setter = undefined;
- } else {
- var res = parseExpression(expOrFn, this.twoWay);
- this.getter = res.get;
- this.setter = res.set;
- }
- this.value = this.lazy ? undefined : this.get();
- // state for avoiding false triggers for deep and Array
- // watchers during vm._digest()
- this.queued = this.shallow = false;
- }
-
- /**
- * Evaluate the getter, and re-collect dependencies.
- */
-
- Watcher.prototype.get = function () {
- this.beforeGet();
- var scope = this.scope || this.vm;
- var value;
- try {
- value = this.getter.call(scope, scope);
- } catch (e) {
- if (process.env.NODE_ENV !== 'production' && config.warnExpressionErrors) {
- warn('Error when evaluating expression ' + '"' + this.expression + '": ' + e.toString(), this.vm);
- }
- }
- // "touch" every property so they are all tracked as
- // dependencies for deep watching
- if (this.deep) {
- traverse(value);
- }
- if (this.preProcess) {
- value = this.preProcess(value);
- }
- if (this.filters) {
- value = scope._applyFilters(value, null, this.filters, false);
- }
- if (this.postProcess) {
- value = this.postProcess(value);
- }
- this.afterGet();
- return value;
- };
-
- /**
- * Set the corresponding value with the setter.
- *
- * @param {*} value
- */
-
- Watcher.prototype.set = function (value) {
- var scope = this.scope || this.vm;
- if (this.filters) {
- value = scope._applyFilters(value, this.value, this.filters, true);
- }
- try {
- this.setter.call(scope, scope, value);
- } catch (e) {
- if (process.env.NODE_ENV !== 'production' && config.warnExpressionErrors) {
- warn('Error when evaluating setter ' + '"' + this.expression + '": ' + e.toString(), this.vm);
- }
- }
- // two-way sync for v-for alias
- var forContext = scope.$forContext;
- if (forContext && forContext.alias === this.expression) {
- if (forContext.filters) {
- process.env.NODE_ENV !== 'production' && warn('It seems you are using two-way binding on ' + 'a v-for alias (' + this.expression + '), and the ' + 'v-for has filters. This will not work properly. ' + 'Either remove the filters or use an array of ' + 'objects and bind to object properties instead.', this.vm);
- return;
- }
- forContext._withLock(function () {
- if (scope.$key) {
- // original is an object
- forContext.rawValue[scope.$key] = value;
- } else {
- forContext.rawValue.$set(scope.$index, value);
- }
- });
- }
- };
-
- /**
- * Prepare for dependency collection.
- */
-
- Watcher.prototype.beforeGet = function () {
- Dep.target = this;
- };
-
- /**
- * Add a dependency to this directive.
- *
- * @param {Dep} dep
- */
-
- Watcher.prototype.addDep = function (dep) {
- var id = dep.id;
- if (!this.newDepIds.has(id)) {
- this.newDepIds.add(id);
- this.newDeps.push(dep);
- if (!this.depIds.has(id)) {
- dep.addSub(this);
- }
- }
- };
-
- /**
- * Clean up for dependency collection.
- */
-
- Watcher.prototype.afterGet = function () {
- Dep.target = null;
- var i = this.deps.length;
- while (i--) {
- var dep = this.deps[i];
- if (!this.newDepIds.has(dep.id)) {
- dep.removeSub(this);
- }
- }
- var tmp = this.depIds;
- this.depIds = this.newDepIds;
- this.newDepIds = tmp;
- this.newDepIds.clear();
- tmp = this.deps;
- this.deps = this.newDeps;
- this.newDeps = tmp;
- this.newDeps.length = 0;
- };
-
- /**
- * Subscriber interface.
- * Will be called when a dependency changes.
- *
- * @param {Boolean} shallow
- */
-
- Watcher.prototype.update = function (shallow) {
- if (this.lazy) {
- this.dirty = true;
- } else if (this.sync || !config.async) {
- this.run();
- } else {
- // if queued, only overwrite shallow with non-shallow,
- // but not the other way around.
- this.shallow = this.queued ? shallow ? this.shallow : false : !!shallow;
- this.queued = true;
- // record before-push error stack in debug mode
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production' && config.debug) {
- this.prevError = new Error('[vue] async stack trace');
- }
- pushWatcher(this);
- }
- };
-
- /**
- * Batcher job interface.
- * Will be called by the batcher.
- */
-
- Watcher.prototype.run = function () {
- if (this.active) {
- var value = this.get();
- if (value !== this.value ||
- // Deep watchers and watchers on Object/Arrays should fire even
- // when the value is the same, because the value may
- // have mutated; but only do so if this is a
- // non-shallow update (caused by a vm digest).
- (isObject(value) || this.deep) && !this.shallow) {
- // set new value
- var oldValue = this.value;
- this.value = value;
- // in debug + async mode, when a watcher callbacks
- // throws, we also throw the saved before-push error
- // so the full cross-tick stack trace is available.
- var prevError = this.prevError;
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production' && config.debug && prevError) {
- this.prevError = null;
- try {
- this.cb.call(this.vm, value, oldValue);
- } catch (e) {
- nextTick(function () {
- throw prevError;
- }, 0);
- throw e;
- }
- } else {
- this.cb.call(this.vm, value, oldValue);
- }
- }
- this.queued = this.shallow = false;
- }
- };
-
- /**
- * Evaluate the value of the watcher.
- * This only gets called for lazy watchers.
- */
-
- Watcher.prototype.evaluate = function () {
- // avoid overwriting another watcher that is being
- // collected.
- var current = Dep.target;
- this.value = this.get();
- this.dirty = false;
- Dep.target = current;
- };
-
- /**
- * Depend on all deps collected by this watcher.
- */
-
- Watcher.prototype.depend = function () {
- var i = this.deps.length;
- while (i--) {
- this.deps[i].depend();
- }
- };
-
- /**
- * Remove self from all dependencies' subcriber list.
- */
-
- Watcher.prototype.teardown = function () {
- if (this.active) {
- // remove self from vm's watcher list
- // this is a somewhat expensive operation so we skip it
- // if the vm is being destroyed or is performing a v-for
- // re-render (the watcher list is then filtered by v-for).
- if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
- this.vm._watchers.$remove(this);
- }
- var i = this.deps.length;
- while (i--) {
- this.deps[i].removeSub(this);
- }
- this.active = false;
- this.vm = this.cb = this.value = null;
- }
- };
-
- /**
- * Recrusively traverse an object to evoke all converted
- * getters, so that every nested property inside the object
- * is collected as a "deep" dependency.
- *
- * @param {*} val
- */
-
- var seenObjects = new _Set();
- function traverse(val, seen) {
- var i = undefined,
- keys = undefined;
- if (!seen) {
- seen = seenObjects;
- seen.clear();
- }
- var isA = isArray(val);
- var isO = isObject(val);
- if (isA || isO) {
- if (val.__ob__) {
- var depId = val.__ob__.dep.id;
- if (seen.has(depId)) {
- return;
- } else {
- seen.add(depId);
- }
- }
- if (isA) {
- i = val.length;
- while (i--) traverse(val[i], seen);
- } else if (isO) {
- keys = Object.keys(val);
- i = keys.length;
- while (i--) traverse(val[keys[i]], seen);
- }
- }
- }
-
- var text$1 = {
-
- bind: function bind() {
- this.attr = this.el.nodeType === 3 ? 'data' : 'textContent';
- },
-
- update: function update(value) {
- this.el[this.attr] = _toString(value);
- }
- };
-
- var templateCache = new Cache(1000);
- var idSelectorCache = new Cache(1000);
-
- var map = {
- efault: [0, '', ''],
- legend: [1, '<fieldset>', '</fieldset>'],
- tr: [2, '<table><tbody>', '</tbody></table>'],
- col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>']
- };
-
- map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
-
- map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
-
- map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
-
- map.g = map.defs = map.symbol = map.use = map.image = map.text = map.circle = map.ellipse = map.line = map.path = map.polygon = map.polyline = map.rect = [1, '<svg ' + 'xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'xmlns:ev="http://www.w3.org/2001/xml-events"' + 'version="1.1">', '</svg>'];
-
- /**
- * Check if a node is a supported template node with a
- * DocumentFragment content.
- *
- * @param {Node} node
- * @return {Boolean}
- */
-
- function isRealTemplate(node) {
- return isTemplate(node) && isFragment(node.content);
- }
-
- var tagRE$1 = /<([\w:-]+)/;
- var entityRE = /&#?\w+?;/;
-
- /**
- * Convert a string template to a DocumentFragment.
- * Determines correct wrapping by tag types. Wrapping
- * strategy found in jQuery & component/domify.
- *
- * @param {String} templateString
- * @param {Boolean} raw
- * @return {DocumentFragment}
- */
-
- function stringToFragment(templateString, raw) {
- // try a cache hit first
- var cacheKey = raw ? templateString : templateString.trim();
- var hit = templateCache.get(cacheKey);
- if (hit) {
- return hit;
- }
-
- var frag = document.createDocumentFragment();
- var tagMatch = templateString.match(tagRE$1);
- var entityMatch = entityRE.test(templateString);
-
- if (!tagMatch && !entityMatch) {
- // text only, return a single text node.
- frag.appendChild(document.createTextNode(templateString));
- } else {
- var tag = tagMatch && tagMatch[1];
- var wrap = map[tag] || map.efault;
- var depth = wrap[0];
- var prefix = wrap[1];
- var suffix = wrap[2];
- var node = document.createElement('div');
-
- node.innerHTML = prefix + templateString + suffix;
- while (depth--) {
- node = node.lastChild;
- }
-
- var child;
- /* eslint-disable no-cond-assign */
- while (child = node.firstChild) {
- /* eslint-enable no-cond-assign */
- frag.appendChild(child);
- }
- }
- if (!raw) {
- trimNode(frag);
- }
- templateCache.put(cacheKey, frag);
- return frag;
- }
-
- /**
- * Convert a template node to a DocumentFragment.
- *
- * @param {Node} node
- * @return {DocumentFragment}
- */
-
- function nodeToFragment(node) {
- // if its a template tag and the browser supports it,
- // its content is already a document fragment. However, iOS Safari has
- // bug when using directly cloned template content with touch
- // events and can cause crashes when the nodes are removed from DOM, so we
- // have to treat template elements as string templates. (#2805)
- /* istanbul ignore if */
- if (isRealTemplate(node)) {
- return stringToFragment(node.innerHTML);
- }
- // script template
- if (node.tagName === 'SCRIPT') {
- return stringToFragment(node.textContent);
- }
- // normal node, clone it to avoid mutating the original
- var clonedNode = cloneNode(node);
- var frag = document.createDocumentFragment();
- var child;
- /* eslint-disable no-cond-assign */
- while (child = clonedNode.firstChild) {
- /* eslint-enable no-cond-assign */
- frag.appendChild(child);
- }
- trimNode(frag);
- return frag;
- }
-
- // Test for the presence of the Safari template cloning bug
- // https://bugs.webkit.org/showug.cgi?id=137755
- var hasBrokenTemplate = (function () {
- /* istanbul ignore else */
- if (inBrowser) {
- var a = document.createElement('div');
- a.innerHTML = '<template>1</template>';
- return !a.cloneNode(true).firstChild.innerHTML;
- } else {
- return false;
- }
- })();
-
- // Test for IE10/11 textarea placeholder clone bug
- var hasTextareaCloneBug = (function () {
- /* istanbul ignore else */
- if (inBrowser) {
- var t = document.createElement('textarea');
- t.placeholder = 't';
- return t.cloneNode(true).value === 't';
- } else {
- return false;
- }
- })();
-
- /**
- * 1. Deal with Safari cloning nested <template> bug by
- * manually cloning all template instances.
- * 2. Deal with IE10/11 textarea placeholder bug by setting
- * the correct value after cloning.
- *
- * @param {Element|DocumentFragment} node
- * @return {Element|DocumentFragment}
- */
-
- function cloneNode(node) {
- /* istanbul ignore if */
- if (!node.querySelectorAll) {
- return node.cloneNode();
- }
- var res = node.cloneNode(true);
- var i, original, cloned;
- /* istanbul ignore if */
- if (hasBrokenTemplate) {
- var tempClone = res;
- if (isRealTemplate(node)) {
- node = node.content;
- tempClone = res.content;
- }
- original = node.querySelectorAll('template');
- if (original.length) {
- cloned = tempClone.querySelectorAll('template');
- i = cloned.length;
- while (i--) {
- cloned[i].parentNode.replaceChild(cloneNode(original[i]), cloned[i]);
- }
- }
- }
- /* istanbul ignore if */
- if (hasTextareaCloneBug) {
- if (node.tagName === 'TEXTAREA') {
- res.value = node.value;
- } else {
- original = node.querySelectorAll('textarea');
- if (original.length) {
- cloned = res.querySelectorAll('textarea');
- i = cloned.length;
- while (i--) {
- cloned[i].value = original[i].value;
- }
- }
- }
- }
- return res;
- }
-
- /**
- * Process the template option and normalizes it into a
- * a DocumentFragment that can be used as a partial or a
- * instance template.
- *
- * @param {*} template
- * Possible values include:
- * - DocumentFragment object
- * - Node object of type Template
- * - id selector: '#some-template-id'
- * - template string: '<div><span>{{msg}}</span></div>'
- * @param {Boolean} shouldClone
- * @param {Boolean} raw
- * inline HTML interpolation. Do not check for id
- * selector and keep whitespace in the string.
- * @return {DocumentFragment|undefined}
- */
-
- function parseTemplate(template, shouldClone, raw) {
- var node, frag;
-
- // if the template is already a document fragment,
- // do nothing
- if (isFragment(template)) {
- trimNode(template);
- return shouldClone ? cloneNode(template) : template;
- }
-
- if (typeof template === 'string') {
- // id selector
- if (!raw && template.charAt(0) === '#') {
- // id selector can be cached too
- frag = idSelectorCache.get(template);
- if (!frag) {
- node = document.getElementById(template.slice(1));
- if (node) {
- frag = nodeToFragment(node);
- // save selector to cache
- idSelectorCache.put(template, frag);
- }
- }
- } else {
- // normal string template
- frag = stringToFragment(template, raw);
- }
- } else if (template.nodeType) {
- // a direct node
- frag = nodeToFragment(template);
- }
-
- return frag && shouldClone ? cloneNode(frag) : frag;
- }
-
- var template = Object.freeze({
- cloneNode: cloneNode,
- parseTemplate: parseTemplate
- });
-
- var html = {
-
- bind: function bind() {
- // a comment node means this is a binding for
- // {{{ inline unescaped html }}}
- if (this.el.nodeType === 8) {
- // hold nodes
- this.nodes = [];
- // replace the placeholder with proper anchor
- this.anchor = createAnchor('v-html');
- replace(this.el, this.anchor);
- }
- },
-
- update: function update(value) {
- value = _toString(value);
- if (this.nodes) {
- this.swap(value);
- } else {
- this.el.innerHTML = value;
- }
- },
-
- swap: function swap(value) {
- // remove old nodes
- var i = this.nodes.length;
- while (i--) {
- remove(this.nodes[i]);
- }
- // convert new value to a fragment
- // do not attempt to retrieve from id selector
- var frag = parseTemplate(value, true, true);
- // save a reference to these nodes so we can remove later
- this.nodes = toArray(frag.childNodes);
- before(frag, this.anchor);
- }
- };
-
- /**
- * Abstraction for a partially-compiled fragment.
- * Can optionally compile content with a child scope.
- *
- * @param {Function} linker
- * @param {Vue} vm
- * @param {DocumentFragment} frag
- * @param {Vue} [host]
- * @param {Object} [scope]
- * @param {Fragment} [parentFrag]
- */
- function Fragment(linker, vm, frag, host, scope, parentFrag) {
- this.children = [];
- this.childFrags = [];
- this.vm = vm;
- this.scope = scope;
- this.inserted = false;
- this.parentFrag = parentFrag;
- if (parentFrag) {
- parentFrag.childFrags.push(this);
- }
- this.unlink = linker(vm, frag, host, scope, this);
- var single = this.single = frag.childNodes.length === 1 &&
- // do not go single mode if the only node is an anchor
- !frag.childNodes[0].__v_anchor;
- if (single) {
- this.node = frag.childNodes[0];
- this.before = singleBefore;
- this.remove = singleRemove;
- } else {
- this.node = createAnchor('fragment-start');
- this.end = createAnchor('fragment-end');
- this.frag = frag;
- prepend(this.node, frag);
- frag.appendChild(this.end);
- this.before = multiBefore;
- this.remove = multiRemove;
- }
- this.node.__v_frag = this;
- }
-
- /**
- * Call attach/detach for all components contained within
- * this fragment. Also do so recursively for all child
- * fragments.
- *
- * @param {Function} hook
- */
-
- Fragment.prototype.callHook = function (hook) {
- var i, l;
- for (i = 0, l = this.childFrags.length; i < l; i++) {
- this.childFrags[i].callHook(hook);
- }
- for (i = 0, l = this.children.length; i < l; i++) {
- hook(this.children[i]);
- }
- };
-
- /**
- * Insert fragment before target, single node version
- *
- * @param {Node} target
- * @param {Boolean} withTransition
- */
-
- function singleBefore(target, withTransition) {
- this.inserted = true;
- var method = withTransition !== false ? beforeWithTransition : before;
- method(this.node, target, this.vm);
- if (inDoc(this.node)) {
- this.callHook(attach);
- }
- }
-
- /**
- * Remove fragment, single node version
- */
-
- function singleRemove() {
- this.inserted = false;
- var shouldCallRemove = inDoc(this.node);
- var self = this;
- this.beforeRemove();
- removeWithTransition(this.node, this.vm, function () {
- if (shouldCallRemove) {
- self.callHook(detach);
- }
- self.destroy();
- });
- }
-
- /**
- * Insert fragment before target, multi-nodes version
- *
- * @param {Node} target
- * @param {Boolean} withTransition
- */
-
- function multiBefore(target, withTransition) {
- this.inserted = true;
- var vm = this.vm;
- var method = withTransition !== false ? beforeWithTransition : before;
- mapNodeRange(this.node, this.end, function (node) {
- method(node, target, vm);
- });
- if (inDoc(this.node)) {
- this.callHook(attach);
- }
- }
-
- /**
- * Remove fragment, multi-nodes version
- */
-
- function multiRemove() {
- this.inserted = false;
- var self = this;
- var shouldCallRemove = inDoc(this.node);
- this.beforeRemove();
- removeNodeRange(this.node, this.end, this.vm, this.frag, function () {
- if (shouldCallRemove) {
- self.callHook(detach);
- }
- self.destroy();
- });
- }
-
- /**
- * Prepare the fragment for removal.
- */
-
- Fragment.prototype.beforeRemove = function () {
- var i, l;
- for (i = 0, l = this.childFrags.length; i < l; i++) {
- // call the same method recursively on child
- // fragments, depth-first
- this.childFrags[i].beforeRemove(false);
- }
- for (i = 0, l = this.children.length; i < l; i++) {
- // Call destroy for all contained instances,
- // with remove:false and defer:true.
- // Defer is necessary because we need to
- // keep the children to call detach hooks
- // on them.
- this.children[i].$destroy(false, true);
- }
- var dirs = this.unlink.dirs;
- for (i = 0, l = dirs.length; i < l; i++) {
- // disable the watchers on all the directives
- // so that the rendered content stays the same
- // during removal.
- dirs[i]._watcher && dirs[i]._watcher.teardown();
- }
- };
-
- /**
- * Destroy the fragment.
- */
-
- Fragment.prototype.destroy = function () {
- if (this.parentFrag) {
- this.parentFrag.childFrags.$remove(this);
- }
- this.node.__v_frag = null;
- this.unlink();
- };
-
- /**
- * Call attach hook for a Vue instance.
- *
- * @param {Vue} child
- */
-
- function attach(child) {
- if (!child._isAttached && inDoc(child.$el)) {
- child._callHook('attached');
- }
- }
-
- /**
- * Call detach hook for a Vue instance.
- *
- * @param {Vue} child
- */
-
- function detach(child) {
- if (child._isAttached && !inDoc(child.$el)) {
- child._callHook('detached');
- }
- }
-
- var linkerCache = new Cache(5000);
-
- /**
- * A factory that can be used to create instances of a
- * fragment. Caches the compiled linker if possible.
- *
- * @param {Vue} vm
- * @param {Element|String} el
- */
- function FragmentFactory(vm, el) {
- this.vm = vm;
- var template;
- var isString = typeof el === 'string';
- if (isString || isTemplate(el) && !el.hasAttribute('v-if')) {
- template = parseTemplate(el, true);
- } else {
- template = document.createDocumentFragment();
- template.appendChild(el);
- }
- this.template = template;
- // linker can be cached, but only for components
- var linker;
- var cid = vm.constructor.cid;
- if (cid > 0) {
- var cacheId = cid + (isString ? el : getOuterHTML(el));
- linker = linkerCache.get(cacheId);
- if (!linker) {
- linker = compile(template, vm.$options, true);
- linkerCache.put(cacheId, linker);
- }
- } else {
- linker = compile(template, vm.$options, true);
- }
- this.linker = linker;
- }
-
- /**
- * Create a fragment instance with given host and scope.
- *
- * @param {Vue} host
- * @param {Object} scope
- * @param {Fragment} parentFrag
- */
-
- FragmentFactory.prototype.create = function (host, scope, parentFrag) {
- var frag = cloneNode(this.template);
- return new Fragment(this.linker, this.vm, frag, host, scope, parentFrag);
- };
-
- var ON = 700;
- var MODEL = 800;
- var BIND = 850;
- var TRANSITION = 1100;
- var EL = 1500;
- var COMPONENT = 1500;
- var PARTIAL = 1750;
- var IF = 2100;
- var FOR = 2200;
- var SLOT = 2300;
-
- var uid$3 = 0;
-
- var vFor = {
-
- priority: FOR,
- terminal: true,
-
- params: ['track-by', 'stagger', 'enter-stagger', 'leave-stagger'],
-
- bind: function bind() {
- // support "item in/of items" syntax
- var inMatch = this.expression.match(/(.*) (?:in|of) (.*)/);
- if (inMatch) {
- var itMatch = inMatch[1].match(/\((.*),(.*)\)/);
- if (itMatch) {
- this.iterator = itMatch[1].trim();
- this.alias = itMatch[2].trim();
- } else {
- this.alias = inMatch[1].trim();
- }
- this.expression = inMatch[2];
- }
-
- if (!this.alias) {
- process.env.NODE_ENV !== 'production' && warn('Invalid v-for expression "' + this.descriptor.raw + '": ' + 'alias is required.', this.vm);
- return;
- }
-
- // uid as a cache identifier
- this.id = '__v-for__' + ++uid$3;
-
- // check if this is an option list,
- // so that we know if we need to update the <select>'s
- // v-model when the option list has changed.
- // because v-model has a lower priority than v-for,
- // the v-model is not bound here yet, so we have to
- // retrive it in the actual updateModel() function.
- var tag = this.el.tagName;
- this.isOption = (tag === 'OPTION' || tag === 'OPTGROUP') && this.el.parentNode.tagName === 'SELECT';
-
- // setup anchor nodes
- this.start = createAnchor('v-for-start');
- this.end = createAnchor('v-for-end');
- replace(this.el, this.end);
- before(this.start, this.end);
-
- // cache
- this.cache = Object.create(null);
-
- // fragment factory
- this.factory = new FragmentFactory(this.vm, this.el);
- },
-
- update: function update(data) {
- this.diff(data);
- this.updateRef();
- this.updateModel();
- },
-
- /**
- * Diff, based on new data and old data, determine the
- * minimum amount of DOM manipulations needed to make the
- * DOM reflect the new data Array.
- *
- * The algorithm diffs the new data Array by storing a
- * hidden reference to an owner vm instance on previously
- * seen data. This allows us to achieve O(n) which is
- * better than a levenshtein distance based algorithm,
- * which is O(m * n).
- *
- * @param {Array} data
- */
-
- diff: function diff(data) {
- // check if the Array was converted from an Object
- var item = data[0];
- var convertedFromObject = this.fromObject = isObject(item) && hasOwn(item, '$key') && hasOwn(item, '$value');
-
- var trackByKey = this.params.trackBy;
- var oldFrags = this.frags;
- var frags = this.frags = new Array(data.length);
- var alias = this.alias;
- var iterator = this.iterator;
- var start = this.start;
- var end = this.end;
- var inDocument = inDoc(start);
- var init = !oldFrags;
- var i, l, frag, key, value, primitive;
-
- // First pass, go through the new Array and fill up
- // the new frags array. If a piece of data has a cached
- // instance for it, we reuse it. Otherwise build a new
- // instance.
- for (i = 0, l = data.length; i < l; i++) {
- item = data[i];
- key = convertedFromObject ? item.$key : null;
- value = convertedFromObject ? item.$value : item;
- primitive = !isObject(value);
- frag = !init && this.getCachedFrag(value, i, key);
- if (frag) {
- // reusable fragment
- frag.reused = true;
- // update $index
- frag.scope.$index = i;
- // update $key
- if (key) {
- frag.scope.$key = key;
- }
- // update iterator
- if (iterator) {
- frag.scope[iterator] = key !== null ? key : i;
- }
- // update data for track-by, object repeat &
- // primitive values.
- if (trackByKey || convertedFromObject || primitive) {
- withoutConversion(function () {
- frag.scope[alias] = value;
- });
- }
- } else {
- // new isntance
- frag = this.create(value, alias, i, key);
- frag.fresh = !init;
- }
- frags[i] = frag;
- if (init) {
- frag.before(end);
- }
- }
-
- // we're done for the initial render.
- if (init) {
- return;
- }
-
- // Second pass, go through the old fragments and
- // destroy those who are not reused (and remove them
- // from cache)
- var removalIndex = 0;
- var totalRemoved = oldFrags.length - frags.length;
- // when removing a large number of fragments, watcher removal
- // turns out to be a perf bottleneck, so we batch the watcher
- // removals into a single filter call!
- this.vm._vForRemoving = true;
- for (i = 0, l = oldFrags.length; i < l; i++) {
- frag = oldFrags[i];
- if (!frag.reused) {
- this.deleteCachedFrag(frag);
- this.remove(frag, removalIndex++, totalRemoved, inDocument);
- }
- }
- this.vm._vForRemoving = false;
- if (removalIndex) {
- this.vm._watchers = this.vm._watchers.filter(function (w) {
- return w.active;
- });
- }
-
- // Final pass, move/insert new fragments into the
- // right place.
- var targetPrev, prevEl, currentPrev;
- var insertionIndex = 0;
- for (i = 0, l = frags.length; i < l; i++) {
- frag = frags[i];
- // this is the frag that we should be after
- targetPrev = frags[i - 1];
- prevEl = targetPrev ? targetPrev.staggerCb ? targetPrev.staggerAnchor : targetPrev.end || targetPrev.node : start;
- if (frag.reused && !frag.staggerCb) {
- currentPrev = findPrevFrag(frag, start, this.id);
- if (currentPrev !== targetPrev && (!currentPrev ||
- // optimization for moving a single item.
- // thanks to suggestions by @livoras in #1807
- findPrevFrag(currentPrev, start, this.id) !== targetPrev)) {
- this.move(frag, prevEl);
- }
- } else {
- // new instance, or still in stagger.
- // insert with updated stagger index.
- this.insert(frag, insertionIndex++, prevEl, inDocument);
- }
- frag.reused = frag.fresh = false;
- }
- },
-
- /**
- * Create a new fragment instance.
- *
- * @param {*} value
- * @param {String} alias
- * @param {Number} index
- * @param {String} [key]
- * @return {Fragment}
- */
-
- create: function create(value, alias, index, key) {
- var host = this._host;
- // create iteration scope
- var parentScope = this._scope || this.vm;
- var scope = Object.create(parentScope);
- // ref holder for the scope
- scope.$refs = Object.create(parentScope.$refs);
- scope.$els = Object.create(parentScope.$els);
- // make sure point $parent to parent scope
- scope.$parent = parentScope;
- // for two-way binding on alias
- scope.$forContext = this;
- // define scope properties
- // important: define the scope alias without forced conversion
- // so that frozen data structures remain non-reactive.
- withoutConversion(function () {
- defineReactive(scope, alias, value);
- });
- defineReactive(scope, '$index', index);
- if (key) {
- defineReactive(scope, '$key', key);
- } else if (scope.$key) {
- // avoid accidental fallback
- def(scope, '$key', null);
- }
- if (this.iterator) {
- defineReactive(scope, this.iterator, key !== null ? key : index);
- }
- var frag = this.factory.create(host, scope, this._frag);
- frag.forId = this.id;
- this.cacheFrag(value, frag, index, key);
- return frag;
- },
-
- /**
- * Update the v-ref on owner vm.
- */
-
- updateRef: function updateRef() {
- var ref = this.descriptor.ref;
- if (!ref) return;
- var hash = (this._scope || this.vm).$refs;
- var refs;
- if (!this.fromObject) {
- refs = this.frags.map(findVmFromFrag);
- } else {
- refs = {};
- this.frags.forEach(function (frag) {
- refs[frag.scope.$key] = findVmFromFrag(frag);
- });
- }
- hash[ref] = refs;
- },
-
- /**
- * For option lists, update the containing v-model on
- * parent <select>.
- */
-
- updateModel: function updateModel() {
- if (this.isOption) {
- var parent = this.start.parentNode;
- var model = parent && parent.__v_model;
- if (model) {
- model.forceUpdate();
- }
- }
- },
-
- /**
- * Insert a fragment. Handles staggering.
- *
- * @param {Fragment} frag
- * @param {Number} index
- * @param {Node} prevEl
- * @param {Boolean} inDocument
- */
-
- insert: function insert(frag, index, prevEl, inDocument) {
- if (frag.staggerCb) {
- frag.staggerCb.cancel();
- frag.staggerCb = null;
- }
- var staggerAmount = this.getStagger(frag, index, null, 'enter');
- if (inDocument && staggerAmount) {
- // create an anchor and insert it synchronously,
- // so that we can resolve the correct order without
- // worrying about some elements not inserted yet
- var anchor = frag.staggerAnchor;
- if (!anchor) {
- anchor = frag.staggerAnchor = createAnchor('stagger-anchor');
- anchor.__v_frag = frag;
- }
- after(anchor, prevEl);
- var op = frag.staggerCb = cancellable(function () {
- frag.staggerCb = null;
- frag.before(anchor);
- remove(anchor);
- });
- setTimeout(op, staggerAmount);
- } else {
- var target = prevEl.nextSibling;
- /* istanbul ignore if */
- if (!target) {
- // reset end anchor position in case the position was messed up
- // by an external drag-n-drop library.
- after(this.end, prevEl);
- target = this.end;
- }
- frag.before(target);
- }
- },
-
- /**
- * Remove a fragment. Handles staggering.
- *
- * @param {Fragment} frag
- * @param {Number} index
- * @param {Number} total
- * @param {Boolean} inDocument
- */
-
- remove: function remove(frag, index, total, inDocument) {
- if (frag.staggerCb) {
- frag.staggerCb.cancel();
- frag.staggerCb = null;
- // it's not possible for the same frag to be removed
- // twice, so if we have a pending stagger callback,
- // it means this frag is queued for enter but removed
- // before its transition started. Since it is already
- // destroyed, we can just leave it in detached state.
- return;
- }
- var staggerAmount = this.getStagger(frag, index, total, 'leave');
- if (inDocument && staggerAmount) {
- var op = frag.staggerCb = cancellable(function () {
- frag.staggerCb = null;
- frag.remove();
- });
- setTimeout(op, staggerAmount);
- } else {
- frag.remove();
- }
- },
-
- /**
- * Move a fragment to a new position.
- * Force no transition.
- *
- * @param {Fragment} frag
- * @param {Node} prevEl
- */
-
- move: function move(frag, prevEl) {
- // fix a common issue with Sortable:
- // if prevEl doesn't have nextSibling, this means it's
- // been dragged after the end anchor. Just re-position
- // the end anchor to the end of the container.
- /* istanbul ignore if */
- if (!prevEl.nextSibling) {
- this.end.parentNode.appendChild(this.end);
- }
- frag.before(prevEl.nextSibling, false);
- },
-
- /**
- * Cache a fragment using track-by or the object key.
- *
- * @param {*} value
- * @param {Fragment} frag
- * @param {Number} index
- * @param {String} [key]
- */
-
- cacheFrag: function cacheFrag(value, frag, index, key) {
- var trackByKey = this.params.trackBy;
- var cache = this.cache;
- var primitive = !isObject(value);
- var id;
- if (key || trackByKey || primitive) {
- id = getTrackByKey(index, key, value, trackByKey);
- if (!cache[id]) {
- cache[id] = frag;
- } else if (trackByKey !== '$index') {
- process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
- }
- } else {
- id = this.id;
- if (hasOwn(value, id)) {
- if (value[id] === null) {
- value[id] = frag;
- } else {
- process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
- }
- } else if (Object.isExtensible(value)) {
- def(value, id, frag);
- } else if (process.env.NODE_ENV !== 'production') {
- warn('Frozen v-for objects cannot be automatically tracked, make sure to ' + 'provide a track-by key.');
- }
- }
- frag.raw = value;
- },
-
- /**
- * Get a cached fragment from the value/index/key
- *
- * @param {*} value
- * @param {Number} index
- * @param {String} key
- * @return {Fragment}
- */
-
- getCachedFrag: function getCachedFrag(value, index, key) {
- var trackByKey = this.params.trackBy;
- var primitive = !isObject(value);
- var frag;
- if (key || trackByKey || primitive) {
- var id = getTrackByKey(index, key, value, trackByKey);
- frag = this.cache[id];
- } else {
- frag = value[this.id];
- }
- if (frag && (frag.reused || frag.fresh)) {
- process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
- }
- return frag;
- },
-
- /**
- * Delete a fragment from cache.
- *
- * @param {Fragment} frag
- */
-
- deleteCachedFrag: function deleteCachedFrag(frag) {
- var value = frag.raw;
- var trackByKey = this.params.trackBy;
- var scope = frag.scope;
- var index = scope.$index;
- // fix #948: avoid accidentally fall through to
- // a parent repeater which happens to have $key.
- var key = hasOwn(scope, '$key') && scope.$key;
- var primitive = !isObject(value);
- if (trackByKey || key || primitive) {
- var id = getTrackByKey(index, key, value, trackByKey);
- this.cache[id] = null;
- } else {
- value[this.id] = null;
- frag.raw = null;
- }
- },
-
- /**
- * Get the stagger amount for an insertion/removal.
- *
- * @param {Fragment} frag
- * @param {Number} index
- * @param {Number} total
- * @param {String} type
- */
-
- getStagger: function getStagger(frag, index, total, type) {
- type = type + 'Stagger';
- var trans = frag.node.__v_trans;
- var hooks = trans && trans.hooks;
- var hook = hooks && (hooks[type] || hooks.stagger);
- return hook ? hook.call(frag, index, total) : index * parseInt(this.params[type] || this.params.stagger, 10);
- },
-
- /**
- * Pre-process the value before piping it through the
- * filters. This is passed to and called by the watcher.
- */
-
- _preProcess: function _preProcess(value) {
- // regardless of type, store the un-filtered raw value.
- this.rawValue = value;
- return value;
- },
-
- /**
- * Post-process the value after it has been piped through
- * the filters. This is passed to and called by the watcher.
- *
- * It is necessary for this to be called during the
- * wathcer's dependency collection phase because we want
- * the v-for to update when the source Object is mutated.
- */
-
- _postProcess: function _postProcess(value) {
- if (isArray(value)) {
- return value;
- } else if (isPlainObject(value)) {
- // convert plain object to array.
- var keys = Object.keys(value);
- var i = keys.length;
- var res = new Array(i);
- var key;
- while (i--) {
- key = keys[i];
- res[i] = {
- $key: key,
- $value: value[key]
- };
- }
- return res;
- } else {
- if (typeof value === 'number' && !isNaN(value)) {
- value = range(value);
- }
- return value || [];
- }
- },
-
- unbind: function unbind() {
- if (this.descriptor.ref) {
- (this._scope || this.vm).$refs[this.descriptor.ref] = null;
- }
- if (this.frags) {
- var i = this.frags.length;
- var frag;
- while (i--) {
- frag = this.frags[i];
- this.deleteCachedFrag(frag);
- frag.destroy();
- }
- }
- }
- };
-
- /**
- * Helper to find the previous element that is a fragment
- * anchor. This is necessary because a destroyed frag's
- * element could still be lingering in the DOM before its
- * leaving transition finishes, but its inserted flag
- * should have been set to false so we can skip them.
- *
- * If this is a block repeat, we want to make sure we only
- * return frag that is bound to this v-for. (see #929)
- *
- * @param {Fragment} frag
- * @param {Comment|Text} anchor
- * @param {String} id
- * @return {Fragment}
- */
-
- function findPrevFrag(frag, anchor, id) {
- var el = frag.node.previousSibling;
- /* istanbul ignore if */
- if (!el) return;
- frag = el.__v_frag;
- while ((!frag || frag.forId !== id || !frag.inserted) && el !== anchor) {
- el = el.previousSibling;
- /* istanbul ignore if */
- if (!el) return;
- frag = el.__v_frag;
- }
- return frag;
- }
-
- /**
- * Find a vm from a fragment.
- *
- * @param {Fragment} frag
- * @return {Vue|undefined}
- */
-
- function findVmFromFrag(frag) {
- var node = frag.node;
- // handle multi-node frag
- if (frag.end) {
- while (!node.__vue__ && node !== frag.end && node.nextSibling) {
- node = node.nextSibling;
- }
- }
- return node.__vue__;
- }
-
- /**
- * Create a range array from given number.
- *
- * @param {Number} n
- * @return {Array}
- */
-
- function range(n) {
- var i = -1;
- var ret = new Array(Math.floor(n));
- while (++i < n) {
- ret[i] = i;
- }
- return ret;
- }
-
- /**
- * Get the track by key for an item.
- *
- * @param {Number} index
- * @param {String} key
- * @param {*} value
- * @param {String} [trackByKey]
- */
-
- function getTrackByKey(index, key, value, trackByKey) {
- return trackByKey ? trackByKey === '$index' ? index : trackByKey.charAt(0).match(/\w/) ? getPath(value, trackByKey) : value[trackByKey] : key || value;
- }
-
- if (process.env.NODE_ENV !== 'production') {
- vFor.warnDuplicate = function (value) {
- warn('Duplicate value found in v-for="' + this.descriptor.raw + '": ' + JSON.stringify(value) + '. Use track-by="$index" if ' + 'you are expecting duplicate values.', this.vm);
- };
- }
-
- var vIf = {
-
- priority: IF,
- terminal: true,
-
- bind: function bind() {
- var el = this.el;
- if (!el.__vue__) {
- // check else block
- var next = el.nextElementSibling;
- if (next && getAttr(next, 'v-else') !== null) {
- remove(next);
- this.elseEl = next;
- }
- // check main block
- this.anchor = createAnchor('v-if');
- replace(el, this.anchor);
- } else {
- process.env.NODE_ENV !== 'production' && warn('v-if="' + this.expression + '" cannot be ' + 'used on an instance root element.', this.vm);
- this.invalid = true;
- }
- },
-
- update: function update(value) {
- if (this.invalid) return;
- if (value) {
- if (!this.frag) {
- this.insert();
- }
- } else {
- this.remove();
- }
- },
-
- insert: function insert() {
- if (this.elseFrag) {
- this.elseFrag.remove();
- this.elseFrag = null;
- }
- // lazy init factory
- if (!this.factory) {
- this.factory = new FragmentFactory(this.vm, this.el);
- }
- this.frag = this.factory.create(this._host, this._scope, this._frag);
- this.frag.before(this.anchor);
- },
-
- remove: function remove() {
- if (this.frag) {
- this.frag.remove();
- this.frag = null;
- }
- if (this.elseEl && !this.elseFrag) {
- if (!this.elseFactory) {
- this.elseFactory = new FragmentFactory(this.elseEl._context || this.vm, this.elseEl);
- }
- this.elseFrag = this.elseFactory.create(this._host, this._scope, this._frag);
- this.elseFrag.before(this.anchor);
- }
- },
-
- unbind: function unbind() {
- if (this.frag) {
- this.frag.destroy();
- }
- if (this.elseFrag) {
- this.elseFrag.destroy();
- }
- }
- };
-
- var show = {
-
- bind: function bind() {
- // check else block
- var next = this.el.nextElementSibling;
- if (next && getAttr(next, 'v-else') !== null) {
- this.elseEl = next;
- }
- },
-
- update: function update(value) {
- this.apply(this.el, value);
- if (this.elseEl) {
- this.apply(this.elseEl, !value);
- }
- },
-
- apply: function apply(el, value) {
- if (inDoc(el)) {
- applyTransition(el, value ? 1 : -1, toggle, this.vm);
- } else {
- toggle();
- }
- function toggle() {
- el.style.display = value ? '' : 'none';
- }
- }
- };
-
- var text$2 = {
-
- bind: function bind() {
- var self = this;
- var el = this.el;
- var isRange = el.type === 'range';
- var lazy = this.params.lazy;
- var number = this.params.number;
- var debounce = this.params.debounce;
-
- // handle composition events.
- // http://blog.evanyou.me/2014/01/03/composition-event/
- // skip this for Android because it handles composition
- // events quite differently. Android doesn't trigger
- // composition events for language input methods e.g.
- // Chinese, but instead triggers them for spelling
- // suggestions... (see Discussion/#162)
- var composing = false;
- if (!isAndroid && !isRange) {
- this.on('compositionstart', function () {
- composing = true;
- });
- this.on('compositionend', function () {
- composing = false;
- // in IE11 the "compositionend" event fires AFTER
- // the "input" event, so the input handler is blocked
- // at the end... have to call it here.
- //
- // #1327: in lazy mode this is unecessary.
- if (!lazy) {
- self.listener();
- }
- });
- }
-
- // prevent messing with the input when user is typing,
- // and force update on blur.
- this.focused = false;
- if (!isRange && !lazy) {
- this.on('focus', function () {
- self.focused = true;
- });
- this.on('blur', function () {
- self.focused = false;
- // do not sync value after fragment removal (#2017)
- if (!self._frag || self._frag.inserted) {
- self.rawListener();
- }
- });
- }
-
- // Now attach the main listener
- this.listener = this.rawListener = function () {
- if (composing || !self._bound) {
- return;
- }
- var val = number || isRange ? toNumber(el.value) : el.value;
- self.set(val);
- // force update on next tick to avoid lock & same value
- // also only update when user is not typing
- nextTick(function () {
- if (self._bound && !self.focused) {
- self.update(self._watcher.value);
- }
- });
- };
-
- // apply debounce
- if (debounce) {
- this.listener = _debounce(this.listener, debounce);
- }
-
- // Support jQuery events, since jQuery.trigger() doesn't
- // trigger native events in some cases and some plugins
- // rely on $.trigger()
- //
- // We want to make sure if a listener is attached using
- // jQuery, it is also removed with jQuery, that's why
- // we do the check for each directive instance and
- // store that check result on itself. This also allows
- // easier test coverage control by unsetting the global
- // jQuery variable in tests.
- this.hasjQuery = typeof jQuery === 'function';
- if (this.hasjQuery) {
- var method = jQuery.fn.on ? 'on' : 'bind';
- jQuery(el)[method]('change', this.rawListener);
- if (!lazy) {
- jQuery(el)[method]('input', this.listener);
- }
- } else {
- this.on('change', this.rawListener);
- if (!lazy) {
- this.on('input', this.listener);
- }
- }
-
- // IE9 doesn't fire input event on backspace/del/cut
- if (!lazy && isIE9) {
- this.on('cut', function () {
- nextTick(self.listener);
- });
- this.on('keyup', function (e) {
- if (e.keyCode === 46 || e.keyCode === 8) {
- self.listener();
- }
- });
- }
-
- // set initial value if present
- if (el.hasAttribute('value') || el.tagName === 'TEXTAREA' && el.value.trim()) {
- this.afterBind = this.listener;
- }
- },
-
- update: function update(value) {
- this.el.value = _toString(value);
- },
-
- unbind: function unbind() {
- var el = this.el;
- if (this.hasjQuery) {
- var method = jQuery.fn.off ? 'off' : 'unbind';
- jQuery(el)[method]('change', this.listener);
- jQuery(el)[method]('input', this.listener);
- }
- }
- };
-
- var radio = {
-
- bind: function bind() {
- var self = this;
- var el = this.el;
-
- this.getValue = function () {
- // value overwrite via v-bind:value
- if (el.hasOwnProperty('_value')) {
- return el._value;
- }
- var val = el.value;
- if (self.params.number) {
- val = toNumber(val);
- }
- return val;
- };
-
- this.listener = function () {
- self.set(self.getValue());
- };
- this.on('change', this.listener);
-
- if (el.hasAttribute('checked')) {
- this.afterBind = this.listener;
- }
- },
-
- update: function update(value) {
- this.el.checked = looseEqual(value, this.getValue());
- }
- };
-
- var select = {
-
- bind: function bind() {
- var self = this;
- var el = this.el;
-
- // method to force update DOM using latest value.
- this.forceUpdate = function () {
- if (self._watcher) {
- self.update(self._watcher.get());
- }
- };
-
- // check if this is a multiple select
- var multiple = this.multiple = el.hasAttribute('multiple');
-
- // attach listener
- this.listener = function () {
- var value = getValue(el, multiple);
- value = self.params.number ? isArray(value) ? value.map(toNumber) : toNumber(value) : value;
- self.set(value);
- };
- this.on('change', this.listener);
-
- // if has initial value, set afterBind
- var initValue = getValue(el, multiple, true);
- if (multiple && initValue.length || !multiple && initValue !== null) {
- this.afterBind = this.listener;
- }
-
- // All major browsers except Firefox resets
- // selectedIndex with value -1 to 0 when the element
- // is appended to a new parent, therefore we have to
- // force a DOM update whenever that happens...
- this.vm.$on('hook:attached', this.forceUpdate);
- },
-
- update: function update(value) {
- var el = this.el;
- el.selectedIndex = -1;
- var multi = this.multiple && isArray(value);
- var options = el.options;
- var i = options.length;
- var op, val;
- while (i--) {
- op = options[i];
- val = op.hasOwnProperty('_value') ? op._value : op.value;
- /* eslint-disable eqeqeq */
- op.selected = multi ? indexOf$1(value, val) > -1 : looseEqual(value, val);
- /* eslint-enable eqeqeq */
- }
- },
-
- unbind: function unbind() {
- /* istanbul ignore next */
- this.vm.$off('hook:attached', this.forceUpdate);
- }
- };
-
- /**
- * Get select value
- *
- * @param {SelectElement} el
- * @param {Boolean} multi
- * @param {Boolean} init
- * @return {Array|*}
- */
-
- function getValue(el, multi, init) {
- var res = multi ? [] : null;
- var op, val, selected;
- for (var i = 0, l = el.options.length; i < l; i++) {
- op = el.options[i];
- selected = init ? op.hasAttribute('selected') : op.selected;
- if (selected) {
- val = op.hasOwnProperty('_value') ? op._value : op.value;
- if (multi) {
- res.push(val);
- } else {
- return val;
- }
- }
- }
- return res;
- }
-
- /**
- * Native Array.indexOf uses strict equal, but in this
- * case we need to match string/numbers with custom equal.
- *
- * @param {Array} arr
- * @param {*} val
- */
-
- function indexOf$1(arr, val) {
- var i = arr.length;
- while (i--) {
- if (looseEqual(arr[i], val)) {
- return i;
- }
- }
- return -1;
- }
-
- var checkbox = {
-
- bind: function bind() {
- var self = this;
- var el = this.el;
-
- this.getValue = function () {
- return el.hasOwnProperty('_value') ? el._value : self.params.number ? toNumber(el.value) : el.value;
- };
-
- function getBooleanValue() {
- var val = el.checked;
- if (val && el.hasOwnProperty('_trueValue')) {
- return el._trueValue;
- }
- if (!val && el.hasOwnProperty('_falseValue')) {
- return el._falseValue;
- }
- return val;
- }
-
- this.listener = function () {
- var model = self._watcher.value;
- if (isArray(model)) {
- var val = self.getValue();
- if (el.checked) {
- if (indexOf(model, val) < 0) {
- model.push(val);
- }
- } else {
- model.$remove(val);
- }
- } else {
- self.set(getBooleanValue());
- }
- };
-
- this.on('change', this.listener);
- if (el.hasAttribute('checked')) {
- this.afterBind = this.listener;
- }
- },
-
- update: function update(value) {
- var el = this.el;
- if (isArray(value)) {
- el.checked = indexOf(value, this.getValue()) > -1;
- } else {
- if (el.hasOwnProperty('_trueValue')) {
- el.checked = looseEqual(value, el._trueValue);
- } else {
- el.checked = !!value;
- }
- }
- }
- };
-
- var handlers = {
- text: text$2,
- radio: radio,
- select: select,
- checkbox: checkbox
- };
-
- var model = {
-
- priority: MODEL,
- twoWay: true,
- handlers: handlers,
- params: ['lazy', 'number', 'debounce'],
-
- /**
- * Possible elements:
- * <select>
- * <textarea>
- * <input type="*">
- * - text
- * - checkbox
- * - radio
- * - number
- */
-
- bind: function bind() {
- // friendly warning...
- this.checkFilters();
- if (this.hasRead && !this.hasWrite) {
- process.env.NODE_ENV !== 'production' && warn('It seems you are using a read-only filter with ' + 'v-model="' + this.descriptor.raw + '". ' + 'You might want to use a two-way filter to ensure correct behavior.', this.vm);
- }
- var el = this.el;
- var tag = el.tagName;
- var handler;
- if (tag === 'INPUT') {
- handler = handlers[el.type] || handlers.text;
- } else if (tag === 'SELECT') {
- handler = handlers.select;
- } else if (tag === 'TEXTAREA') {
- handler = handlers.text;
- } else {
- process.env.NODE_ENV !== 'production' && warn('v-model does not support element type: ' + tag, this.vm);
- return;
- }
- el.__v_model = this;
- handler.bind.call(this);
- this.update = handler.update;
- this._unbind = handler.unbind;
- },
-
- /**
- * Check read/write filter stats.
- */
-
- checkFilters: function checkFilters() {
- var filters = this.filters;
- if (!filters) return;
- var i = filters.length;
- while (i--) {
- var filter = resolveAsset(this.vm.$options, 'filters', filters[i].name);
- if (typeof filter === 'function' || filter.read) {
- this.hasRead = true;
- }
- if (filter.write) {
- this.hasWrite = true;
- }
- }
- },
-
- unbind: function unbind() {
- this.el.__v_model = null;
- this._unbind && this._unbind();
- }
- };
-
- // keyCode aliases
- var keyCodes = {
- esc: 27,
- tab: 9,
- enter: 13,
- space: 32,
- 'delete': [8, 46],
- up: 38,
- left: 37,
- right: 39,
- down: 40
- };
-
- function keyFilter(handler, keys) {
- var codes = keys.map(function (key) {
- var charCode = key.charCodeAt(0);
- if (charCode > 47 && charCode < 58) {
- return parseInt(key, 10);
- }
- if (key.length === 1) {
- charCode = key.toUpperCase().charCodeAt(0);
- if (charCode > 64 && charCode < 91) {
- return charCode;
- }
- }
- return keyCodes[key];
- });
- codes = [].concat.apply([], codes);
- return function keyHandler(e) {
- if (codes.indexOf(e.keyCode) > -1) {
- return handler.call(this, e);
- }
- };
- }
-
- function stopFilter(handler) {
- return function stopHandler(e) {
- e.stopPropagation();
- return handler.call(this, e);
- };
- }
-
- function preventFilter(handler) {
- return function preventHandler(e) {
- e.preventDefault();
- return handler.call(this, e);
- };
- }
-
- function selfFilter(handler) {
- return function selfHandler(e) {
- if (e.target === e.currentTarget) {
- return handler.call(this, e);
- }
- };
- }
-
- var on$1 = {
-
- priority: ON,
- acceptStatement: true,
- keyCodes: keyCodes,
-
- bind: function bind() {
- // deal with iframes
- if (this.el.tagName === 'IFRAME' && this.arg !== 'load') {
- var self = this;
- this.iframeBind = function () {
- on(self.el.contentWindow, self.arg, self.handler, self.modifiers.capture);
- };
- this.on('load', this.iframeBind);
- }
- },
-
- update: function update(handler) {
- // stub a noop for v-on with no value,
- // e.g. @mousedown.prevent
- if (!this.descriptor.raw) {
- handler = function () {};
- }
-
- if (typeof handler !== 'function') {
- process.env.NODE_ENV !== 'production' && warn('v-on:' + this.arg + '="' + this.expression + '" expects a function value, ' + 'got ' + handler, this.vm);
- return;
- }
-
- // apply modifiers
- if (this.modifiers.stop) {
- handler = stopFilter(handler);
- }
- if (this.modifiers.prevent) {
- handler = preventFilter(handler);
- }
- if (this.modifiers.self) {
- handler = selfFilter(handler);
- }
- // key filter
- var keys = Object.keys(this.modifiers).filter(function (key) {
- return key !== 'stop' && key !== 'prevent' && key !== 'self' && key !== 'capture';
- });
- if (keys.length) {
- handler = keyFilter(handler, keys);
- }
-
- this.reset();
- this.handler = handler;
-
- if (this.iframeBind) {
- this.iframeBind();
- } else {
- on(this.el, this.arg, this.handler, this.modifiers.capture);
- }
- },
-
- reset: function reset() {
- var el = this.iframeBind ? this.el.contentWindow : this.el;
- if (this.handler) {
- off(el, this.arg, this.handler);
- }
- },
-
- unbind: function unbind() {
- this.reset();
- }
- };
-
- var prefixes = ['-webkit-', '-moz-', '-ms-'];
- var camelPrefixes = ['Webkit', 'Moz', 'ms'];
- var importantRE = /!important;?$/;
- var propCache = Object.create(null);
-
- var testEl = null;
-
- var style = {
-
- deep: true,
-
- update: function update(value) {
- if (typeof value === 'string') {
- this.el.style.cssText = value;
- } else if (isArray(value)) {
- this.handleObject(value.reduce(extend, {}));
- } else {
- this.handleObject(value || {});
- }
- },
-
- handleObject: function handleObject(value) {
- // cache object styles so that only changed props
- // are actually updated.
- var cache = this.cache || (this.cache = {});
- var name, val;
- for (name in cache) {
- if (!(name in value)) {
- this.handleSingle(name, null);
- delete cache[name];
- }
- }
- for (name in value) {
- val = value[name];
- if (val !== cache[name]) {
- cache[name] = val;
- this.handleSingle(name, val);
- }
- }
- },
-
- handleSingle: function handleSingle(prop, value) {
- prop = normalize(prop);
- if (!prop) return; // unsupported prop
- // cast possible numbers/booleans into strings
- if (value != null) value += '';
- if (value) {
- var isImportant = importantRE.test(value) ? 'important' : '';
- if (isImportant) {
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production') {
- warn('It\'s probably a bad idea to use !important with inline rules. ' + 'This feature will be deprecated in a future version of Vue.');
- }
- value = value.replace(importantRE, '').trim();
- this.el.style.setProperty(prop.kebab, value, isImportant);
- } else {
- this.el.style[prop.camel] = value;
- }
- } else {
- this.el.style[prop.camel] = '';
- }
- }
-
- };
-
- /**
- * Normalize a CSS property name.
- * - cache result
- * - auto prefix
- * - camelCase -> dash-case
- *
- * @param {String} prop
- * @return {String}
- */
-
- function normalize(prop) {
- if (propCache[prop]) {
- return propCache[prop];
- }
- var res = prefix(prop);
- propCache[prop] = propCache[res] = res;
- return res;
- }
-
- /**
- * Auto detect the appropriate prefix for a CSS property.
- * https://gist.github.com/paulirish/523692
- *
- * @param {String} prop
- * @return {String}
- */
-
- function prefix(prop) {
- prop = hyphenate(prop);
- var camel = camelize(prop);
- var upper = camel.charAt(0).toUpperCase() + camel.slice(1);
- if (!testEl) {
- testEl = document.createElement('div');
- }
- var i = prefixes.length;
- var prefixed;
- if (camel !== 'filter' && camel in testEl.style) {
- return {
- kebab: prop,
- camel: camel
- };
- }
- while (i--) {
- prefixed = camelPrefixes[i] + upper;
- if (prefixed in testEl.style) {
- return {
- kebab: prefixes[i] + prop,
- camel: prefixed
- };
- }
- }
- }
-
- // xlink
- var xlinkNS = 'http://www.w3.org/1999/xlink';
- var xlinkRE = /^xlink:/;
-
- // check for attributes that prohibit interpolations
- var disallowedInterpAttrRE = /^v-|^:|^@|^(?:is|transition|transition-mode|debounce|track-by|stagger|enter-stagger|leave-stagger)$/;
- // these attributes should also set their corresponding properties
- // because they only affect the initial state of the element
- var attrWithPropsRE = /^(?:value|checked|selected|muted)$/;
- // these attributes expect enumrated values of "true" or "false"
- // but are not boolean attributes
- var enumeratedAttrRE = /^(?:draggable|contenteditable|spellcheck)$/;
-
- // these attributes should set a hidden property for
- // binding v-model to object values
- var modelProps = {
- value: '_value',
- 'true-value': '_trueValue',
- 'false-value': '_falseValue'
- };
-
- var bind$1 = {
-
- priority: BIND,
-
- bind: function bind() {
- var attr = this.arg;
- var tag = this.el.tagName;
- // should be deep watch on object mode
- if (!attr) {
- this.deep = true;
- }
- // handle interpolation bindings
- var descriptor = this.descriptor;
- var tokens = descriptor.interp;
- if (tokens) {
- // handle interpolations with one-time tokens
- if (descriptor.hasOneTime) {
- this.expression = tokensToExp(tokens, this._scope || this.vm);
- }
-
- // only allow binding on native attributes
- if (disallowedInterpAttrRE.test(attr) || attr === 'name' && (tag === 'PARTIAL' || tag === 'SLOT')) {
- process.env.NODE_ENV !== 'production' && warn(attr + '="' + descriptor.raw + '": ' + 'attribute interpolation is not allowed in Vue.js ' + 'directives and special attributes.', this.vm);
- this.el.removeAttribute(attr);
- this.invalid = true;
- }
-
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production') {
- var raw = attr + '="' + descriptor.raw + '": ';
- // warn src
- if (attr === 'src') {
- warn(raw + 'interpolation in "src" attribute will cause ' + 'a 404 request. Use v-bind:src instead.', this.vm);
- }
-
- // warn style
- if (attr === 'style') {
- warn(raw + 'interpolation in "style" attribute will cause ' + 'the attribute to be discarded in Internet Explorer. ' + 'Use v-bind:style instead.', this.vm);
- }
- }
- }
- },
-
- update: function update(value) {
- if (this.invalid) {
- return;
- }
- var attr = this.arg;
- if (this.arg) {
- this.handleSingle(attr, value);
- } else {
- this.handleObject(value || {});
- }
- },
-
- // share object handler with v-bind:class
- handleObject: style.handleObject,
-
- handleSingle: function handleSingle(attr, value) {
- var el = this.el;
- var interp = this.descriptor.interp;
- if (this.modifiers.camel) {
- attr = camelize(attr);
- }
- if (!interp && attrWithPropsRE.test(attr) && attr in el) {
- var attrValue = attr === 'value' ? value == null // IE9 will set input.value to "null" for null...
- ? '' : value : value;
-
- if (el[attr] !== attrValue) {
- el[attr] = attrValue;
- }
- }
- // set model props
- var modelProp = modelProps[attr];
- if (!interp && modelProp) {
- el[modelProp] = value;
- // update v-model if present
- var model = el.__v_model;
- if (model) {
- model.listener();
- }
- }
- // do not set value attribute for textarea
- if (attr === 'value' && el.tagName === 'TEXTAREA') {
- el.removeAttribute(attr);
- return;
- }
- // update attribute
- if (enumeratedAttrRE.test(attr)) {
- el.setAttribute(attr, value ? 'true' : 'false');
- } else if (value != null && value !== false) {
- if (attr === 'class') {
- // handle edge case #1960:
- // class interpolation should not overwrite Vue transition class
- if (el.__v_trans) {
- value += ' ' + el.__v_trans.id + '-transition';
- }
- setClass(el, value);
- } else if (xlinkRE.test(attr)) {
- el.setAttributeNS(xlinkNS, attr, value === true ? '' : value);
- } else {
- el.setAttribute(attr, value === true ? '' : value);
- }
- } else {
- el.removeAttribute(attr);
- }
- }
- };
-
- var el = {
-
- priority: EL,
-
- bind: function bind() {
- /* istanbul ignore if */
- if (!this.arg) {
- return;
- }
- var id = this.id = camelize(this.arg);
- var refs = (this._scope || this.vm).$els;
- if (hasOwn(refs, id)) {
- refs[id] = this.el;
- } else {
- defineReactive(refs, id, this.el);
- }
- },
-
- unbind: function unbind() {
- var refs = (this._scope || this.vm).$els;
- if (refs[this.id] === this.el) {
- refs[this.id] = null;
- }
- }
- };
-
- var ref = {
- bind: function bind() {
- process.env.NODE_ENV !== 'production' && warn('v-ref:' + this.arg + ' must be used on a child ' + 'component. Found on <' + this.el.tagName.toLowerCase() + '>.', this.vm);
- }
- };
-
- var cloak = {
- bind: function bind() {
- var el = this.el;
- this.vm.$once('pre-hook:compiled', function () {
- el.removeAttribute('v-cloak');
- });
- }
- };
-
- // must export plain object
- var directives = {
- text: text$1,
- html: html,
- 'for': vFor,
- 'if': vIf,
- show: show,
- model: model,
- on: on$1,
- bind: bind$1,
- el: el,
- ref: ref,
- cloak: cloak
- };
-
- var vClass = {
-
- deep: true,
-
- update: function update(value) {
- if (!value) {
- this.cleanup();
- } else if (typeof value === 'string') {
- this.setClass(value.trim().split(/\s+/));
- } else {
- this.setClass(normalize$1(value));
- }
- },
-
- setClass: function setClass(value) {
- this.cleanup(value);
- for (var i = 0, l = value.length; i < l; i++) {
- var val = value[i];
- if (val) {
- apply(this.el, val, addClass);
- }
- }
- this.prevKeys = value;
- },
-
- cleanup: function cleanup(value) {
- var prevKeys = this.prevKeys;
- if (!prevKeys) return;
- var i = prevKeys.length;
- while (i--) {
- var key = prevKeys[i];
- if (!value || value.indexOf(key) < 0) {
- apply(this.el, key, removeClass);
- }
- }
- }
- };
-
- /**
- * Normalize objects and arrays (potentially containing objects)
- * into array of strings.
- *
- * @param {Object|Array<String|Object>} value
- * @return {Array<String>}
- */
-
- function normalize$1(value) {
- var res = [];
- if (isArray(value)) {
- for (var i = 0, l = value.length; i < l; i++) {
- var _key = value[i];
- if (_key) {
- if (typeof _key === 'string') {
- res.push(_key);
- } else {
- for (var k in _key) {
- if (_key[k]) res.push(k);
- }
- }
- }
- }
- } else if (isObject(value)) {
- for (var key in value) {
- if (value[key]) res.push(key);
- }
- }
- return res;
- }
-
- /**
- * Add or remove a class/classes on an element
- *
- * @param {Element} el
- * @param {String} key The class name. This may or may not
- * contain a space character, in such a
- * case we'll deal with multiple class
- * names at once.
- * @param {Function} fn
- */
-
- function apply(el, key, fn) {
- key = key.trim();
- if (key.indexOf(' ') === -1) {
- fn(el, key);
- return;
- }
- // The key contains one or more space characters.
- // Since a class name doesn't accept such characters, we
- // treat it as multiple classes.
- var keys = key.split(/\s+/);
- for (var i = 0, l = keys.length; i < l; i++) {
- fn(el, keys[i]);
- }
- }
-
- var component = {
-
- priority: COMPONENT,
-
- params: ['keep-alive', 'transition-mode', 'inline-template'],
-
- /**
- * Setup. Two possible usages:
- *
- * - static:
- * <comp> or <div v-component="comp">
- *
- * - dynamic:
- * <component :is="view">
- */
-
- bind: function bind() {
- if (!this.el.__vue__) {
- // keep-alive cache
- this.keepAlive = this.params.keepAlive;
- if (this.keepAlive) {
- this.cache = {};
- }
- // check inline-template
- if (this.params.inlineTemplate) {
- // extract inline template as a DocumentFragment
- this.inlineTemplate = extractContent(this.el, true);
- }
- // component resolution related state
- this.pendingComponentCb = this.Component = null;
- // transition related state
- this.pendingRemovals = 0;
- this.pendingRemovalCb = null;
- // create a ref anchor
- this.anchor = createAnchor('v-component');
- replace(this.el, this.anchor);
- // remove is attribute.
- // this is removed during compilation, but because compilation is
- // cached, when the component is used elsewhere this attribute
- // will remain at link time.
- this.el.removeAttribute('is');
- this.el.removeAttribute(':is');
- // remove ref, same as above
- if (this.descriptor.ref) {
- this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref));
- }
- // if static, build right now.
- if (this.literal) {
- this.setComponent(this.expression);
- }
- } else {
- process.env.NODE_ENV !== 'production' && warn('cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el);
- }
- },
-
- /**
- * Public update, called by the watcher in the dynamic
- * literal scenario, e.g. <component :is="view">
- */
-
- update: function update(value) {
- if (!this.literal) {
- this.setComponent(value);
- }
- },
-
- /**
- * Switch dynamic components. May resolve the component
- * asynchronously, and perform transition based on
- * specified transition mode. Accepts a few additional
- * arguments specifically for vue-router.
- *
- * The callback is called when the full transition is
- * finished.
- *
- * @param {String} value
- * @param {Function} [cb]
- */
-
- setComponent: function setComponent(value, cb) {
- this.invalidatePending();
- if (!value) {
- // just remove current
- this.unbuild(true);
- this.remove(this.childVM, cb);
- this.childVM = null;
- } else {
- var self = this;
- this.resolveComponent(value, function () {
- self.mountComponent(cb);
- });
- }
- },
-
- /**
- * Resolve the component constructor to use when creating
- * the child vm.
- *
- * @param {String|Function} value
- * @param {Function} cb
- */
-
- resolveComponent: function resolveComponent(value, cb) {
- var self = this;
- this.pendingComponentCb = cancellable(function (Component) {
- self.ComponentName = Component.options.name || (typeof value === 'string' ? value : null);
- self.Component = Component;
- cb();
- });
- this.vm._resolveComponent(value, this.pendingComponentCb);
- },
-
- /**
- * Create a new instance using the current constructor and
- * replace the existing instance. This method doesn't care
- * whether the new component and the old one are actually
- * the same.
- *
- * @param {Function} [cb]
- */
-
- mountComponent: function mountComponent(cb) {
- // actual mount
- this.unbuild(true);
- var self = this;
- var activateHooks = this.Component.options.activate;
- var cached = this.getCached();
- var newComponent = this.build();
- if (activateHooks && !cached) {
- this.waitingFor = newComponent;
- callActivateHooks(activateHooks, newComponent, function () {
- if (self.waitingFor !== newComponent) {
- return;
- }
- self.waitingFor = null;
- self.transition(newComponent, cb);
- });
- } else {
- // update ref for kept-alive component
- if (cached) {
- newComponent._updateRef();
- }
- this.transition(newComponent, cb);
- }
- },
-
- /**
- * When the component changes or unbinds before an async
- * constructor is resolved, we need to invalidate its
- * pending callback.
- */
-
- invalidatePending: function invalidatePending() {
- if (this.pendingComponentCb) {
- this.pendingComponentCb.cancel();
- this.pendingComponentCb = null;
- }
- },
-
- /**
- * Instantiate/insert a new child vm.
- * If keep alive and has cached instance, insert that
- * instance; otherwise build a new one and cache it.
- *
- * @param {Object} [extraOptions]
- * @return {Vue} - the created instance
- */
-
- build: function build(extraOptions) {
- var cached = this.getCached();
- if (cached) {
- return cached;
- }
- if (this.Component) {
- // default options
- var options = {
- name: this.ComponentName,
- el: cloneNode(this.el),
- template: this.inlineTemplate,
- // make sure to add the child with correct parent
- // if this is a transcluded component, its parent
- // should be the transclusion host.
- parent: this._host || this.vm,
- // if no inline-template, then the compiled
- // linker can be cached for better performance.
- _linkerCachable: !this.inlineTemplate,
- _ref: this.descriptor.ref,
- _asComponent: true,
- _isRouterView: this._isRouterView,
- // if this is a transcluded component, context
- // will be the common parent vm of this instance
- // and its host.
- _context: this.vm,
- // if this is inside an inline v-for, the scope
- // will be the intermediate scope created for this
- // repeat fragment. this is used for linking props
- // and container directives.
- _scope: this._scope,
- // pass in the owner fragment of this component.
- // this is necessary so that the fragment can keep
- // track of its contained components in order to
- // call attach/detach hooks for them.
- _frag: this._frag
- };
- // extra options
- // in 1.0.0 this is used by vue-router only
- /* istanbul ignore if */
- if (extraOptions) {
- extend(options, extraOptions);
- }
- var child = new this.Component(options);
- if (this.keepAlive) {
- this.cache[this.Component.cid] = child;
- }
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production' && this.el.hasAttribute('transition') && child._isFragment) {
- warn('Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template, child);
- }
- return child;
- }
- },
-
- /**
- * Try to get a cached instance of the current component.
- *
- * @return {Vue|undefined}
- */
-
- getCached: function getCached() {
- return this.keepAlive && this.cache[this.Component.cid];
- },
-
- /**
- * Teardown the current child, but defers cleanup so
- * that we can separate the destroy and removal steps.
- *
- * @param {Boolean} defer
- */
-
- unbuild: function unbuild(defer) {
- if (this.waitingFor) {
- if (!this.keepAlive) {
- this.waitingFor.$destroy();
- }
- this.waitingFor = null;
- }
- var child = this.childVM;
- if (!child || this.keepAlive) {
- if (child) {
- // remove ref
- child._inactive = true;
- child._updateRef(true);
- }
- return;
- }
- // the sole purpose of `deferCleanup` is so that we can
- // "deactivate" the vm right now and perform DOM removal
- // later.
- child.$destroy(false, defer);
- },
-
- /**
- * Remove current destroyed child and manually do
- * the cleanup after removal.
- *
- * @param {Function} cb
- */
-
- remove: function remove(child, cb) {
- var keepAlive = this.keepAlive;
- if (child) {
- // we may have a component switch when a previous
- // component is still being transitioned out.
- // we want to trigger only one lastest insertion cb
- // when the existing transition finishes. (#1119)
- this.pendingRemovals++;
- this.pendingRemovalCb = cb;
- var self = this;
- child.$remove(function () {
- self.pendingRemovals--;
- if (!keepAlive) child._cleanup();
- if (!self.pendingRemovals && self.pendingRemovalCb) {
- self.pendingRemovalCb();
- self.pendingRemovalCb = null;
- }
- });
- } else if (cb) {
- cb();
- }
- },
-
- /**
- * Actually swap the components, depending on the
- * transition mode. Defaults to simultaneous.
- *
- * @param {Vue} target
- * @param {Function} [cb]
- */
-
- transition: function transition(target, cb) {
- var self = this;
- var current = this.childVM;
- // for devtool inspection
- if (current) current._inactive = true;
- target._inactive = false;
- this.childVM = target;
- switch (self.params.transitionMode) {
- case 'in-out':
- target.$before(self.anchor, function () {
- self.remove(current, cb);
- });
- break;
- case 'out-in':
- self.remove(current, function () {
- target.$before(self.anchor, cb);
- });
- break;
- default:
- self.remove(current);
- target.$before(self.anchor, cb);
- }
- },
-
- /**
- * Unbind.
- */
-
- unbind: function unbind() {
- this.invalidatePending();
- // Do not defer cleanup when unbinding
- this.unbuild();
- // destroy all keep-alive cached instances
- if (this.cache) {
- for (var key in this.cache) {
- this.cache[key].$destroy();
- }
- this.cache = null;
- }
- }
- };
-
- /**
- * Call activate hooks in order (asynchronous)
- *
- * @param {Array} hooks
- * @param {Vue} vm
- * @param {Function} cb
- */
-
- function callActivateHooks(hooks, vm, cb) {
- var total = hooks.length;
- var called = 0;
- hooks[0].call(vm, next);
- function next() {
- if (++called >= total) {
- cb();
- } else {
- hooks[called].call(vm, next);
- }
- }
- }
-
- var propBindingModes = config._propBindingModes;
- var empty = {};
-
- // regexes
- var identRE$1 = /^[$_a-zA-Z]+[\w$]*$/;
- var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/;
-
- /**
- * Compile props on a root element and return
- * a props link function.
- *
- * @param {Element|DocumentFragment} el
- * @param {Array} propOptions
- * @param {Vue} vm
- * @return {Function} propsLinkFn
- */
-
- function compileProps(el, propOptions, vm) {
- var props = [];
- var names = Object.keys(propOptions);
- var i = names.length;
- var options, name, attr, value, path, parsed, prop;
- while (i--) {
- name = names[i];
- options = propOptions[name] || empty;
-
- if (process.env.NODE_ENV !== 'production' && name === '$data') {
- warn('Do not use $data as prop.', vm);
- continue;
- }
-
- // props could contain dashes, which will be
- // interpreted as minus calculations by the parser
- // so we need to camelize the path here
- path = camelize(name);
- if (!identRE$1.test(path)) {
- process.env.NODE_ENV !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.', vm);
- continue;
- }
-
- prop = {
- name: name,
- path: path,
- options: options,
- mode: propBindingModes.ONE_WAY,
- raw: null
- };
-
- attr = hyphenate(name);
- // first check dynamic version
- if ((value = getBindAttr(el, attr)) === null) {
- if ((value = getBindAttr(el, attr + '.sync')) !== null) {
- prop.mode = propBindingModes.TWO_WAY;
- } else if ((value = getBindAttr(el, attr + '.once')) !== null) {
- prop.mode = propBindingModes.ONE_TIME;
- }
- }
- if (value !== null) {
- // has dynamic binding!
- prop.raw = value;
- parsed = parseDirective(value);
- value = parsed.expression;
- prop.filters = parsed.filters;
- // check binding type
- if (isLiteral(value) && !parsed.filters) {
- // for expressions containing literal numbers and
- // booleans, there's no need to setup a prop binding,
- // so we can optimize them as a one-time set.
- prop.optimizedLiteral = true;
- } else {
- prop.dynamic = true;
- // check non-settable path for two-way bindings
- if (process.env.NODE_ENV !== 'production' && prop.mode === propBindingModes.TWO_WAY && !settablePathRE.test(value)) {
- prop.mode = propBindingModes.ONE_WAY;
- warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value, vm);
- }
- }
- prop.parentPath = value;
-
- // warn required two-way
- if (process.env.NODE_ENV !== 'production' && options.twoWay && prop.mode !== propBindingModes.TWO_WAY) {
- warn('Prop "' + name + '" expects a two-way binding type.', vm);
- }
- } else if ((value = getAttr(el, attr)) !== null) {
- // has literal binding!
- prop.raw = value;
- } else if (process.env.NODE_ENV !== 'production') {
- // check possible camelCase prop usage
- var lowerCaseName = path.toLowerCase();
- value = /[A-Z\-]/.test(name) && (el.getAttribute(lowerCaseName) || el.getAttribute(':' + lowerCaseName) || el.getAttribute('v-bind:' + lowerCaseName) || el.getAttribute(':' + lowerCaseName + '.once') || el.getAttribute('v-bind:' + lowerCaseName + '.once') || el.getAttribute(':' + lowerCaseName + '.sync') || el.getAttribute('v-bind:' + lowerCaseName + '.sync'));
- if (value) {
- warn('Possible usage error for prop `' + lowerCaseName + '` - ' + 'did you mean `' + attr + '`? HTML is case-insensitive, remember to use ' + 'kebab-case for props in templates.', vm);
- } else if (options.required) {
- // warn missing required
- warn('Missing required prop: ' + name, vm);
- }
- }
- // push prop
- props.push(prop);
- }
- return makePropsLinkFn(props);
- }
-
- /**
- * Build a function that applies props to a vm.
- *
- * @param {Array} props
- * @return {Function} propsLinkFn
- */
-
- function makePropsLinkFn(props) {
- return function propsLinkFn(vm, scope) {
- // store resolved props info
- vm._props = {};
- var inlineProps = vm.$options.propsData;
- var i = props.length;
- var prop, path, options, value, raw;
- while (i--) {
- prop = props[i];
- raw = prop.raw;
- path = prop.path;
- options = prop.options;
- vm._props[path] = prop;
- if (inlineProps && hasOwn(inlineProps, path)) {
- initProp(vm, prop, inlineProps[path]);
- }if (raw === null) {
- // initialize absent prop
- initProp(vm, prop, undefined);
- } else if (prop.dynamic) {
- // dynamic prop
- if (prop.mode === propBindingModes.ONE_TIME) {
- // one time binding
- value = (scope || vm._context || vm).$get(prop.parentPath);
- initProp(vm, prop, value);
- } else {
- if (vm._context) {
- // dynamic binding
- vm._bindDir({
- name: 'prop',
- def: propDef,
- prop: prop
- }, null, null, scope); // el, host, scope
- } else {
- // root instance
- initProp(vm, prop, vm.$get(prop.parentPath));
- }
- }
- } else if (prop.optimizedLiteral) {
- // optimized literal, cast it and just set once
- var stripped = stripQuotes(raw);
- value = stripped === raw ? toBoolean(toNumber(raw)) : stripped;
- initProp(vm, prop, value);
- } else {
- // string literal, but we need to cater for
- // Boolean props with no value, or with same
- // literal value (e.g. disabled="disabled")
- // see https://github.com/vuejs/vue-loader/issues/182
- value = options.type === Boolean && (raw === '' || raw === hyphenate(prop.name)) ? true : raw;
- initProp(vm, prop, value);
- }
- }
- };
- }
-
- /**
- * Process a prop with a rawValue, applying necessary coersions,
- * default values & assertions and call the given callback with
- * processed value.
- *
- * @param {Vue} vm
- * @param {Object} prop
- * @param {*} rawValue
- * @param {Function} fn
- */
-
- function processPropValue(vm, prop, rawValue, fn) {
- var isSimple = prop.dynamic && isSimplePath(prop.parentPath);
- var value = rawValue;
- if (value === undefined) {
- value = getPropDefaultValue(vm, prop);
- }
- value = coerceProp(prop, value);
- var coerced = value !== rawValue;
- if (!assertProp(prop, value, vm)) {
- value = undefined;
- }
- if (isSimple && !coerced) {
- withoutConversion(function () {
- fn(value);
- });
- } else {
- fn(value);
- }
- }
-
- /**
- * Set a prop's initial value on a vm and its data object.
- *
- * @param {Vue} vm
- * @param {Object} prop
- * @param {*} value
- */
-
- function initProp(vm, prop, value) {
- processPropValue(vm, prop, value, function (value) {
- defineReactive(vm, prop.path, value);
- });
- }
-
- /**
- * Update a prop's value on a vm.
- *
- * @param {Vue} vm
- * @param {Object} prop
- * @param {*} value
- */
-
- function updateProp(vm, prop, value) {
- processPropValue(vm, prop, value, function (value) {
- vm[prop.path] = value;
- });
- }
-
- /**
- * Get the default value of a prop.
- *
- * @param {Vue} vm
- * @param {Object} prop
- * @return {*}
- */
-
- function getPropDefaultValue(vm, prop) {
- // no default, return undefined
- var options = prop.options;
- if (!hasOwn(options, 'default')) {
- // absent boolean value defaults to false
- return options.type === Boolean ? false : undefined;
- }
- var def = options['default'];
- // warn against non-factory defaults for Object & Array
- if (isObject(def)) {
- process.env.NODE_ENV !== 'production' && warn('Invalid default value for prop "' + prop.name + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm);
- }
- // call factory function for non-Function types
- return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
- }
-
- /**
- * Assert whether a prop is valid.
- *
- * @param {Object} prop
- * @param {*} value
- * @param {Vue} vm
- */
-
- function assertProp(prop, value, vm) {
- if (!prop.options.required && ( // non-required
- prop.raw === null || // abscent
- value == null) // null or undefined
- ) {
- return true;
- }
- var options = prop.options;
- var type = options.type;
- var valid = !type;
- var expectedTypes = [];
- if (type) {
- if (!isArray(type)) {
- type = [type];
- }
- for (var i = 0; i < type.length && !valid; i++) {
- var assertedType = assertType(value, type[i]);
- expectedTypes.push(assertedType.expectedType);
- valid = assertedType.valid;
- }
- }
- if (!valid) {
- if (process.env.NODE_ENV !== 'production') {
- warn('Invalid prop: type check failed for prop "' + prop.name + '".' + ' Expected ' + expectedTypes.map(formatType).join(', ') + ', got ' + formatValue(value) + '.', vm);
- }
- return false;
- }
- var validator = options.validator;
- if (validator) {
- if (!validator(value)) {
- process.env.NODE_ENV !== 'production' && warn('Invalid prop: custom validator check failed for prop "' + prop.name + '".', vm);
- return false;
- }
- }
- return true;
- }
-
- /**
- * Force parsing value with coerce option.
- *
- * @param {*} value
- * @param {Object} options
- * @return {*}
- */
-
- function coerceProp(prop, value) {
- var coerce = prop.options.coerce;
- if (!coerce) {
- return value;
- }
- // coerce is a function
- return coerce(value);
- }
-
- /**
- * Assert the type of a value
- *
- * @param {*} value
- * @param {Function} type
- * @return {Object}
- */
-
- function assertType(value, type) {
- var valid;
- var expectedType;
- if (type === String) {
- expectedType = 'string';
- valid = typeof value === expectedType;
- } else if (type === Number) {
- expectedType = 'number';
- valid = typeof value === expectedType;
- } else if (type === Boolean) {
- expectedType = 'boolean';
- valid = typeof value === expectedType;
- } else if (type === Function) {
- expectedType = 'function';
- valid = typeof value === expectedType;
- } else if (type === Object) {
- expectedType = 'object';
- valid = isPlainObject(value);
- } else if (type === Array) {
- expectedType = 'array';
- valid = isArray(value);
- } else {
- valid = value instanceof type;
- }
- return {
- valid: valid,
- expectedType: expectedType
- };
- }
-
- /**
- * Format type for output
- *
- * @param {String} type
- * @return {String}
- */
-
- function formatType(type) {
- return type ? type.charAt(0).toUpperCase() + type.slice(1) : 'custom type';
- }
-
- /**
- * Format value
- *
- * @param {*} value
- * @return {String}
- */
-
- function formatValue(val) {
- return Object.prototype.toString.call(val).slice(8, -1);
- }
-
- var bindingModes = config._propBindingModes;
-
- var propDef = {
-
- bind: function bind() {
- var child = this.vm;
- var parent = child._context;
- // passed in from compiler directly
- var prop = this.descriptor.prop;
- var childKey = prop.path;
- var parentKey = prop.parentPath;
- var twoWay = prop.mode === bindingModes.TWO_WAY;
-
- var parentWatcher = this.parentWatcher = new Watcher(parent, parentKey, function (val) {
- updateProp(child, prop, val);
- }, {
- twoWay: twoWay,
- filters: prop.filters,
- // important: props need to be observed on the
- // v-for scope if present
- scope: this._scope
- });
-
- // set the child initial value.
- initProp(child, prop, parentWatcher.value);
-
- // setup two-way binding
- if (twoWay) {
- // important: defer the child watcher creation until
- // the created hook (after data observation)
- var self = this;
- child.$once('pre-hook:created', function () {
- self.childWatcher = new Watcher(child, childKey, function (val) {
- parentWatcher.set(val);
- }, {
- // ensure sync upward before parent sync down.
- // this is necessary in cases e.g. the child
- // mutates a prop array, then replaces it. (#1683)
- sync: true
- });
- });
- }
- },
-
- unbind: function unbind() {
- this.parentWatcher.teardown();
- if (this.childWatcher) {
- this.childWatcher.teardown();
- }
- }
- };
-
- var queue$1 = [];
- var queued = false;
-
- /**
- * Push a job into the queue.
- *
- * @param {Function} job
- */
-
- function pushJob(job) {
- queue$1.push(job);
- if (!queued) {
- queued = true;
- nextTick(flush);
- }
- }
-
- /**
- * Flush the queue, and do one forced reflow before
- * triggering transitions.
- */
-
- function flush() {
- // Force layout
- var f = document.documentElement.offsetHeight;
- for (var i = 0; i < queue$1.length; i++) {
- queue$1[i]();
- }
- queue$1 = [];
- queued = false;
- // dummy return, so js linters don't complain about
- // unused variable f
- return f;
- }
-
- var TYPE_TRANSITION = 'transition';
- var TYPE_ANIMATION = 'animation';
- var transDurationProp = transitionProp + 'Duration';
- var animDurationProp = animationProp + 'Duration';
-
- /**
- * If a just-entered element is applied the
- * leave class while its enter transition hasn't started yet,
- * and the transitioned property has the same value for both
- * enter/leave, then the leave transition will be skipped and
- * the transitionend event never fires. This function ensures
- * its callback to be called after a transition has started
- * by waiting for double raf.
- *
- * It falls back to setTimeout on devices that support CSS
- * transitions but not raf (e.g. Android 4.2 browser) - since
- * these environments are usually slow, we are giving it a
- * relatively large timeout.
- */
-
- var raf = inBrowser && window.requestAnimationFrame;
- var waitForTransitionStart = raf
- /* istanbul ignore next */
- ? function (fn) {
- raf(function () {
- raf(fn);
- });
- } : function (fn) {
- setTimeout(fn, 50);
- };
-
- /**
- * A Transition object that encapsulates the state and logic
- * of the transition.
- *
- * @param {Element} el
- * @param {String} id
- * @param {Object} hooks
- * @param {Vue} vm
- */
- function Transition(el, id, hooks, vm) {
- this.id = id;
- this.el = el;
- this.enterClass = hooks && hooks.enterClass || id + '-enter';
- this.leaveClass = hooks && hooks.leaveClass || id + '-leave';
- this.hooks = hooks;
- this.vm = vm;
- // async state
- this.pendingCssEvent = this.pendingCssCb = this.cancel = this.pendingJsCb = this.op = this.cb = null;
- this.justEntered = false;
- this.entered = this.left = false;
- this.typeCache = {};
- // check css transition type
- this.type = hooks && hooks.type;
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production') {
- if (this.type && this.type !== TYPE_TRANSITION && this.type !== TYPE_ANIMATION) {
- warn('invalid CSS transition type for transition="' + this.id + '": ' + this.type, vm);
- }
- }
- // bind
- var self = this;['enterNextTick', 'enterDone', 'leaveNextTick', 'leaveDone'].forEach(function (m) {
- self[m] = bind(self[m], self);
- });
- }
-
- var p$1 = Transition.prototype;
-
- /**
- * Start an entering transition.
- *
- * 1. enter transition triggered
- * 2. call beforeEnter hook
- * 3. add enter class
- * 4. insert/show element
- * 5. call enter hook (with possible explicit js callback)
- * 6. reflow
- * 7. based on transition type:
- * - transition:
- * remove class now, wait for transitionend,
- * then done if there's no explicit js callback.
- * - animation:
- * wait for animationend, remove class,
- * then done if there's no explicit js callback.
- * - no css transition:
- * done now if there's no explicit js callback.
- * 8. wait for either done or js callback, then call
- * afterEnter hook.
- *
- * @param {Function} op - insert/show the element
- * @param {Function} [cb]
- */
-
- p$1.enter = function (op, cb) {
- this.cancelPending();
- this.callHook('beforeEnter');
- this.cb = cb;
- addClass(this.el, this.enterClass);
- op();
- this.entered = false;
- this.callHookWithCb('enter');
- if (this.entered) {
- return; // user called done synchronously.
- }
- this.cancel = this.hooks && this.hooks.enterCancelled;
- pushJob(this.enterNextTick);
- };
-
- /**
- * The "nextTick" phase of an entering transition, which is
- * to be pushed into a queue and executed after a reflow so
- * that removing the class can trigger a CSS transition.
- */
-
- p$1.enterNextTick = function () {
- var _this = this;
-
- // prevent transition skipping
- this.justEntered = true;
- waitForTransitionStart(function () {
- _this.justEntered = false;
- });
- var enterDone = this.enterDone;
- var type = this.getCssTransitionType(this.enterClass);
- if (!this.pendingJsCb) {
- if (type === TYPE_TRANSITION) {
- // trigger transition by removing enter class now
- removeClass(this.el, this.enterClass);
- this.setupCssCb(transitionEndEvent, enterDone);
- } else if (type === TYPE_ANIMATION) {
- this.setupCssCb(animationEndEvent, enterDone);
- } else {
- enterDone();
- }
- } else if (type === TYPE_TRANSITION) {
- removeClass(this.el, this.enterClass);
- }
- };
-
- /**
- * The "cleanup" phase of an entering transition.
- */
-
- p$1.enterDone = function () {
- this.entered = true;
- this.cancel = this.pendingJsCb = null;
- removeClass(this.el, this.enterClass);
- this.callHook('afterEnter');
- if (this.cb) this.cb();
- };
-
- /**
- * Start a leaving transition.
- *
- * 1. leave transition triggered.
- * 2. call beforeLeave hook
- * 3. add leave class (trigger css transition)
- * 4. call leave hook (with possible explicit js callback)
- * 5. reflow if no explicit js callback is provided
- * 6. based on transition type:
- * - transition or animation:
- * wait for end event, remove class, then done if
- * there's no explicit js callback.
- * - no css transition:
- * done if there's no explicit js callback.
- * 7. wait for either done or js callback, then call
- * afterLeave hook.
- *
- * @param {Function} op - remove/hide the element
- * @param {Function} [cb]
- */
-
- p$1.leave = function (op, cb) {
- this.cancelPending();
- this.callHook('beforeLeave');
- this.op = op;
- this.cb = cb;
- addClass(this.el, this.leaveClass);
- this.left = false;
- this.callHookWithCb('leave');
- if (this.left) {
- return; // user called done synchronously.
- }
- this.cancel = this.hooks && this.hooks.leaveCancelled;
- // only need to handle leaveDone if
- // 1. the transition is already done (synchronously called
- // by the user, which causes this.op set to null)
- // 2. there's no explicit js callback
- if (this.op && !this.pendingJsCb) {
- // if a CSS transition leaves immediately after enter,
- // the transitionend event never fires. therefore we
- // detect such cases and end the leave immediately.
- if (this.justEntered) {
- this.leaveDone();
- } else {
- pushJob(this.leaveNextTick);
- }
- }
- };
-
- /**
- * The "nextTick" phase of a leaving transition.
- */
-
- p$1.leaveNextTick = function () {
- var type = this.getCssTransitionType(this.leaveClass);
- if (type) {
- var event = type === TYPE_TRANSITION ? transitionEndEvent : animationEndEvent;
- this.setupCssCb(event, this.leaveDone);
- } else {
- this.leaveDone();
- }
- };
-
- /**
- * The "cleanup" phase of a leaving transition.
- */
-
- p$1.leaveDone = function () {
- this.left = true;
- this.cancel = this.pendingJsCb = null;
- this.op();
- removeClass(this.el, this.leaveClass);
- this.callHook('afterLeave');
- if (this.cb) this.cb();
- this.op = null;
- };
-
- /**
- * Cancel any pending callbacks from a previously running
- * but not finished transition.
- */
-
- p$1.cancelPending = function () {
- this.op = this.cb = null;
- var hasPending = false;
- if (this.pendingCssCb) {
- hasPending = true;
- off(this.el, this.pendingCssEvent, this.pendingCssCb);
- this.pendingCssEvent = this.pendingCssCb = null;
- }
- if (this.pendingJsCb) {
- hasPending = true;
- this.pendingJsCb.cancel();
- this.pendingJsCb = null;
- }
- if (hasPending) {
- removeClass(this.el, this.enterClass);
- removeClass(this.el, this.leaveClass);
- }
- if (this.cancel) {
- this.cancel.call(this.vm, this.el);
- this.cancel = null;
- }
- };
-
- /**
- * Call a user-provided synchronous hook function.
- *
- * @param {String} type
- */
-
- p$1.callHook = function (type) {
- if (this.hooks && this.hooks[type]) {
- this.hooks[type].call(this.vm, this.el);
- }
- };
-
- /**
- * Call a user-provided, potentially-async hook function.
- * We check for the length of arguments to see if the hook
- * expects a `done` callback. If true, the transition's end
- * will be determined by when the user calls that callback;
- * otherwise, the end is determined by the CSS transition or
- * animation.
- *
- * @param {String} type
- */
-
- p$1.callHookWithCb = function (type) {
- var hook = this.hooks && this.hooks[type];
- if (hook) {
- if (hook.length > 1) {
- this.pendingJsCb = cancellable(this[type + 'Done']);
- }
- hook.call(this.vm, this.el, this.pendingJsCb);
- }
- };
-
- /**
- * Get an element's transition type based on the
- * calculated styles.
- *
- * @param {String} className
- * @return {Number}
- */
-
- p$1.getCssTransitionType = function (className) {
- /* istanbul ignore if */
- if (!transitionEndEvent ||
- // skip CSS transitions if page is not visible -
- // this solves the issue of transitionend events not
- // firing until the page is visible again.
- // pageVisibility API is supported in IE10+, same as
- // CSS transitions.
- document.hidden ||
- // explicit js-only transition
- this.hooks && this.hooks.css === false ||
- // element is hidden
- isHidden(this.el)) {
- return;
- }
- var type = this.type || this.typeCache[className];
- if (type) return type;
- var inlineStyles = this.el.style;
- var computedStyles = window.getComputedStyle(this.el);
- var transDuration = inlineStyles[transDurationProp] || computedStyles[transDurationProp];
- if (transDuration && transDuration !== '0s') {
- type = TYPE_TRANSITION;
- } else {
- var animDuration = inlineStyles[animDurationProp] || computedStyles[animDurationProp];
- if (animDuration && animDuration !== '0s') {
- type = TYPE_ANIMATION;
- }
- }
- if (type) {
- this.typeCache[className] = type;
- }
- return type;
- };
-
- /**
- * Setup a CSS transitionend/animationend callback.
- *
- * @param {String} event
- * @param {Function} cb
- */
-
- p$1.setupCssCb = function (event, cb) {
- this.pendingCssEvent = event;
- var self = this;
- var el = this.el;
- var onEnd = this.pendingCssCb = function (e) {
- if (e.target === el) {
- off(el, event, onEnd);
- self.pendingCssEvent = self.pendingCssCb = null;
- if (!self.pendingJsCb && cb) {
- cb();
- }
- }
- };
- on(el, event, onEnd);
- };
-
- /**
- * Check if an element is hidden - in that case we can just
- * skip the transition alltogether.
- *
- * @param {Element} el
- * @return {Boolean}
- */
-
- function isHidden(el) {
- if (/svg$/.test(el.namespaceURI)) {
- // SVG elements do not have offset(Width|Height)
- // so we need to check the client rect
- var rect = el.getBoundingClientRect();
- return !(rect.width || rect.height);
- } else {
- return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
- }
- }
-
- var transition$1 = {
-
- priority: TRANSITION,
-
- update: function update(id, oldId) {
- var el = this.el;
- // resolve on owner vm
- var hooks = resolveAsset(this.vm.$options, 'transitions', id);
- id = id || 'v';
- el.__v_trans = new Transition(el, id, hooks, this.vm);
- if (oldId) {
- removeClass(el, oldId + '-transition');
- }
- addClass(el, id + '-transition');
- }
- };
-
- var internalDirectives = {
- style: style,
- 'class': vClass,
- component: component,
- prop: propDef,
- transition: transition$1
- };
-
- // special binding prefixes
- var bindRE = /^v-bind:|^:/;
- var onRE = /^v-on:|^@/;
- var dirAttrRE = /^v-([^:]+)(?:$|:(.*)$)/;
- var modifierRE = /\.[^\.]+/g;
- var transitionRE = /^(v-bind:|:)?transition$/;
-
- // default directive priority
- var DEFAULT_PRIORITY = 1000;
- var DEFAULT_TERMINAL_PRIORITY = 2000;
-
- /**
- * Compile a template and return a reusable composite link
- * function, which recursively contains more link functions
- * inside. This top level compile function would normally
- * be called on instance root nodes, but can also be used
- * for partial compilation if the partial argument is true.
- *
- * The returned composite link function, when called, will
- * return an unlink function that tearsdown all directives
- * created during the linking phase.
- *
- * @param {Element|DocumentFragment} el
- * @param {Object} options
- * @param {Boolean} partial
- * @return {Function}
- */
-
- function compile(el, options, partial) {
- // link function for the node itself.
- var nodeLinkFn = partial || !options._asComponent ? compileNode(el, options) : null;
- // link function for the childNodes
- var childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && !isScript(el) && el.hasChildNodes() ? compileNodeList(el.childNodes, options) : null;
-
- /**
- * A composite linker function to be called on a already
- * compiled piece of DOM, which instantiates all directive
- * instances.
- *
- * @param {Vue} vm
- * @param {Element|DocumentFragment} el
- * @param {Vue} [host] - host vm of transcluded content
- * @param {Object} [scope] - v-for scope
- * @param {Fragment} [frag] - link context fragment
- * @return {Function|undefined}
- */
-
- return function compositeLinkFn(vm, el, host, scope, frag) {
- // cache childNodes before linking parent, fix #657
- var childNodes = toArray(el.childNodes);
- // link
- var dirs = linkAndCapture(function compositeLinkCapturer() {
- if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag);
- if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag);
- }, vm);
- return makeUnlinkFn(vm, dirs);
- };
- }
-
- /**
- * Apply a linker to a vm/element pair and capture the
- * directives created during the process.
- *
- * @param {Function} linker
- * @param {Vue} vm
- */
-
- function linkAndCapture(linker, vm) {
- /* istanbul ignore if */
- if (process.env.NODE_ENV === 'production') {
- // reset directives before every capture in production
- // mode, so that when unlinking we don't need to splice
- // them out (which turns out to be a perf hit).
- // they are kept in development mode because they are
- // useful for Vue's own tests.
- vm._directives = [];
- }
- var originalDirCount = vm._directives.length;
- linker();
- var dirs = vm._directives.slice(originalDirCount);
- dirs.sort(directiveComparator);
- for (var i = 0, l = dirs.length; i < l; i++) {
- dirs[i]._bind();
- }
- return dirs;
- }
-
- /**
- * Directive priority sort comparator
- *
- * @param {Object} a
- * @param {Object} b
- */
-
- function directiveComparator(a, b) {
- a = a.descriptor.def.priority || DEFAULT_PRIORITY;
- b = b.descriptor.def.priority || DEFAULT_PRIORITY;
- return a > b ? -1 : a === b ? 0 : 1;
- }
-
- /**
- * Linker functions return an unlink function that
- * tearsdown all directives instances generated during
- * the process.
- *
- * We create unlink functions with only the necessary
- * information to avoid retaining additional closures.
- *
- * @param {Vue} vm
- * @param {Array} dirs
- * @param {Vue} [context]
- * @param {Array} [contextDirs]
- * @return {Function}
- */
-
- function makeUnlinkFn(vm, dirs, context, contextDirs) {
- function unlink(destroying) {
- teardownDirs(vm, dirs, destroying);
- if (context && contextDirs) {
- teardownDirs(context, contextDirs);
- }
- }
- // expose linked directives
- unlink.dirs = dirs;
- return unlink;
- }
-
- /**
- * Teardown partial linked directives.
- *
- * @param {Vue} vm
- * @param {Array} dirs
- * @param {Boolean} destroying
- */
-
- function teardownDirs(vm, dirs, destroying) {
- var i = dirs.length;
- while (i--) {
- dirs[i]._teardown();
- if (process.env.NODE_ENV !== 'production' && !destroying) {
- vm._directives.$remove(dirs[i]);
- }
- }
- }
-
- /**
- * Compile link props on an instance.
- *
- * @param {Vue} vm
- * @param {Element} el
- * @param {Object} props
- * @param {Object} [scope]
- * @return {Function}
- */
-
- function compileAndLinkProps(vm, el, props, scope) {
- var propsLinkFn = compileProps(el, props, vm);
- var propDirs = linkAndCapture(function () {
- propsLinkFn(vm, scope);
- }, vm);
- return makeUnlinkFn(vm, propDirs);
- }
-
- /**
- * Compile the root element of an instance.
- *
- * 1. attrs on context container (context scope)
- * 2. attrs on the component template root node, if
- * replace:true (child scope)
- *
- * If this is a fragment instance, we only need to compile 1.
- *
- * @param {Element} el
- * @param {Object} options
- * @param {Object} contextOptions
- * @return {Function}
- */
-
- function compileRoot(el, options, contextOptions) {
- var containerAttrs = options._containerAttrs;
- var replacerAttrs = options._replacerAttrs;
- var contextLinkFn, replacerLinkFn;
-
- // only need to compile other attributes for
- // non-fragment instances
- if (el.nodeType !== 11) {
- // for components, container and replacer need to be
- // compiled separately and linked in different scopes.
- if (options._asComponent) {
- // 2. container attributes
- if (containerAttrs && contextOptions) {
- contextLinkFn = compileDirectives(containerAttrs, contextOptions);
- }
- if (replacerAttrs) {
- // 3. replacer attributes
- replacerLinkFn = compileDirectives(replacerAttrs, options);
- }
- } else {
- // non-component, just compile as a normal element.
- replacerLinkFn = compileDirectives(el.attributes, options);
- }
- } else if (process.env.NODE_ENV !== 'production' && containerAttrs) {
- // warn container directives for fragment instances
- var names = containerAttrs.filter(function (attr) {
- // allow vue-loader/vueify scoped css attributes
- return attr.name.indexOf('_v-') < 0 &&
- // allow event listeners
- !onRE.test(attr.name) &&
- // allow slots
- attr.name !== 'slot';
- }).map(function (attr) {
- return '"' + attr.name + '"';
- });
- if (names.length) {
- var plural = names.length > 1;
- warn('Attribute' + (plural ? 's ' : ' ') + names.join(', ') + (plural ? ' are' : ' is') + ' ignored on component ' + '<' + options.el.tagName.toLowerCase() + '> because ' + 'the component is a fragment instance: ' + 'http://vuejs.org/guide/components.html#Fragment-Instance');
- }
- }
-
- options._containerAttrs = options._replacerAttrs = null;
- return function rootLinkFn(vm, el, scope) {
- // link context scope dirs
- var context = vm._context;
- var contextDirs;
- if (context && contextLinkFn) {
- contextDirs = linkAndCapture(function () {
- contextLinkFn(context, el, null, scope);
- }, context);
- }
-
- // link self
- var selfDirs = linkAndCapture(function () {
- if (replacerLinkFn) replacerLinkFn(vm, el);
- }, vm);
-
- // return the unlink function that tearsdown context
- // container directives.
- return makeUnlinkFn(vm, selfDirs, context, contextDirs);
- };
- }
-
- /**
- * Compile a node and return a nodeLinkFn based on the
- * node type.
- *
- * @param {Node} node
- * @param {Object} options
- * @return {Function|null}
- */
-
- function compileNode(node, options) {
- var type = node.nodeType;
- if (type === 1 && !isScript(node)) {
- return compileElement(node, options);
- } else if (type === 3 && node.data.trim()) {
- return compileTextNode(node, options);
- } else {
- return null;
- }
- }
-
- /**
- * Compile an element and return a nodeLinkFn.
- *
- * @param {Element} el
- * @param {Object} options
- * @return {Function|null}
- */
-
- function compileElement(el, options) {
- // preprocess textareas.
- // textarea treats its text content as the initial value.
- // just bind it as an attr directive for value.
- if (el.tagName === 'TEXTAREA') {
- var tokens = parseText(el.value);
- if (tokens) {
- el.setAttribute(':value', tokensToExp(tokens));
- el.value = '';
- }
- }
- var linkFn;
- var hasAttrs = el.hasAttributes();
- var attrs = hasAttrs && toArray(el.attributes);
- // check terminal directives (for & if)
- if (hasAttrs) {
- linkFn = checkTerminalDirectives(el, attrs, options);
- }
- // check element directives
- if (!linkFn) {
- linkFn = checkElementDirectives(el, options);
- }
- // check component
- if (!linkFn) {
- linkFn = checkComponent(el, options);
- }
- // normal directives
- if (!linkFn && hasAttrs) {
- linkFn = compileDirectives(attrs, options);
- }
- return linkFn;
- }
-
- /**
- * Compile a textNode and return a nodeLinkFn.
- *
- * @param {TextNode} node
- * @param {Object} options
- * @return {Function|null} textNodeLinkFn
- */
-
- function compileTextNode(node, options) {
- // skip marked text nodes
- if (node._skip) {
- return removeText;
- }
-
- var tokens = parseText(node.wholeText);
- if (!tokens) {
- return null;
- }
-
- // mark adjacent text nodes as skipped,
- // because we are using node.wholeText to compile
- // all adjacent text nodes together. This fixes
- // issues in IE where sometimes it splits up a single
- // text node into multiple ones.
- var next = node.nextSibling;
- while (next && next.nodeType === 3) {
- next._skip = true;
- next = next.nextSibling;
- }
-
- var frag = document.createDocumentFragment();
- var el, token;
- for (var i = 0, l = tokens.length; i < l; i++) {
- token = tokens[i];
- el = token.tag ? processTextToken(token, options) : document.createTextNode(token.value);
- frag.appendChild(el);
- }
- return makeTextNodeLinkFn(tokens, frag, options);
- }
-
- /**
- * Linker for an skipped text node.
- *
- * @param {Vue} vm
- * @param {Text} node
- */
-
- function removeText(vm, node) {
- remove(node);
- }
-
- /**
- * Process a single text token.
- *
- * @param {Object} token
- * @param {Object} options
- * @return {Node}
- */
-
- function processTextToken(token, options) {
- var el;
- if (token.oneTime) {
- el = document.createTextNode(token.value);
- } else {
- if (token.html) {
- el = document.createComment('v-html');
- setTokenType('html');
- } else {
- // IE will clean up empty textNodes during
- // frag.cloneNode(true), so we have to give it
- // something here...
- el = document.createTextNode(' ');
- setTokenType('text');
- }
- }
- function setTokenType(type) {
- if (token.descriptor) return;
- var parsed = parseDirective(token.value);
- token.descriptor = {
- name: type,
- def: directives[type],
- expression: parsed.expression,
- filters: parsed.filters
- };
- }
- return el;
- }
-
- /**
- * Build a function that processes a textNode.
- *
- * @param {Array<Object>} tokens
- * @param {DocumentFragment} frag
- */
-
- function makeTextNodeLinkFn(tokens, frag) {
- return function textNodeLinkFn(vm, el, host, scope) {
- var fragClone = frag.cloneNode(true);
- var childNodes = toArray(fragClone.childNodes);
- var token, value, node;
- for (var i = 0, l = tokens.length; i < l; i++) {
- token = tokens[i];
- value = token.value;
- if (token.tag) {
- node = childNodes[i];
- if (token.oneTime) {
- value = (scope || vm).$eval(value);
- if (token.html) {
- replace(node, parseTemplate(value, true));
- } else {
- node.data = value;
- }
- } else {
- vm._bindDir(token.descriptor, node, host, scope);
- }
- }
- }
- replace(el, fragClone);
- };
- }
-
- /**
- * Compile a node list and return a childLinkFn.
- *
- * @param {NodeList} nodeList
- * @param {Object} options
- * @return {Function|undefined}
- */
-
- function compileNodeList(nodeList, options) {
- var linkFns = [];
- var nodeLinkFn, childLinkFn, node;
- for (var i = 0, l = nodeList.length; i < l; i++) {
- node = nodeList[i];
- nodeLinkFn = compileNode(node, options);
- childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && node.tagName !== 'SCRIPT' && node.hasChildNodes() ? compileNodeList(node.childNodes, options) : null;
- linkFns.push(nodeLinkFn, childLinkFn);
- }
- return linkFns.length ? makeChildLinkFn(linkFns) : null;
- }
-
- /**
- * Make a child link function for a node's childNodes.
- *
- * @param {Array<Function>} linkFns
- * @return {Function} childLinkFn
- */
-
- function makeChildLinkFn(linkFns) {
- return function childLinkFn(vm, nodes, host, scope, frag) {
- var node, nodeLinkFn, childrenLinkFn;
- for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
- node = nodes[n];
- nodeLinkFn = linkFns[i++];
- childrenLinkFn = linkFns[i++];
- // cache childNodes before linking parent, fix #657
- var childNodes = toArray(node.childNodes);
- if (nodeLinkFn) {
- nodeLinkFn(vm, node, host, scope, frag);
- }
- if (childrenLinkFn) {
- childrenLinkFn(vm, childNodes, host, scope, frag);
- }
- }
- };
- }
-
- /**
- * Check for element directives (custom elements that should
- * be resovled as terminal directives).
- *
- * @param {Element} el
- * @param {Object} options
- */
-
- function checkElementDirectives(el, options) {
- var tag = el.tagName.toLowerCase();
- if (commonTagRE.test(tag)) {
- return;
- }
- var def = resolveAsset(options, 'elementDirectives', tag);
- if (def) {
- return makeTerminalNodeLinkFn(el, tag, '', options, def);
- }
- }
-
- /**
- * Check if an element is a component. If yes, return
- * a component link function.
- *
- * @param {Element} el
- * @param {Object} options
- * @return {Function|undefined}
- */
-
- function checkComponent(el, options) {
- var component = checkComponentAttr(el, options);
- if (component) {
- var ref = findRef(el);
- var descriptor = {
- name: 'component',
- ref: ref,
- expression: component.id,
- def: internalDirectives.component,
- modifiers: {
- literal: !component.dynamic
- }
- };
- var componentLinkFn = function componentLinkFn(vm, el, host, scope, frag) {
- if (ref) {
- defineReactive((scope || vm).$refs, ref, null);
- }
- vm._bindDir(descriptor, el, host, scope, frag);
- };
- componentLinkFn.terminal = true;
- return componentLinkFn;
- }
- }
-
- /**
- * Check an element for terminal directives in fixed order.
- * If it finds one, return a terminal link function.
- *
- * @param {Element} el
- * @param {Array} attrs
- * @param {Object} options
- * @return {Function} terminalLinkFn
- */
-
- function checkTerminalDirectives(el, attrs, options) {
- // skip v-pre
- if (getAttr(el, 'v-pre') !== null) {
- return skip;
- }
- // skip v-else block, but only if following v-if
- if (el.hasAttribute('v-else')) {
- var prev = el.previousElementSibling;
- if (prev && prev.hasAttribute('v-if')) {
- return skip;
- }
- }
-
- var attr, name, value, modifiers, matched, dirName, rawName, arg, def, termDef;
- for (var i = 0, j = attrs.length; i < j; i++) {
- attr = attrs[i];
- name = attr.name.replace(modifierRE, '');
- if (matched = name.match(dirAttrRE)) {
- def = resolveAsset(options, 'directives', matched[1]);
- if (def && def.terminal) {
- if (!termDef || (def.priority || DEFAULT_TERMINAL_PRIORITY) > termDef.priority) {
- termDef = def;
- rawName = attr.name;
- modifiers = parseModifiers(attr.name);
- value = attr.value;
- dirName = matched[1];
- arg = matched[2];
- }
- }
- }
- }
-
- if (termDef) {
- return makeTerminalNodeLinkFn(el, dirName, value, options, termDef, rawName, arg, modifiers);
- }
- }
-
- function skip() {}
- skip.terminal = true;
-
- /**
- * Build a node link function for a terminal directive.
- * A terminal link function terminates the current
- * compilation recursion and handles compilation of the
- * subtree in the directive.
- *
- * @param {Element} el
- * @param {String} dirName
- * @param {String} value
- * @param {Object} options
- * @param {Object} def
- * @param {String} [rawName]
- * @param {String} [arg]
- * @param {Object} [modifiers]
- * @return {Function} terminalLinkFn
- */
-
- function makeTerminalNodeLinkFn(el, dirName, value, options, def, rawName, arg, modifiers) {
- var parsed = parseDirective(value);
- var descriptor = {
- name: dirName,
- arg: arg,
- expression: parsed.expression,
- filters: parsed.filters,
- raw: value,
- attr: rawName,
- modifiers: modifiers,
- def: def
- };
- // check ref for v-for and router-view
- if (dirName === 'for' || dirName === 'router-view') {
- descriptor.ref = findRef(el);
- }
- var fn = function terminalNodeLinkFn(vm, el, host, scope, frag) {
- if (descriptor.ref) {
- defineReactive((scope || vm).$refs, descriptor.ref, null);
- }
- vm._bindDir(descriptor, el, host, scope, frag);
- };
- fn.terminal = true;
- return fn;
- }
-
- /**
- * Compile the directives on an element and return a linker.
- *
- * @param {Array|NamedNodeMap} attrs
- * @param {Object} options
- * @return {Function}
- */
-
- function compileDirectives(attrs, options) {
- var i = attrs.length;
- var dirs = [];
- var attr, name, value, rawName, rawValue, dirName, arg, modifiers, dirDef, tokens, matched;
- while (i--) {
- attr = attrs[i];
- name = rawName = attr.name;
- value = rawValue = attr.value;
- tokens = parseText(value);
- // reset arg
- arg = null;
- // check modifiers
- modifiers = parseModifiers(name);
- name = name.replace(modifierRE, '');
-
- // attribute interpolations
- if (tokens) {
- value = tokensToExp(tokens);
- arg = name;
- pushDir('bind', directives.bind, tokens);
- // warn against mixing mustaches with v-bind
- if (process.env.NODE_ENV !== 'production') {
- if (name === 'class' && Array.prototype.some.call(attrs, function (attr) {
- return attr.name === ':class' || attr.name === 'v-bind:class';
- })) {
- warn('class="' + rawValue + '": Do not mix mustache interpolation ' + 'and v-bind for "class" on the same element. Use one or the other.', options);
- }
- }
- } else
-
- // special attribute: transition
- if (transitionRE.test(name)) {
- modifiers.literal = !bindRE.test(name);
- pushDir('transition', internalDirectives.transition);
- } else
-
- // event handlers
- if (onRE.test(name)) {
- arg = name.replace(onRE, '');
- pushDir('on', directives.on);
- } else
-
- // attribute bindings
- if (bindRE.test(name)) {
- dirName = name.replace(bindRE, '');
- if (dirName === 'style' || dirName === 'class') {
- pushDir(dirName, internalDirectives[dirName]);
- } else {
- arg = dirName;
- pushDir('bind', directives.bind);
- }
- } else
-
- // normal directives
- if (matched = name.match(dirAttrRE)) {
- dirName = matched[1];
- arg = matched[2];
-
- // skip v-else (when used with v-show)
- if (dirName === 'else') {
- continue;
- }
-
- dirDef = resolveAsset(options, 'directives', dirName, true);
- if (dirDef) {
- pushDir(dirName, dirDef);
- }
- }
- }
-
- /**
- * Push a directive.
- *
- * @param {String} dirName
- * @param {Object|Function} def
- * @param {Array} [interpTokens]
- */
-
- function pushDir(dirName, def, interpTokens) {
- var hasOneTimeToken = interpTokens && hasOneTime(interpTokens);
- var parsed = !hasOneTimeToken && parseDirective(value);
- dirs.push({
- name: dirName,
- attr: rawName,
- raw: rawValue,
- def: def,
- arg: arg,
- modifiers: modifiers,
- // conversion from interpolation strings with one-time token
- // to expression is differed until directive bind time so that we
- // have access to the actual vm context for one-time bindings.
- expression: parsed && parsed.expression,
- filters: parsed && parsed.filters,
- interp: interpTokens,
- hasOneTime: hasOneTimeToken
- });
- }
-
- if (dirs.length) {
- return makeNodeLinkFn(dirs);
- }
- }
-
- /**
- * Parse modifiers from directive attribute name.
- *
- * @param {String} name
- * @return {Object}
- */
-
- function parseModifiers(name) {
- var res = Object.create(null);
- var match = name.match(modifierRE);
- if (match) {
- var i = match.length;
- while (i--) {
- res[match[i].slice(1)] = true;
- }
- }
- return res;
- }
-
- /**
- * Build a link function for all directives on a single node.
- *
- * @param {Array} directives
- * @return {Function} directivesLinkFn
- */
-
- function makeNodeLinkFn(directives) {
- return function nodeLinkFn(vm, el, host, scope, frag) {
- // reverse apply because it's sorted low to high
- var i = directives.length;
- while (i--) {
- vm._bindDir(directives[i], el, host, scope, frag);
- }
- };
- }
-
- /**
- * Check if an interpolation string contains one-time tokens.
- *
- * @param {Array} tokens
- * @return {Boolean}
- */
-
- function hasOneTime(tokens) {
- var i = tokens.length;
- while (i--) {
- if (tokens[i].oneTime) return true;
- }
- }
-
- function isScript(el) {
- return el.tagName === 'SCRIPT' && (!el.hasAttribute('type') || el.getAttribute('type') === 'text/javascript');
- }
-
- var specialCharRE = /[^\w\-:\.]/;
-
- /**
- * Process an element or a DocumentFragment based on a
- * instance option object. This allows us to transclude
- * a template node/fragment before the instance is created,
- * so the processed fragment can then be cloned and reused
- * in v-for.
- *
- * @param {Element} el
- * @param {Object} options
- * @return {Element|DocumentFragment}
- */
-
- function transclude(el, options) {
- // extract container attributes to pass them down
- // to compiler, because they need to be compiled in
- // parent scope. we are mutating the options object here
- // assuming the same object will be used for compile
- // right after this.
- if (options) {
- options._containerAttrs = extractAttrs(el);
- }
- // for template tags, what we want is its content as
- // a documentFragment (for fragment instances)
- if (isTemplate(el)) {
- el = parseTemplate(el);
- }
- if (options) {
- if (options._asComponent && !options.template) {
- options.template = '<slot></slot>';
- }
- if (options.template) {
- options._content = extractContent(el);
- el = transcludeTemplate(el, options);
- }
- }
- if (isFragment(el)) {
- // anchors for fragment instance
- // passing in `persist: true` to avoid them being
- // discarded by IE during template cloning
- prepend(createAnchor('v-start', true), el);
- el.appendChild(createAnchor('v-end', true));
- }
- return el;
- }
-
- /**
- * Process the template option.
- * If the replace option is true this will swap the $el.
- *
- * @param {Element} el
- * @param {Object} options
- * @return {Element|DocumentFragment}
- */
-
- function transcludeTemplate(el, options) {
- var template = options.template;
- var frag = parseTemplate(template, true);
- if (frag) {
- var replacer = frag.firstChild;
- var tag = replacer.tagName && replacer.tagName.toLowerCase();
- if (options.replace) {
- /* istanbul ignore if */
- if (el === document.body) {
- process.env.NODE_ENV !== 'production' && warn('You are mounting an instance with a template to ' + '<body>. This will replace <body> entirely. You ' + 'should probably use `replace: false` here.');
- }
- // there are many cases where the instance must
- // become a fragment instance: basically anything that
- // can create more than 1 root nodes.
- if (
- // multi-children template
- frag.childNodes.length > 1 ||
- // non-element template
- replacer.nodeType !== 1 ||
- // single nested component
- tag === 'component' || resolveAsset(options, 'components', tag) || hasBindAttr(replacer, 'is') ||
- // element directive
- resolveAsset(options, 'elementDirectives', tag) ||
- // for block
- replacer.hasAttribute('v-for') ||
- // if block
- replacer.hasAttribute('v-if')) {
- return frag;
- } else {
- options._replacerAttrs = extractAttrs(replacer);
- mergeAttrs(el, replacer);
- return replacer;
- }
- } else {
- el.appendChild(frag);
- return el;
- }
- } else {
- process.env.NODE_ENV !== 'production' && warn('Invalid template option: ' + template);
- }
- }
-
- /**
- * Helper to extract a component container's attributes
- * into a plain object array.
- *
- * @param {Element} el
- * @return {Array}
- */
-
- function extractAttrs(el) {
- if (el.nodeType === 1 && el.hasAttributes()) {
- return toArray(el.attributes);
- }
- }
-
- /**
- * Merge the attributes of two elements, and make sure
- * the class names are merged properly.
- *
- * @param {Element} from
- * @param {Element} to
- */
-
- function mergeAttrs(from, to) {
- var attrs = from.attributes;
- var i = attrs.length;
- var name, value;
- while (i--) {
- name = attrs[i].name;
- value = attrs[i].value;
- if (!to.hasAttribute(name) && !specialCharRE.test(name)) {
- to.setAttribute(name, value);
- } else if (name === 'class' && !parseText(value) && (value = value.trim())) {
- value.split(/\s+/).forEach(function (cls) {
- addClass(to, cls);
- });
- }
- }
- }
-
- /**
- * Scan and determine slot content distribution.
- * We do this during transclusion instead at compile time so that
- * the distribution is decoupled from the compilation order of
- * the slots.
- *
- * @param {Element|DocumentFragment} template
- * @param {Element} content
- * @param {Vue} vm
- */
-
- function resolveSlots(vm, content) {
- if (!content) {
- return;
- }
- var contents = vm._slotContents = Object.create(null);
- var el, name;
- for (var i = 0, l = content.children.length; i < l; i++) {
- el = content.children[i];
- /* eslint-disable no-cond-assign */
- if (name = el.getAttribute('slot')) {
- (contents[name] || (contents[name] = [])).push(el);
- }
- /* eslint-enable no-cond-assign */
- if (process.env.NODE_ENV !== 'production' && getBindAttr(el, 'slot')) {
- warn('The "slot" attribute must be static.', vm.$parent);
- }
- }
- for (name in contents) {
- contents[name] = extractFragment(contents[name], content);
- }
- if (content.hasChildNodes()) {
- var nodes = content.childNodes;
- if (nodes.length === 1 && nodes[0].nodeType === 3 && !nodes[0].data.trim()) {
- return;
- }
- contents['default'] = extractFragment(content.childNodes, content);
- }
- }
-
- /**
- * Extract qualified content nodes from a node list.
- *
- * @param {NodeList} nodes
- * @return {DocumentFragment}
- */
-
- function extractFragment(nodes, parent) {
- var frag = document.createDocumentFragment();
- nodes = toArray(nodes);
- for (var i = 0, l = nodes.length; i < l; i++) {
- var node = nodes[i];
- if (isTemplate(node) && !node.hasAttribute('v-if') && !node.hasAttribute('v-for')) {
- parent.removeChild(node);
- node = parseTemplate(node, true);
- }
- frag.appendChild(node);
- }
- return frag;
- }
-
-
-
- var compiler = Object.freeze({
- compile: compile,
- compileAndLinkProps: compileAndLinkProps,
- compileRoot: compileRoot,
- transclude: transclude,
- resolveSlots: resolveSlots
- });
-
- function stateMixin (Vue) {
- /**
- * Accessor for `$data` property, since setting $data
- * requires observing the new object and updating
- * proxied properties.
- */
-
- Object.defineProperty(Vue.prototype, '$data', {
- get: function get() {
- return this._data;
- },
- set: function set(newData) {
- if (newData !== this._data) {
- this._setData(newData);
- }
- }
- });
-
- /**
- * Setup the scope of an instance, which contains:
- * - observed data
- * - computed properties
- * - user methods
- * - meta properties
- */
-
- Vue.prototype._initState = function () {
- this._initProps();
- this._initMeta();
- this._initMethods();
- this._initData();
- this._initComputed();
- };
-
- /**
- * Initialize props.
- */
-
- Vue.prototype._initProps = function () {
- var options = this.$options;
- var el = options.el;
- var props = options.props;
- if (props && !el) {
- process.env.NODE_ENV !== 'production' && warn('Props will not be compiled if no `el` option is ' + 'provided at instantiation.', this);
- }
- // make sure to convert string selectors into element now
- el = options.el = query(el);
- this._propsUnlinkFn = el && el.nodeType === 1 && props
- // props must be linked in proper scope if inside v-for
- ? compileAndLinkProps(this, el, props, this._scope) : null;
- };
-
- /**
- * Initialize the data.
- */
-
- Vue.prototype._initData = function () {
- var dataFn = this.$options.data;
- var data = this._data = dataFn ? dataFn() : {};
- if (!isPlainObject(data)) {
- data = {};
- process.env.NODE_ENV !== 'production' && warn('data functions should return an object.', this);
- }
- var props = this._props;
- // proxy data on instance
- var keys = Object.keys(data);
- var i, key;
- i = keys.length;
- while (i--) {
- key = keys[i];
- // there are two scenarios where we can proxy a data key:
- // 1. it's not already defined as a prop
- // 2. it's provided via a instantiation option AND there are no
- // template prop present
- if (!props || !hasOwn(props, key)) {
- this._proxy(key);
- } else if (process.env.NODE_ENV !== 'production') {
- warn('Data field "' + key + '" is already defined ' + 'as a prop. To provide default value for a prop, use the "default" ' + 'prop option; if you want to pass prop values to an instantiation ' + 'call, use the "propsData" option.', this);
- }
- }
- // observe data
- observe(data, this);
- };
-
- /**
- * Swap the instance's $data. Called in $data's setter.
- *
- * @param {Object} newData
- */
-
- Vue.prototype._setData = function (newData) {
- newData = newData || {};
- var oldData = this._data;
- this._data = newData;
- var keys, key, i;
- // unproxy keys not present in new data
- keys = Object.keys(oldData);
- i = keys.length;
- while (i--) {
- key = keys[i];
- if (!(key in newData)) {
- this._unproxy(key);
- }
- }
- // proxy keys not already proxied,
- // and trigger change for changed values
- keys = Object.keys(newData);
- i = keys.length;
- while (i--) {
- key = keys[i];
- if (!hasOwn(this, key)) {
- // new property
- this._proxy(key);
- }
- }
- oldData.__ob__.removeVm(this);
- observe(newData, this);
- this._digest();
- };
-
- /**
- * Proxy a property, so that
- * vm.prop === vm._data.prop
- *
- * @param {String} key
- */
-
- Vue.prototype._proxy = function (key) {
- if (!isReserved(key)) {
- // need to store ref to self here
- // because these getter/setters might
- // be called by child scopes via
- // prototype inheritance.
- var self = this;
- Object.defineProperty(self, key, {
- configurable: true,
- enumerable: true,
- get: function proxyGetter() {
- return self._data[key];
- },
- set: function proxySetter(val) {
- self._data[key] = val;
- }
- });
- }
- };
-
- /**
- * Unproxy a property.
- *
- * @param {String} key
- */
-
- Vue.prototype._unproxy = function (key) {
- if (!isReserved(key)) {
- delete this[key];
- }
- };
-
- /**
- * Force update on every watcher in scope.
- */
-
- Vue.prototype._digest = function () {
- for (var i = 0, l = this._watchers.length; i < l; i++) {
- this._watchers[i].update(true); // shallow updates
- }
- };
-
- /**
- * Setup computed properties. They are essentially
- * special getter/setters
- */
-
- function noop() {}
- Vue.prototype._initComputed = function () {
- var computed = this.$options.computed;
- if (computed) {
- for (var key in computed) {
- var userDef = computed[key];
- var def = {
- enumerable: true,
- configurable: true
- };
- if (typeof userDef === 'function') {
- def.get = makeComputedGetter(userDef, this);
- def.set = noop;
- } else {
- def.get = userDef.get ? userDef.cache !== false ? makeComputedGetter(userDef.get, this) : bind(userDef.get, this) : noop;
- def.set = userDef.set ? bind(userDef.set, this) : noop;
- }
- Object.defineProperty(this, key, def);
- }
- }
- };
-
- function makeComputedGetter(getter, owner) {
- var watcher = new Watcher(owner, getter, null, {
- lazy: true
- });
- return function computedGetter() {
- if (watcher.dirty) {
- watcher.evaluate();
- }
- if (Dep.target) {
- watcher.depend();
- }
- return watcher.value;
- };
- }
-
- /**
- * Setup instance methods. Methods must be bound to the
- * instance since they might be passed down as a prop to
- * child components.
- */
-
- Vue.prototype._initMethods = function () {
- var methods = this.$options.methods;
- if (methods) {
- for (var key in methods) {
- this[key] = bind(methods[key], this);
- }
- }
- };
-
- /**
- * Initialize meta information like $index, $key & $value.
- */
-
- Vue.prototype._initMeta = function () {
- var metas = this.$options._meta;
- if (metas) {
- for (var key in metas) {
- defineReactive(this, key, metas[key]);
- }
- }
- };
- }
-
- var eventRE = /^v-on:|^@/;
-
- function eventsMixin (Vue) {
- /**
- * Setup the instance's option events & watchers.
- * If the value is a string, we pull it from the
- * instance's methods by name.
- */
-
- Vue.prototype._initEvents = function () {
- var options = this.$options;
- if (options._asComponent) {
- registerComponentEvents(this, options.el);
- }
- registerCallbacks(this, '$on', options.events);
- registerCallbacks(this, '$watch', options.watch);
- };
-
- /**
- * Register v-on events on a child component
- *
- * @param {Vue} vm
- * @param {Element} el
- */
-
- function registerComponentEvents(vm, el) {
- var attrs = el.attributes;
- var name, value, handler;
- for (var i = 0, l = attrs.length; i < l; i++) {
- name = attrs[i].name;
- if (eventRE.test(name)) {
- name = name.replace(eventRE, '');
- // force the expression into a statement so that
- // it always dynamically resolves the method to call (#2670)
- // kinda ugly hack, but does the job.
- value = attrs[i].value;
- if (isSimplePath(value)) {
- value += '.apply(this, $arguments)';
- }
- handler = (vm._scope || vm._context).$eval(value, true);
- handler._fromParent = true;
- vm.$on(name.replace(eventRE), handler);
- }
- }
- }
-
- /**
- * Register callbacks for option events and watchers.
- *
- * @param {Vue} vm
- * @param {String} action
- * @param {Object} hash
- */
-
- function registerCallbacks(vm, action, hash) {
- if (!hash) return;
- var handlers, key, i, j;
- for (key in hash) {
- handlers = hash[key];
- if (isArray(handlers)) {
- for (i = 0, j = handlers.length; i < j; i++) {
- register(vm, action, key, handlers[i]);
- }
- } else {
- register(vm, action, key, handlers);
- }
- }
- }
-
- /**
- * Helper to register an event/watch callback.
- *
- * @param {Vue} vm
- * @param {String} action
- * @param {String} key
- * @param {Function|String|Object} handler
- * @param {Object} [options]
- */
-
- function register(vm, action, key, handler, options) {
- var type = typeof handler;
- if (type === 'function') {
- vm[action](key, handler, options);
- } else if (type === 'string') {
- var methods = vm.$options.methods;
- var method = methods && methods[handler];
- if (method) {
- vm[action](key, method, options);
- } else {
- process.env.NODE_ENV !== 'production' && warn('Unknown method: "' + handler + '" when ' + 'registering callback for ' + action + ': "' + key + '".', vm);
- }
- } else if (handler && type === 'object') {
- register(vm, action, key, handler.handler, handler);
- }
- }
-
- /**
- * Setup recursive attached/detached calls
- */
-
- Vue.prototype._initDOMHooks = function () {
- this.$on('hook:attached', onAttached);
- this.$on('hook:detached', onDetached);
- };
-
- /**
- * Callback to recursively call attached hook on children
- */
-
- function onAttached() {
- if (!this._isAttached) {
- this._isAttached = true;
- this.$children.forEach(callAttach);
- }
- }
-
- /**
- * Iterator to call attached hook
- *
- * @param {Vue} child
- */
-
- function callAttach(child) {
- if (!child._isAttached && inDoc(child.$el)) {
- child._callHook('attached');
- }
- }
-
- /**
- * Callback to recursively call detached hook on children
- */
-
- function onDetached() {
- if (this._isAttached) {
- this._isAttached = false;
- this.$children.forEach(callDetach);
- }
- }
-
- /**
- * Iterator to call detached hook
- *
- * @param {Vue} child
- */
-
- function callDetach(child) {
- if (child._isAttached && !inDoc(child.$el)) {
- child._callHook('detached');
- }
- }
-
- /**
- * Trigger all handlers for a hook
- *
- * @param {String} hook
- */
-
- Vue.prototype._callHook = function (hook) {
- this.$emit('pre-hook:' + hook);
- var handlers = this.$options[hook];
- if (handlers) {
- for (var i = 0, j = handlers.length; i < j; i++) {
- handlers[i].call(this);
- }
- }
- this.$emit('hook:' + hook);
- };
- }
-
- function noop() {}
-
- /**
- * A directive links a DOM element with a piece of data,
- * which is the result of evaluating an expression.
- * It registers a watcher with the expression and calls
- * the DOM update function when a change is triggered.
- *
- * @param {Object} descriptor
- * - {String} name
- * - {Object} def
- * - {String} expression
- * - {Array<Object>} [filters]
- * - {Object} [modifiers]
- * - {Boolean} literal
- * - {String} attr
- * - {String} arg
- * - {String} raw
- * - {String} [ref]
- * - {Array<Object>} [interp]
- * - {Boolean} [hasOneTime]
- * @param {Vue} vm
- * @param {Node} el
- * @param {Vue} [host] - transclusion host component
- * @param {Object} [scope] - v-for scope
- * @param {Fragment} [frag] - owner fragment
- * @constructor
- */
- function Directive(descriptor, vm, el, host, scope, frag) {
- this.vm = vm;
- this.el = el;
- // copy descriptor properties
- this.descriptor = descriptor;
- this.name = descriptor.name;
- this.expression = descriptor.expression;
- this.arg = descriptor.arg;
- this.modifiers = descriptor.modifiers;
- this.filters = descriptor.filters;
- this.literal = this.modifiers && this.modifiers.literal;
- // private
- this._locked = false;
- this._bound = false;
- this._listeners = null;
- // link context
- this._host = host;
- this._scope = scope;
- this._frag = frag;
- // store directives on node in dev mode
- if (process.env.NODE_ENV !== 'production' && this.el) {
- this.el._vue_directives = this.el._vue_directives || [];
- this.el._vue_directives.push(this);
- }
- }
-
- /**
- * Initialize the directive, mixin definition properties,
- * setup the watcher, call definition bind() and update()
- * if present.
- */
-
- Directive.prototype._bind = function () {
- var name = this.name;
- var descriptor = this.descriptor;
-
- // remove attribute
- if ((name !== 'cloak' || this.vm._isCompiled) && this.el && this.el.removeAttribute) {
- var attr = descriptor.attr || 'v-' + name;
- this.el.removeAttribute(attr);
- }
-
- // copy def properties
- var def = descriptor.def;
- if (typeof def === 'function') {
- this.update = def;
- } else {
- extend(this, def);
- }
-
- // setup directive params
- this._setupParams();
-
- // initial bind
- if (this.bind) {
- this.bind();
- }
- this._bound = true;
-
- if (this.literal) {
- this.update && this.update(descriptor.raw);
- } else if ((this.expression || this.modifiers) && (this.update || this.twoWay) && !this._checkStatement()) {
- // wrapped updater for context
- var dir = this;
- if (this.update) {
- this._update = function (val, oldVal) {
- if (!dir._locked) {
- dir.update(val, oldVal);
- }
- };
- } else {
- this._update = noop;
- }
- var preProcess = this._preProcess ? bind(this._preProcess, this) : null;
- var postProcess = this._postProcess ? bind(this._postProcess, this) : null;
- var watcher = this._watcher = new Watcher(this.vm, this.expression, this._update, // callback
- {
- filters: this.filters,
- twoWay: this.twoWay,
- deep: this.deep,
- preProcess: preProcess,
- postProcess: postProcess,
- scope: this._scope
- });
- // v-model with inital inline value need to sync back to
- // model instead of update to DOM on init. They would
- // set the afterBind hook to indicate that.
- if (this.afterBind) {
- this.afterBind();
- } else if (this.update) {
- this.update(watcher.value);
- }
- }
- };
-
- /**
- * Setup all param attributes, e.g. track-by,
- * transition-mode, etc...
- */
-
- Directive.prototype._setupParams = function () {
- if (!this.params) {
- return;
- }
- var params = this.params;
- // swap the params array with a fresh object.
- this.params = Object.create(null);
- var i = params.length;
- var key, val, mappedKey;
- while (i--) {
- key = hyphenate(params[i]);
- mappedKey = camelize(key);
- val = getBindAttr(this.el, key);
- if (val != null) {
- // dynamic
- this._setupParamWatcher(mappedKey, val);
- } else {
- // static
- val = getAttr(this.el, key);
- if (val != null) {
- this.params[mappedKey] = val === '' ? true : val;
- }
- }
- }
- };
-
- /**
- * Setup a watcher for a dynamic param.
- *
- * @param {String} key
- * @param {String} expression
- */
-
- Directive.prototype._setupParamWatcher = function (key, expression) {
- var self = this;
- var called = false;
- var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
- self.params[key] = val;
- // since we are in immediate mode,
- // only call the param change callbacks if this is not the first update.
- if (called) {
- var cb = self.paramWatchers && self.paramWatchers[key];
- if (cb) {
- cb.call(self, val, oldVal);
- }
- } else {
- called = true;
- }
- }, {
- immediate: true,
- user: false
- });(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
- };
-
- /**
- * Check if the directive is a function caller
- * and if the expression is a callable one. If both true,
- * we wrap up the expression and use it as the event
- * handler.
- *
- * e.g. on-click="a++"
- *
- * @return {Boolean}
- */
-
- Directive.prototype._checkStatement = function () {
- var expression = this.expression;
- if (expression && this.acceptStatement && !isSimplePath(expression)) {
- var fn = parseExpression(expression).get;
- var scope = this._scope || this.vm;
- var handler = function handler(e) {
- scope.$event = e;
- fn.call(scope, scope);
- scope.$event = null;
- };
- if (this.filters) {
- handler = scope._applyFilters(handler, null, this.filters);
- }
- this.update(handler);
- return true;
- }
- };
-
- /**
- * Set the corresponding value with the setter.
- * This should only be used in two-way directives
- * e.g. v-model.
- *
- * @param {*} value
- * @public
- */
-
- Directive.prototype.set = function (value) {
- /* istanbul ignore else */
- if (this.twoWay) {
- this._withLock(function () {
- this._watcher.set(value);
- });
- } else if (process.env.NODE_ENV !== 'production') {
- warn('Directive.set() can only be used inside twoWay' + 'directives.');
- }
- };
-
- /**
- * Execute a function while preventing that function from
- * triggering updates on this directive instance.
- *
- * @param {Function} fn
- */
-
- Directive.prototype._withLock = function (fn) {
- var self = this;
- self._locked = true;
- fn.call(self);
- nextTick(function () {
- self._locked = false;
- });
- };
-
- /**
- * Convenience method that attaches a DOM event listener
- * to the directive element and autometically tears it down
- * during unbind.
- *
- * @param {String} event
- * @param {Function} handler
- * @param {Boolean} [useCapture]
- */
-
- Directive.prototype.on = function (event, handler, useCapture) {
- on(this.el, event, handler, useCapture);(this._listeners || (this._listeners = [])).push([event, handler]);
- };
-
- /**
- * Teardown the watcher and call unbind.
- */
-
- Directive.prototype._teardown = function () {
- if (this._bound) {
- this._bound = false;
- if (this.unbind) {
- this.unbind();
- }
- if (this._watcher) {
- this._watcher.teardown();
- }
- var listeners = this._listeners;
- var i;
- if (listeners) {
- i = listeners.length;
- while (i--) {
- off(this.el, listeners[i][0], listeners[i][1]);
- }
- }
- var unwatchFns = this._paramUnwatchFns;
- if (unwatchFns) {
- i = unwatchFns.length;
- while (i--) {
- unwatchFns[i]();
- }
- }
- if (process.env.NODE_ENV !== 'production' && this.el) {
- this.el._vue_directives.$remove(this);
- }
- this.vm = this.el = this._watcher = this._listeners = null;
- }
- };
-
- function lifecycleMixin (Vue) {
- /**
- * Update v-ref for component.
- *
- * @param {Boolean} remove
- */
-
- Vue.prototype._updateRef = function (remove) {
- var ref = this.$options._ref;
- if (ref) {
- var refs = (this._scope || this._context).$refs;
- if (remove) {
- if (refs[ref] === this) {
- refs[ref] = null;
- }
- } else {
- refs[ref] = this;
- }
- }
- };
-
- /**
- * Transclude, compile and link element.
- *
- * If a pre-compiled linker is available, that means the
- * passed in element will be pre-transcluded and compiled
- * as well - all we need to do is to call the linker.
- *
- * Otherwise we need to call transclude/compile/link here.
- *
- * @param {Element} el
- */
-
- Vue.prototype._compile = function (el) {
- var options = this.$options;
-
- // transclude and init element
- // transclude can potentially replace original
- // so we need to keep reference; this step also injects
- // the template and caches the original attributes
- // on the container node and replacer node.
- var original = el;
- el = transclude(el, options);
- this._initElement(el);
-
- // handle v-pre on root node (#2026)
- if (el.nodeType === 1 && getAttr(el, 'v-pre') !== null) {
- return;
- }
-
- // root is always compiled per-instance, because
- // container attrs and props can be different every time.
- var contextOptions = this._context && this._context.$options;
- var rootLinker = compileRoot(el, options, contextOptions);
-
- // resolve slot distribution
- resolveSlots(this, options._content);
-
- // compile and link the rest
- var contentLinkFn;
- var ctor = this.constructor;
- // component compilation can be cached
- // as long as it's not using inline-template
- if (options._linkerCachable) {
- contentLinkFn = ctor.linker;
- if (!contentLinkFn) {
- contentLinkFn = ctor.linker = compile(el, options);
- }
- }
-
- // link phase
- // make sure to link root with prop scope!
- var rootUnlinkFn = rootLinker(this, el, this._scope);
- var contentUnlinkFn = contentLinkFn ? contentLinkFn(this, el) : compile(el, options)(this, el);
-
- // register composite unlink function
- // to be called during instance destruction
- this._unlinkFn = function () {
- rootUnlinkFn();
- // passing destroying: true to avoid searching and
- // splicing the directives
- contentUnlinkFn(true);
- };
-
- // finally replace original
- if (options.replace) {
- replace(original, el);
- }
-
- this._isCompiled = true;
- this._callHook('compiled');
- };
-
- /**
- * Initialize instance element. Called in the public
- * $mount() method.
- *
- * @param {Element} el
- */
-
- Vue.prototype._initElement = function (el) {
- if (isFragment(el)) {
- this._isFragment = true;
- this.$el = this._fragmentStart = el.firstChild;
- this._fragmentEnd = el.lastChild;
- // set persisted text anchors to empty
- if (this._fragmentStart.nodeType === 3) {
- this._fragmentStart.data = this._fragmentEnd.data = '';
- }
- this._fragment = el;
- } else {
- this.$el = el;
- }
- this.$el.__vue__ = this;
- this._callHook('beforeCompile');
- };
-
- /**
- * Create and bind a directive to an element.
- *
- * @param {Object} descriptor - parsed directive descriptor
- * @param {Node} node - target node
- * @param {Vue} [host] - transclusion host component
- * @param {Object} [scope] - v-for scope
- * @param {Fragment} [frag] - owner fragment
- */
-
- Vue.prototype._bindDir = function (descriptor, node, host, scope, frag) {
- this._directives.push(new Directive(descriptor, this, node, host, scope, frag));
- };
-
- /**
- * Teardown an instance, unobserves the data, unbind all the
- * directives, turn off all the event listeners, etc.
- *
- * @param {Boolean} remove - whether to remove the DOM node.
- * @param {Boolean} deferCleanup - if true, defer cleanup to
- * be called later
- */
-
- Vue.prototype._destroy = function (remove, deferCleanup) {
- if (this._isBeingDestroyed) {
- if (!deferCleanup) {
- this._cleanup();
- }
- return;
- }
-
- var destroyReady;
- var pendingRemoval;
-
- var self = this;
- // Cleanup should be called either synchronously or asynchronoysly as
- // callback of this.$remove(), or if remove and deferCleanup are false.
- // In any case it should be called after all other removing, unbinding and
- // turning of is done
- var cleanupIfPossible = function cleanupIfPossible() {
- if (destroyReady && !pendingRemoval && !deferCleanup) {
- self._cleanup();
- }
- };
-
- // remove DOM element
- if (remove && this.$el) {
- pendingRemoval = true;
- this.$remove(function () {
- pendingRemoval = false;
- cleanupIfPossible();
- });
- }
-
- this._callHook('beforeDestroy');
- this._isBeingDestroyed = true;
- var i;
- // remove self from parent. only necessary
- // if parent is not being destroyed as well.
- var parent = this.$parent;
- if (parent && !parent._isBeingDestroyed) {
- parent.$children.$remove(this);
- // unregister ref (remove: true)
- this._updateRef(true);
- }
- // destroy all children.
- i = this.$children.length;
- while (i--) {
- this.$children[i].$destroy();
- }
- // teardown props
- if (this._propsUnlinkFn) {
- this._propsUnlinkFn();
- }
- // teardown all directives. this also tearsdown all
- // directive-owned watchers.
- if (this._unlinkFn) {
- this._unlinkFn();
- }
- i = this._watchers.length;
- while (i--) {
- this._watchers[i].teardown();
- }
- // remove reference to self on $el
- if (this.$el) {
- this.$el.__vue__ = null;
- }
-
- destroyReady = true;
- cleanupIfPossible();
- };
-
- /**
- * Clean up to ensure garbage collection.
- * This is called after the leave transition if there
- * is any.
- */
-
- Vue.prototype._cleanup = function () {
- if (this._isDestroyed) {
- return;
- }
- // remove self from owner fragment
- // do it in cleanup so that we can call $destroy with
- // defer right when a fragment is about to be removed.
- if (this._frag) {
- this._frag.children.$remove(this);
- }
- // remove reference from data ob
- // frozen object may not have observer.
- if (this._data && this._data.__ob__) {
- this._data.__ob__.removeVm(this);
- }
- // Clean up references to private properties and other
- // instances. preserve reference to _data so that proxy
- // accessors still work. The only potential side effect
- // here is that mutating the instance after it's destroyed
- // may affect the state of other components that are still
- // observing the same object, but that seems to be a
- // reasonable responsibility for the user rather than
- // always throwing an error on them.
- this.$el = this.$parent = this.$root = this.$children = this._watchers = this._context = this._scope = this._directives = null;
- // call the last hook...
- this._isDestroyed = true;
- this._callHook('destroyed');
- // turn off all instance listeners.
- this.$off();
- };
- }
-
- function miscMixin (Vue) {
- /**
- * Apply a list of filter (descriptors) to a value.
- * Using plain for loops here because this will be called in
- * the getter of any watcher with filters so it is very
- * performance sensitive.
- *
- * @param {*} value
- * @param {*} [oldValue]
- * @param {Array} filters
- * @param {Boolean} write
- * @return {*}
- */
-
- Vue.prototype._applyFilters = function (value, oldValue, filters, write) {
- var filter, fn, args, arg, offset, i, l, j, k;
- for (i = 0, l = filters.length; i < l; i++) {
- filter = filters[write ? l - i - 1 : i];
- fn = resolveAsset(this.$options, 'filters', filter.name, true);
- if (!fn) continue;
- fn = write ? fn.write : fn.read || fn;
- if (typeof fn !== 'function') continue;
- args = write ? [value, oldValue] : [value];
- offset = write ? 2 : 1;
- if (filter.args) {
- for (j = 0, k = filter.args.length; j < k; j++) {
- arg = filter.args[j];
- args[j + offset] = arg.dynamic ? this.$get(arg.value) : arg.value;
- }
- }
- value = fn.apply(this, args);
- }
- return value;
- };
-
- /**
- * Resolve a component, depending on whether the component
- * is defined normally or using an async factory function.
- * Resolves synchronously if already resolved, otherwise
- * resolves asynchronously and caches the resolved
- * constructor on the factory.
- *
- * @param {String|Function} value
- * @param {Function} cb
- */
-
- Vue.prototype._resolveComponent = function (value, cb) {
- var factory;
- if (typeof value === 'function') {
- factory = value;
- } else {
- factory = resolveAsset(this.$options, 'components', value, true);
- }
- /* istanbul ignore if */
- if (!factory) {
- return;
- }
- // async component factory
- if (!factory.options) {
- if (factory.resolved) {
- // cached
- cb(factory.resolved);
- } else if (factory.requested) {
- // pool callbacks
- factory.pendingCallbacks.push(cb);
- } else {
- factory.requested = true;
- var cbs = factory.pendingCallbacks = [cb];
- factory.call(this, function resolve(res) {
- if (isPlainObject(res)) {
- res = Vue.extend(res);
- }
- // cache resolved
- factory.resolved = res;
- // invoke callbacks
- for (var i = 0, l = cbs.length; i < l; i++) {
- cbs[i](res);
- }
- }, function reject(reason) {
- process.env.NODE_ENV !== 'production' && warn('Failed to resolve async component' + (typeof value === 'string' ? ': ' + value : '') + '. ' + (reason ? '\nReason: ' + reason : ''));
- });
- }
- } else {
- // normal component
- cb(factory);
- }
- };
- }
-
- var filterRE$1 = /[^|]\|[^|]/;
-
- function dataAPI (Vue) {
- /**
- * Get the value from an expression on this vm.
- *
- * @param {String} exp
- * @param {Boolean} [asStatement]
- * @return {*}
- */
-
- Vue.prototype.$get = function (exp, asStatement) {
- var res = parseExpression(exp);
- if (res) {
- if (asStatement) {
- var self = this;
- return function statementHandler() {
- self.$arguments = toArray(arguments);
- var result = res.get.call(self, self);
- self.$arguments = null;
- return result;
- };
- } else {
- try {
- return res.get.call(this, this);
- } catch (e) {}
- }
- }
- };
-
- /**
- * Set the value from an expression on this vm.
- * The expression must be a valid left-hand
- * expression in an assignment.
- *
- * @param {String} exp
- * @param {*} val
- */
-
- Vue.prototype.$set = function (exp, val) {
- var res = parseExpression(exp, true);
- if (res && res.set) {
- res.set.call(this, this, val);
- }
- };
-
- /**
- * Delete a property on the VM
- *
- * @param {String} key
- */
-
- Vue.prototype.$delete = function (key) {
- del(this._data, key);
- };
-
- /**
- * Watch an expression, trigger callback when its
- * value changes.
- *
- * @param {String|Function} expOrFn
- * @param {Function} cb
- * @param {Object} [options]
- * - {Boolean} deep
- * - {Boolean} immediate
- * @return {Function} - unwatchFn
- */
-
- Vue.prototype.$watch = function (expOrFn, cb, options) {
- var vm = this;
- var parsed;
- if (typeof expOrFn === 'string') {
- parsed = parseDirective(expOrFn);
- expOrFn = parsed.expression;
- }
- var watcher = new Watcher(vm, expOrFn, cb, {
- deep: options && options.deep,
- sync: options && options.sync,
- filters: parsed && parsed.filters,
- user: !options || options.user !== false
- });
- if (options && options.immediate) {
- cb.call(vm, watcher.value);
- }
- return function unwatchFn() {
- watcher.teardown();
- };
- };
-
- /**
- * Evaluate a text directive, including filters.
- *
- * @param {String} text
- * @param {Boolean} [asStatement]
- * @return {String}
- */
-
- Vue.prototype.$eval = function (text, asStatement) {
- // check for filters.
- if (filterRE$1.test(text)) {
- var dir = parseDirective(text);
- // the filter regex check might give false positive
- // for pipes inside strings, so it's possible that
- // we don't get any filters here
- var val = this.$get(dir.expression, asStatement);
- return dir.filters ? this._applyFilters(val, null, dir.filters) : val;
- } else {
- // no filter
- return this.$get(text, asStatement);
- }
- };
-
- /**
- * Interpolate a piece of template text.
- *
- * @param {String} text
- * @return {String}
- */
-
- Vue.prototype.$interpolate = function (text) {
- var tokens = parseText(text);
- var vm = this;
- if (tokens) {
- if (tokens.length === 1) {
- return vm.$eval(tokens[0].value) + '';
- } else {
- return tokens.map(function (token) {
- return token.tag ? vm.$eval(token.value) : token.value;
- }).join('');
- }
- } else {
- return text;
- }
- };
-
- /**
- * Log instance data as a plain JS object
- * so that it is easier to inspect in console.
- * This method assumes console is available.
- *
- * @param {String} [path]
- */
-
- Vue.prototype.$log = function (path) {
- var data = path ? getPath(this._data, path) : this._data;
- if (data) {
- data = clean(data);
- }
- // include computed fields
- if (!path) {
- var key;
- for (key in this.$options.computed) {
- data[key] = clean(this[key]);
- }
- if (this._props) {
- for (key in this._props) {
- data[key] = clean(this[key]);
- }
- }
- }
- console.log(data);
- };
-
- /**
- * "clean" a getter/setter converted object into a plain
- * object copy.
- *
- * @param {Object} - obj
- * @return {Object}
- */
-
- function clean(obj) {
- return JSON.parse(JSON.stringify(obj));
- }
- }
-
- function domAPI (Vue) {
- /**
- * Convenience on-instance nextTick. The callback is
- * auto-bound to the instance, and this avoids component
- * modules having to rely on the global Vue.
- *
- * @param {Function} fn
- */
-
- Vue.prototype.$nextTick = function (fn) {
- nextTick(fn, this);
- };
-
- /**
- * Append instance to target
- *
- * @param {Node} target
- * @param {Function} [cb]
- * @param {Boolean} [withTransition] - defaults to true
- */
-
- Vue.prototype.$appendTo = function (target, cb, withTransition) {
- return insert(this, target, cb, withTransition, append, appendWithTransition);
- };
-
- /**
- * Prepend instance to target
- *
- * @param {Node} target
- * @param {Function} [cb]
- * @param {Boolean} [withTransition] - defaults to true
- */
-
- Vue.prototype.$prependTo = function (target, cb, withTransition) {
- target = query(target);
- if (target.hasChildNodes()) {
- this.$before(target.firstChild, cb, withTransition);
- } else {
- this.$appendTo(target, cb, withTransition);
- }
- return this;
- };
-
- /**
- * Insert instance before target
- *
- * @param {Node} target
- * @param {Function} [cb]
- * @param {Boolean} [withTransition] - defaults to true
- */
-
- Vue.prototype.$before = function (target, cb, withTransition) {
- return insert(this, target, cb, withTransition, beforeWithCb, beforeWithTransition);
- };
-
- /**
- * Insert instance after target
- *
- * @param {Node} target
- * @param {Function} [cb]
- * @param {Boolean} [withTransition] - defaults to true
- */
-
- Vue.prototype.$after = function (target, cb, withTransition) {
- target = query(target);
- if (target.nextSibling) {
- this.$before(target.nextSibling, cb, withTransition);
- } else {
- this.$appendTo(target.parentNode, cb, withTransition);
- }
- return this;
- };
-
- /**
- * Remove instance from DOM
- *
- * @param {Function} [cb]
- * @param {Boolean} [withTransition] - defaults to true
- */
-
- Vue.prototype.$remove = function (cb, withTransition) {
- if (!this.$el.parentNode) {
- return cb && cb();
- }
- var inDocument = this._isAttached && inDoc(this.$el);
- // if we are not in document, no need to check
- // for transitions
- if (!inDocument) withTransition = false;
- var self = this;
- var realCb = function realCb() {
- if (inDocument) self._callHook('detached');
- if (cb) cb();
- };
- if (this._isFragment) {
- removeNodeRange(this._fragmentStart, this._fragmentEnd, this, this._fragment, realCb);
- } else {
- var op = withTransition === false ? removeWithCb : removeWithTransition;
- op(this.$el, this, realCb);
- }
- return this;
- };
-
- /**
- * Shared DOM insertion function.
- *
- * @param {Vue} vm
- * @param {Element} target
- * @param {Function} [cb]
- * @param {Boolean} [withTransition]
- * @param {Function} op1 - op for non-transition insert
- * @param {Function} op2 - op for transition insert
- * @return vm
- */
-
- function insert(vm, target, cb, withTransition, op1, op2) {
- target = query(target);
- var targetIsDetached = !inDoc(target);
- var op = withTransition === false || targetIsDetached ? op1 : op2;
- var shouldCallHook = !targetIsDetached && !vm._isAttached && !inDoc(vm.$el);
- if (vm._isFragment) {
- mapNodeRange(vm._fragmentStart, vm._fragmentEnd, function (node) {
- op(node, target, vm);
- });
- cb && cb();
- } else {
- op(vm.$el, target, vm, cb);
- }
- if (shouldCallHook) {
- vm._callHook('attached');
- }
- return vm;
- }
-
- /**
- * Check for selectors
- *
- * @param {String|Element} el
- */
-
- function query(el) {
- return typeof el === 'string' ? document.querySelector(el) : el;
- }
-
- /**
- * Append operation that takes a callback.
- *
- * @param {Node} el
- * @param {Node} target
- * @param {Vue} vm - unused
- * @param {Function} [cb]
- */
-
- function append(el, target, vm, cb) {
- target.appendChild(el);
- if (cb) cb();
- }
-
- /**
- * InsertBefore operation that takes a callback.
- *
- * @param {Node} el
- * @param {Node} target
- * @param {Vue} vm - unused
- * @param {Function} [cb]
- */
-
- function beforeWithCb(el, target, vm, cb) {
- before(el, target);
- if (cb) cb();
- }
-
- /**
- * Remove operation that takes a callback.
- *
- * @param {Node} el
- * @param {Vue} vm - unused
- * @param {Function} [cb]
- */
-
- function removeWithCb(el, vm, cb) {
- remove(el);
- if (cb) cb();
- }
- }
-
- function eventsAPI (Vue) {
- /**
- * Listen on the given `event` with `fn`.
- *
- * @param {String} event
- * @param {Function} fn
- */
-
- Vue.prototype.$on = function (event, fn) {
- (this._events[event] || (this._events[event] = [])).push(fn);
- modifyListenerCount(this, event, 1);
- return this;
- };
-
- /**
- * Adds an `event` listener that will be invoked a single
- * time then automatically removed.
- *
- * @param {String} event
- * @param {Function} fn
- */
-
- Vue.prototype.$once = function (event, fn) {
- var self = this;
- function on() {
- self.$off(event, on);
- fn.apply(this, arguments);
- }
- on.fn = fn;
- this.$on(event, on);
- return this;
- };
-
- /**
- * Remove the given callback for `event` or all
- * registered callbacks.
- *
- * @param {String} event
- * @param {Function} fn
- */
-
- Vue.prototype.$off = function (event, fn) {
- var cbs;
- // all
- if (!arguments.length) {
- if (this.$parent) {
- for (event in this._events) {
- cbs = this._events[event];
- if (cbs) {
- modifyListenerCount(this, event, -cbs.length);
- }
- }
- }
- this._events = {};
- return this;
- }
- // specific event
- cbs = this._events[event];
- if (!cbs) {
- return this;
- }
- if (arguments.length === 1) {
- modifyListenerCount(this, event, -cbs.length);
- this._events[event] = null;
- return this;
- }
- // specific handler
- var cb;
- var i = cbs.length;
- while (i--) {
- cb = cbs[i];
- if (cb === fn || cb.fn === fn) {
- modifyListenerCount(this, event, -1);
- cbs.splice(i, 1);
- break;
- }
- }
- return this;
- };
-
- /**
- * Trigger an event on self.
- *
- * @param {String|Object} event
- * @return {Boolean} shouldPropagate
- */
-
- Vue.prototype.$emit = function (event) {
- var isSource = typeof event === 'string';
- event = isSource ? event : event.name;
- var cbs = this._events[event];
- var shouldPropagate = isSource || !cbs;
- if (cbs) {
- cbs = cbs.length > 1 ? toArray(cbs) : cbs;
- // this is a somewhat hacky solution to the question raised
- // in #2102: for an inline component listener like <comp @test="doThis">,
- // the propagation handling is somewhat broken. Therefore we
- // need to treat these inline callbacks differently.
- var hasParentCbs = isSource && cbs.some(function (cb) {
- return cb._fromParent;
- });
- if (hasParentCbs) {
- shouldPropagate = false;
- }
- var args = toArray(arguments, 1);
- for (var i = 0, l = cbs.length; i < l; i++) {
- var cb = cbs[i];
- var res = cb.apply(this, args);
- if (res === true && (!hasParentCbs || cb._fromParent)) {
- shouldPropagate = true;
- }
- }
- }
- return shouldPropagate;
- };
-
- /**
- * Recursively broadcast an event to all children instances.
- *
- * @param {String|Object} event
- * @param {...*} additional arguments
- */
-
- Vue.prototype.$broadcast = function (event) {
- var isSource = typeof event === 'string';
- event = isSource ? event : event.name;
- // if no child has registered for this event,
- // then there's no need to broadcast.
- if (!this._eventsCount[event]) return;
- var children = this.$children;
- var args = toArray(arguments);
- if (isSource) {
- // use object event to indicate non-source emit
- // on children
- args[0] = { name: event, source: this };
- }
- for (var i = 0, l = children.length; i < l; i++) {
- var child = children[i];
- var shouldPropagate = child.$emit.apply(child, args);
- if (shouldPropagate) {
- child.$broadcast.apply(child, args);
- }
- }
- return this;
- };
-
- /**
- * Recursively propagate an event up the parent chain.
- *
- * @param {String} event
- * @param {...*} additional arguments
- */
-
- Vue.prototype.$dispatch = function (event) {
- var shouldPropagate = this.$emit.apply(this, arguments);
- if (!shouldPropagate) return;
- var parent = this.$parent;
- var args = toArray(arguments);
- // use object event to indicate non-source emit
- // on parents
- args[0] = { name: event, source: this };
- while (parent) {
- shouldPropagate = parent.$emit.apply(parent, args);
- parent = shouldPropagate ? parent.$parent : null;
- }
- return this;
- };
-
- /**
- * Modify the listener counts on all parents.
- * This bookkeeping allows $broadcast to return early when
- * no child has listened to a certain event.
- *
- * @param {Vue} vm
- * @param {String} event
- * @param {Number} count
- */
-
- var hookRE = /^hook:/;
- function modifyListenerCount(vm, event, count) {
- var parent = vm.$parent;
- // hooks do not get broadcasted so no need
- // to do bookkeeping for them
- if (!parent || !count || hookRE.test(event)) return;
- while (parent) {
- parent._eventsCount[event] = (parent._eventsCount[event] || 0) + count;
- parent = parent.$parent;
- }
- }
- }
-
- function lifecycleAPI (Vue) {
- /**
- * Set instance target element and kick off the compilation
- * process. The passed in `el` can be a selector string, an
- * existing Element, or a DocumentFragment (for block
- * instances).
- *
- * @param {Element|DocumentFragment|string} el
- * @public
- */
-
- Vue.prototype.$mount = function (el) {
- if (this._isCompiled) {
- process.env.NODE_ENV !== 'production' && warn('$mount() should be called only once.', this);
- return;
- }
- el = query(el);
- if (!el) {
- el = document.createElement('div');
- }
- this._compile(el);
- this._initDOMHooks();
- if (inDoc(this.$el)) {
- this._callHook('attached');
- ready.call(this);
- } else {
- this.$once('hook:attached', ready);
- }
- return this;
- };
-
- /**
- * Mark an instance as ready.
- */
-
- function ready() {
- this._isAttached = true;
- this._isReady = true;
- this._callHook('ready');
- }
-
- /**
- * Teardown the instance, simply delegate to the internal
- * _destroy.
- *
- * @param {Boolean} remove
- * @param {Boolean} deferCleanup
- */
-
- Vue.prototype.$destroy = function (remove, deferCleanup) {
- this._destroy(remove, deferCleanup);
- };
-
- /**
- * Partially compile a piece of DOM and return a
- * decompile function.
- *
- * @param {Element|DocumentFragment} el
- * @param {Vue} [host]
- * @param {Object} [scope]
- * @param {Fragment} [frag]
- * @return {Function}
- */
-
- Vue.prototype.$compile = function (el, host, scope, frag) {
- return compile(el, this.$options, true)(this, el, host, scope, frag);
- };
- }
-
- /**
- * The exposed Vue constructor.
- *
- * API conventions:
- * - public API methods/properties are prefixed with `$`
- * - internal methods/properties are prefixed with `_`
- * - non-prefixed properties are assumed to be proxied user
- * data.
- *
- * @constructor
- * @param {Object} [options]
- * @public
- */
-
- function Vue(options) {
- this._init(options);
- }
-
- // install internals
- initMixin(Vue);
- stateMixin(Vue);
- eventsMixin(Vue);
- lifecycleMixin(Vue);
- miscMixin(Vue);
-
- // install instance APIs
- dataAPI(Vue);
- domAPI(Vue);
- eventsAPI(Vue);
- lifecycleAPI(Vue);
-
- var slot = {
-
- priority: SLOT,
- params: ['name'],
-
- bind: function bind() {
- // this was resolved during component transclusion
- var name = this.params.name || 'default';
- var content = this.vm._slotContents && this.vm._slotContents[name];
- if (!content || !content.hasChildNodes()) {
- this.fallback();
- } else {
- this.compile(content.cloneNode(true), this.vm._context, this.vm);
- }
- },
-
- compile: function compile(content, context, host) {
- if (content && context) {
- if (this.el.hasChildNodes() && content.childNodes.length === 1 && content.childNodes[0].nodeType === 1 && content.childNodes[0].hasAttribute('v-if')) {
- // if the inserted slot has v-if
- // inject fallback content as the v-else
- var elseBlock = document.createElement('template');
- elseBlock.setAttribute('v-else', '');
- elseBlock.innerHTML = this.el.innerHTML;
- // the else block should be compiled in child scope
- elseBlock._context = this.vm;
- content.appendChild(elseBlock);
- }
- var scope = host ? host._scope : this._scope;
- this.unlink = context.$compile(content, host, scope, this._frag);
- }
- if (content) {
- replace(this.el, content);
- } else {
- remove(this.el);
- }
- },
-
- fallback: function fallback() {
- this.compile(extractContent(this.el, true), this.vm);
- },
-
- unbind: function unbind() {
- if (this.unlink) {
- this.unlink();
- }
- }
- };
-
- var partial = {
-
- priority: PARTIAL,
-
- params: ['name'],
-
- // watch changes to name for dynamic partials
- paramWatchers: {
- name: function name(value) {
- vIf.remove.call(this);
- if (value) {
- this.insert(value);
- }
- }
- },
-
- bind: function bind() {
- this.anchor = createAnchor('v-partial');
- replace(this.el, this.anchor);
- this.insert(this.params.name);
- },
-
- insert: function insert(id) {
- var partial = resolveAsset(this.vm.$options, 'partials', id, true);
- if (partial) {
- this.factory = new FragmentFactory(this.vm, partial);
- vIf.insert.call(this);
- }
- },
-
- unbind: function unbind() {
- if (this.frag) {
- this.frag.destroy();
- }
- }
- };
-
- var elementDirectives = {
- slot: slot,
- partial: partial
- };
-
- var convertArray = vFor._postProcess;
-
- /**
- * Limit filter for arrays
- *
- * @param {Number} n
- * @param {Number} offset (Decimal expected)
- */
-
- function limitBy(arr, n, offset) {
- offset = offset ? parseInt(offset, 10) : 0;
- n = toNumber(n);
- return typeof n === 'number' ? arr.slice(offset, offset + n) : arr;
- }
-
- /**
- * Filter filter for arrays
- *
- * @param {String} search
- * @param {String} [delimiter]
- * @param {String} ...dataKeys
- */
-
- function filterBy(arr, search, delimiter) {
- arr = convertArray(arr);
- if (search == null) {
- return arr;
- }
- if (typeof search === 'function') {
- return arr.filter(search);
- }
- // cast to lowercase string
- search = ('' + search).toLowerCase();
- // allow optional `in` delimiter
- // because why not
- var n = delimiter === 'in' ? 3 : 2;
- // extract and flatten keys
- var keys = Array.prototype.concat.apply([], toArray(arguments, n));
- var res = [];
- var item, key, val, j;
- for (var i = 0, l = arr.length; i < l; i++) {
- item = arr[i];
- val = item && item.$value || item;
- j = keys.length;
- if (j) {
- while (j--) {
- key = keys[j];
- if (key === '$key' && contains(item.$key, search) || contains(getPath(val, key), search)) {
- res.push(item);
- break;
- }
- }
- } else if (contains(item, search)) {
- res.push(item);
- }
- }
- return res;
- }
-
- /**
- * Filter filter for arrays
- *
- * @param {String|Array<String>|Function} ...sortKeys
- * @param {Number} [order]
- */
-
- function orderBy(arr) {
- var comparator = null;
- var sortKeys = undefined;
- arr = convertArray(arr);
-
- // determine order (last argument)
- var args = toArray(arguments, 1);
- var order = args[args.length - 1];
- if (typeof order === 'number') {
- order = order < 0 ? -1 : 1;
- args = args.length > 1 ? args.slice(0, -1) : args;
- } else {
- order = 1;
- }
-
- // determine sortKeys & comparator
- var firstArg = args[0];
- if (!firstArg) {
- return arr;
- } else if (typeof firstArg === 'function') {
- // custom comparator
- comparator = function (a, b) {
- return firstArg(a, b) * order;
- };
- } else {
- // string keys. flatten first
- sortKeys = Array.prototype.concat.apply([], args);
- comparator = function (a, b, i) {
- i = i || 0;
- return i >= sortKeys.length - 1 ? baseCompare(a, b, i) : baseCompare(a, b, i) || comparator(a, b, i + 1);
- };
- }
-
- function baseCompare(a, b, sortKeyIndex) {
- var sortKey = sortKeys[sortKeyIndex];
- if (sortKey) {
- if (sortKey !== '$key') {
- if (isObject(a) && '$value' in a) a = a.$value;
- if (isObject(b) && '$value' in b) b = b.$value;
- }
- a = isObject(a) ? getPath(a, sortKey) : a;
- b = isObject(b) ? getPath(b, sortKey) : b;
- }
- return a === b ? 0 : a > b ? order : -order;
- }
-
- // sort on a copy to avoid mutating original array
- return arr.slice().sort(comparator);
- }
-
- /**
- * String contain helper
- *
- * @param {*} val
- * @param {String} search
- */
-
- function contains(val, search) {
- var i;
- if (isPlainObject(val)) {
- var keys = Object.keys(val);
- i = keys.length;
- while (i--) {
- if (contains(val[keys[i]], search)) {
- return true;
- }
- }
- } else if (isArray(val)) {
- i = val.length;
- while (i--) {
- if (contains(val[i], search)) {
- return true;
- }
- }
- } else if (val != null) {
- return val.toString().toLowerCase().indexOf(search) > -1;
- }
- }
-
- var digitsRE = /(\d{3})(?=\d)/g;
-
- // asset collections must be a plain object.
- var filters = {
-
- orderBy: orderBy,
- filterBy: filterBy,
- limitBy: limitBy,
-
- /**
- * Stringify value.
- *
- * @param {Number} indent
- */
-
- json: {
- read: function read(value, indent) {
- return typeof value === 'string' ? value : JSON.stringify(value, null, Number(indent) || 2);
- },
- write: function write(value) {
- try {
- return JSON.parse(value);
- } catch (e) {
- return value;
- }
- }
- },
-
- /**
- * 'abc' => 'Abc'
- */
-
- capitalize: function capitalize(value) {
- if (!value && value !== 0) return '';
- value = value.toString();
- return value.charAt(0).toUpperCase() + value.slice(1);
- },
-
- /**
- * 'abc' => 'ABC'
- */
-
- uppercase: function uppercase(value) {
- return value || value === 0 ? value.toString().toUpperCase() : '';
- },
-
- /**
- * 'AbC' => 'abc'
- */
-
- lowercase: function lowercase(value) {
- return value || value === 0 ? value.toString().toLowerCase() : '';
- },
-
- /**
- * 12345 => $12,345.00
- *
- * @param {String} sign
- * @param {Number} decimals Decimal places
- */
-
- currency: function currency(value, _currency, decimals) {
- value = parseFloat(value);
- if (!isFinite(value) || !value && value !== 0) return '';
- _currency = _currency != null ? _currency : '$';
- decimals = decimals != null ? decimals : 2;
- var stringified = Math.abs(value).toFixed(decimals);
- var _int = decimals ? stringified.slice(0, -1 - decimals) : stringified;
- var i = _int.length % 3;
- var head = i > 0 ? _int.slice(0, i) + (_int.length > 3 ? ',' : '') : '';
- var _float = decimals ? stringified.slice(-1 - decimals) : '';
- var sign = value < 0 ? '-' : '';
- return sign + _currency + head + _int.slice(i).replace(digitsRE, '$1,') + _float;
- },
-
- /**
- * 'item' => 'items'
- *
- * @params
- * an array of strings corresponding to
- * the single, double, triple ... forms of the word to
- * be pluralized. When the number to be pluralized
- * exceeds the length of the args, it will use the last
- * entry in the array.
- *
- * e.g. ['single', 'double', 'triple', 'multiple']
- */
-
- pluralize: function pluralize(value) {
- var args = toArray(arguments, 1);
- return args.length > 1 ? args[value % 10 - 1] || args[args.length - 1] : args[0] + (value === 1 ? '' : 's');
- },
-
- /**
- * Debounce a handler function.
- *
- * @param {Function} handler
- * @param {Number} delay = 300
- * @return {Function}
- */
-
- debounce: function debounce(handler, delay) {
- if (!handler) return;
- if (!delay) {
- delay = 300;
- }
- return _debounce(handler, delay);
- }
- };
-
- function installGlobalAPI (Vue) {
- /**
- * Vue and every constructor that extends Vue has an
- * associated options object, which can be accessed during
- * compilation steps as `this.constructor.options`.
- *
- * These can be seen as the default options of every
- * Vue instance.
- */
-
- Vue.options = {
- directives: directives,
- elementDirectives: elementDirectives,
- filters: filters,
- transitions: {},
- components: {},
- partials: {},
- replace: true
- };
-
- /**
- * Expose useful internals
- */
-
- Vue.util = util;
- Vue.config = config;
- Vue.set = set;
- Vue['delete'] = del;
- Vue.nextTick = nextTick;
-
- /**
- * The following are exposed for advanced usage / plugins
- */
-
- Vue.compiler = compiler;
- Vue.FragmentFactory = FragmentFactory;
- Vue.internalDirectives = internalDirectives;
- Vue.parsers = {
- path: path,
- text: text,
- template: template,
- directive: directive,
- expression: expression
- };
-
- /**
- * Each instance constructor, including Vue, has a unique
- * cid. This enables us to create wrapped "child
- * constructors" for prototypal inheritance and cache them.
- */
-
- Vue.cid = 0;
- var cid = 1;
-
- /**
- * Class inheritance
- *
- * @param {Object} extendOptions
- */
-
- Vue.extend = function (extendOptions) {
- extendOptions = extendOptions || {};
- var Super = this;
- var isFirstExtend = Super.cid === 0;
- if (isFirstExtend && extendOptions._Ctor) {
- return extendOptions._Ctor;
- }
- var name = extendOptions.name || Super.options.name;
- if (process.env.NODE_ENV !== 'production') {
- if (!/^[a-zA-Z][\w-]*$/.test(name)) {
- warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
- name = null;
- }
- }
- var Sub = createClass(name || 'VueComponent');
- Sub.prototype = Object.create(Super.prototype);
- Sub.prototype.constructor = Sub;
- Sub.cid = cid++;
- Sub.options = mergeOptions(Super.options, extendOptions);
- Sub['super'] = Super;
- // allow further extension
- Sub.extend = Super.extend;
- // create asset registers, so extended classes
- // can have their private assets too.
- config._assetTypes.forEach(function (type) {
- Sub[type] = Super[type];
- });
- // enable recursive self-lookup
- if (name) {
- Sub.options.components[name] = Sub;
- }
- // cache constructor
- if (isFirstExtend) {
- extendOptions._Ctor = Sub;
- }
- return Sub;
- };
-
- /**
- * A function that returns a sub-class constructor with the
- * given name. This gives us much nicer output when
- * logging instances in the console.
- *
- * @param {String} name
- * @return {Function}
- */
-
- function createClass(name) {
- /* eslint-disable no-new-func */
- return new Function('return function ' + classify(name) + ' (options) { this._init(options) }')();
- /* eslint-enable no-new-func */
- }
-
- /**
- * Plugin system
- *
- * @param {Object} plugin
- */
-
- Vue.use = function (plugin) {
- /* istanbul ignore if */
- if (plugin.installed) {
- return;
- }
- // additional parameters
- var args = toArray(arguments, 1);
- args.unshift(this);
- if (typeof plugin.install === 'function') {
- plugin.install.apply(plugin, args);
- } else {
- plugin.apply(null, args);
- }
- plugin.installed = true;
- return this;
- };
-
- /**
- * Apply a global mixin by merging it into the default
- * options.
- */
-
- Vue.mixin = function (mixin) {
- Vue.options = mergeOptions(Vue.options, mixin);
- };
-
- /**
- * Create asset registration methods with the following
- * signature:
- *
- * @param {String} id
- * @param {*} definition
- */
-
- config._assetTypes.forEach(function (type) {
- Vue[type] = function (id, definition) {
- if (!definition) {
- return this.options[type + 's'][id];
- } else {
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production') {
- if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {
- warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
- }
- }
- if (type === 'component' && isPlainObject(definition)) {
- definition.name = id;
- definition = Vue.extend(definition);
- }
- this.options[type + 's'][id] = definition;
- return definition;
- }
- };
- });
-
- // expose internal transition API
- extend(Vue.transition, transition);
- }
-
- installGlobalAPI(Vue);
-
- Vue.version = '1.0.24';
-
- // devtools global hook
- /* istanbul ignore next */
- setTimeout(function () {
- if (config.devtools) {
- if (devtools) {
- devtools.emit('init', Vue);
- } else if (process.env.NODE_ENV !== 'production' && inBrowser && /Chrome\/\d+/.test(window.navigator.userAgent)) {
- console.log('Download the Vue Devtools for a better development experience:\n' + 'https://github.com/vuejs/vue-devtools');
- }
- }
- }, 0);
-
- module.exports = Vue;
- /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(23)))
-
-/***/ },
-/* 23 */
-/***/ function(module, exports) {
-
- // shim for using process in browser
-
- var process = module.exports = {};
-
- // cached from whatever global is present so that test runners that stub it don't break things.
- var cachedSetTimeout = setTimeout;
- var cachedClearTimeout = clearTimeout;
-
- var queue = [];
- var draining = false;
- var currentQueue;
- var queueIndex = -1;
-
- function cleanUpNextTick() {
- if (!draining || !currentQueue) {
- return;
- }
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
- }
-
- function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = cachedSetTimeout(cleanUpNextTick);
- draining = true;
-
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- if (currentQueue) {
- currentQueue[queueIndex].run();
- }
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- cachedClearTimeout(timeout);
- }
-
- process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- cachedSetTimeout(drainQueue, 0);
- }
- };
-
- // v8 likes predictible objects
- function Item(fun, array) {
- this.fun = fun;
- this.array = array;
- }
- Item.prototype.run = function () {
- this.fun.apply(null, this.array);
- };
- process.title = 'browser';
- process.browser = true;
- process.env = {};
- process.argv = [];
- process.version = ''; // empty string to avoid regexp issues
- process.versions = {};
-
- function noop() {}
-
- process.on = noop;
- process.addListener = noop;
- process.once = noop;
- process.off = noop;
- process.removeListener = noop;
- process.removeAllListeners = noop;
- process.emit = noop;
-
- process.binding = function (name) {
- throw new Error('process.binding is not supported');
- };
-
- process.cwd = function () { return '/' };
- process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
- };
- process.umask = function() { return 0; };
-
-
-/***/ }
-/******/ ]);
\ No newline at end of file